Skip to content

The Web Server (CoreHttpd)

CorePanel does not ship Apache, nginx or LiteSpeed. Every site on the server — and the panel itself — is served by CoreHttpd, the web server CorePanel is built around.

Most of the time that is invisible: sites are configured from the panel and the server follows. This page is for the moments when it is not invisible — when you go looking for a vhost file that is not there, when a log is not where you expected it, or when you need to know exactly what the process serving your customers can and cannot read.

If you have run a hosting server before, this table is the fastest way in. Nothing in the left column exists on a CorePanel server.

On Apache / nginxOn CorePanel
A vhost or server {} block per siteA site record in the panel; CorePanel writes the server’s config itself
httpd -t / nginx -t before a reloadNothing to validate — there is no configuration language to get wrong
mod_rewrite, mod_deflate, mod_headersBuilt into the server; nothing to load
A third-party cache, WebP or minify moduleWeb optimizations, per site, in the panel
certbot, a renewal cron, a deploy hookAutomatic certificates, issued and renewed by the server
/var/log/httpd/*/var/log/corehttpd/*, plus one access log per domain
The apache / nginx user, started as rootThe corehttpd user, which is never root
.htaccess.htaccess — still read, with a report of what was applied

CorePanel does not render a configuration file for CoreHttpd to parse. It writes one JSON site record per site into /var/lib/corehttpd/sites/<domain>.json and signals the server to re-read them. Each file is written to a temporary name and renamed into place, so a half-written file is never read as live configuration, and the reload is a SIGHUP: no downtime, no dropped connections.

The practical consequence: those files are not yours to edit. They are regenerated from the panel’s database whenever anything about the site changes — a new alias, a PHP version, a certificate, a serving mode — and a hand edit is silently overwritten the next time that happens. Everything they contain has a control in the panel or in the CLI.

For anything that a single document root cannot express, the site record carries an ordered route table — that is what reverse proxy routes are — and that too is written by the panel.

Apache runs as root. So do nginx and LiteSpeed: they start privileged, bind the low ports, and drop to an unprivileged user for the workers. CoreHttpd never has privileges to drop. It runs as the unprivileged corehttpd user from the first instruction, with exactly two capabilities granted by its unit:

CapabilityWhat it is for
CAP_NET_BIND_SERVICEBind ports 80 and 443 as a non-root user
CAP_DAC_READ_SEARCHRead any document root regardless of owner and mode

That second one is what lets account homes stay 0700 and account files 0600 with no POSIX ACLs anywhere. The traditional approach — granting the web server access with setfacl — is fragile, because tar, rsync, backups, restores and ordinary uploads all strip ACLs, so the panel has to keep reapplying them forever. CoreHttpd needs none.

The capability is read-only: it bypasses permission checks for reading and traversing, never for writing. And because it is broad, the real boundary is mandatory access control — CoreHttpd runs in its own SELinux domain, corehttpd_t, shipped as a policy module with the RPM. Not httpd_t: a domain scoped to what this server actually does.

Terminal window
# The web server should show corehttpd_t, not init_t or unconfined_t
ps -eZ | grep corehttpd

Beyond that, the unit runs with ProtectSystem=strict and ProtectHome=read-only: the only paths the server can write are /var/lib/corehttpd and /var/log/corehttpd.

It also never executes PHP in its own process. PHP runs in a per-account PHP-FPM pool that CoreHttpd reaches over a Unix socket — see How PHP runs. A compromised web server is an HTTP front and nothing more; it cannot read a customer’s wp-config.php, because only that account’s pool ever opens it.

80/tcpHTTP/1.1 — redirects to HTTPS where Force HTTPS is on
443/tcpHTTP/1.1 and HTTP/2 over TLS
443/udpHTTP/3 over QUIC, advertised to browsers with Alt-Svc: h3=":443"

HTTP/2 and HTTP/3 are on by default and need no per-site setting. Responses carry Server: CoreHttpd, which is the quickest way to confirm from outside which server answered:

Terminal window
curl -sI https://example.com | grep -i '^server\|^alt-svc'

Certificates are the server’s own job: it obtains them from Let’s Encrypt on demand, renews them before expiry, and prefers an uploaded commercial certificate over its own wherever one has been installed. SSL/TLS certificates covers both paths.

What it does that a stock server would need modules for

Section titled “What it does that a stock server would need modules for”

Each of these is part of the same request, in the same process, and each has its own page:

PathWhat it holds
/etc/corehttpd.iniThe server’s own settings — see below
/var/lib/corehttpd/sites/One JSON site record per site, written by CorePanel
/var/lib/corehttpd/Writable state: certificate cache, WebP and minify cache, the host certificate, the GeoIP database, the WAF event store
/var/log/corehttpd/access.logServer-wide access log
/var/log/corehttpd/error.logServer errors — the first place to look
/var/log/corehttpd/users/<account>/<domain>.access.logOne access log per domain

Per-domain access logs live outside the account’s home and are symlinked into ~/logs, so the account can read its own traffic without being able to touch the file. All of them are also readable from the panel — see Reading logs.

Terminal window
systemctl status corehttpd # is it up
systemctl reload corehttpd # re-read site records, no downtime
systemctl restart corehttpd # drops connections; needed after an .ini change
journalctl -u corehttpd -n 50 --no-pager
rpm -q corepanel-httpd # the installed version

Reload is the normal operation and CorePanel performs it for you on every change; a restart is only for a change to /etc/corehttpd.ini.

This file is server-wide, and CorePanel manages what matters through the panel — a per-site setting is never in here. It ships with sensible defaults, it is commented, and most servers never need it touched. The keys worth knowing about:

KeyDefaultWhat it does
EnableIPAccesstrueKeeps https://<server-ip> serving the panel with a self-signed certificate. This is the way back in when DNS breaks or the hostname’s certificate expires; set it to false to serve the panel by hostname only
MaxPostSizeMB64Ceiling on request body size, above any PHP limit
ProxyTimeout60Seconds a proxied route may take to respond
WafEventsRetentionDays30How long WAF events are kept for the security screens; 0 stops recording them
EnableDynamicCachetrueBox-wide gate for the page cache; false disables it whatever the sites say

A change here needs systemctl restart corehttpd. The configuration is read at start-up only — a reload re-reads the site records, not this file, so an edit followed by a reload leaves the server running with the old value and no error anywhere.

Work from the outside in:

  1. Is the server up and were the ports left open? systemctl status corehttpd and ss -lntup | grep corehttpd. The installer opens 80 and 443; an empty result means something closed them afterwards — or that a cloud provider’s own firewall is in front, which CorePanel cannot see.
  2. What did the server answer? The domain’s access log gives the status code, the path and the client. /var/log/corehttpd/error.log gives the reason.
  3. A 404 on a path the application owns is almost always the serving mode, not the server.
  4. A rule that used to work on Apache — check the per-site .htaccess report, which lists every directive that was not applied.
  5. Certificate problems have their own path: see SSL/TLS certificates.