# Websites and PHP

> Create websites, add domain aliases, choose the PHP version and document root, switch to Apache mode for .htaccess and turn on the nginx page cache.

Source: https://zopanel.net/docs/hosting  
Updated: 2026-10-07

Every website in ZoPanel belongs to one hosting account and lives in `/home/<account>/domains/<domain>/`. nginx serves it, and PHP runs in the account's own isolated PHP-FPM pool, so one customer's code never shares a PHP process with another's.

## Create a website

1. Open **Websites** and click **New website**.
2. Enter the **Domain** without `http://` (for example `example.com`). Leave **Also serve www.example.com** ticked to add the `www` name as an alias.
3. Choose the **Website type**:

| Type | What you get |
| --- | --- |
| Git deploy | Pulls a repository, detects the framework and deploys it (see [Git deploy](/docs/git-deploy)). |
| PHP | A PHP application in `public_html`. |
| WordPress | A PHP website with WordPress installed automatically (see [WordPress Toolkit](/docs/wordpress)). |
| Laravel | A PHP website whose document root is `public_html/public`. |
| HTML | Static files only, no PHP. |
| Node / Proxy | nginx forwards requests to an application listening on `127.0.0.1` (see [Node.js and Python apps](/docs/apps-node-python)). |

4. For PHP types, pick the **PHP version**. The list shows the versions installed on the server; ZoPanel supports PHP 7.4, 8.0, 8.1, 8.2, 8.3 and 8.4, and administrators install them under **Runtimes**.
5. Keep **Free SSL (Let's Encrypt)** on. The certificate is issued as soon as the domain points to the server (see [SSL certificates](/docs/ssl)).
6. Click **Create website**.

Point the domain's A (and AAAA, if you use IPv6) record to the server's IP before you expect SSL to work. Administrators and resellers can choose the **Owner** account in the same dialog. The account's package limits how many websites it may have.

## Domains and aliases

Open the website (**Websites → Manage**) and go to the **Domains** tab to add more names that serve the same files, for example `www.example.com` or a second brand domain.

- Up to 20 aliases per website.
- A domain can only be used once on the server. A domain related to one owned by another account (for example a subdomain of someone else's domain) is refused.
- After you save a change, the Let's Encrypt certificate is re-issued automatically to cover the new list of names.
- You cannot remove an alias that still has an email domain with mailboxes: delete its email domain first on the **Email** page.

## PHP version and document root

The **PHP & config** tab holds the runtime settings:

| Field | Meaning |
| --- | --- |
| PHP version | Any installed version, or **No PHP (static / proxy)**. You can change it at any time; the account's PHP-FPM pool is updated for you. |
| Rewrite rules | **Standard**, **WordPress** or **Laravel**. The WordPress rules also block `xmlrpc.php`, PHP files in `wp-content/uploads` and direct access to `wp-config.php`, `readme.html` and `license.txt`. |
| Document root | Relative to the domain folder and always inside `public_html`, for example `public_html` or `public_html/public`. |
| Application port | Reverse-proxy port. Set it to `0` to turn proxy mode off. |

On websites without PHP, nginx returns 403 for `.php`, `.phtml`, `.phar` and `.inc` files instead of showing their source. On every website, nginx denies hidden files (except `.well-known`) and common backup or dump files such as `.sql`, `.env`, `.bak` and `.log`.

The memory limit and maximum execution time come from the account's package. Other options, such as `upload_max_filesize` or `date.timezone`, are set per website in **Tools → PHP settings for this website** (see [Website tools](/docs/website-tools)). Uploads are limited to 256 MB per request on every website.

## Apache mode for .htaccess

ZoPanel serves sites with nginx by default, so `.htaccess` files are ignored. Sites moved from cPanel or DirectAdmin, and applications that ship `.htaccess` rules, can switch to Apache mode:

1. Open the website's **Tools** tab.
2. Turn on **.htaccess support (Apache mode)**. The first time, Apache is installed on the server (about 30 seconds).

nginx keeps handling SSL, the firewall, redirects and common static files; Apache on `127.0.0.1` applies `.htaccess` and passes PHP to the account's own PHP-FPM pool.

What `.htaccess` may contain in Apache mode:

- **Supported:** rewrites, redirects, access rules (`Require`, `Deny`/`Allow`), password protection, `ErrorDocument`, headers, expiry, types and `SetEnv`.
- **Ignored for security:** `Options`, `SetHandler`/`AddHandler` and similar lines. They are noted in the site's Apache log instead of breaking the site.
- **Ignored:** `php_value` and `php_flag`. Set PHP options in **PHP settings for this website** instead (written to `.user.ini`).

The page cache is off in Apache mode. Apache mode is available for PHP and static websites, not for proxy websites.

## Page cache

PHP websites can be served from nginx's page cache, which speeds WordPress up many times:

1. Open the **PHP & config** tab.
2. Turn on **Page cache**.

Pages are cached for 10 minutes. ZoPanel never caches:

- requests other than GET and HEAD (for example POST);
- visitors with a WordPress login, password-protected post, comment author, WooCommerce cart or session cookie, or a `laravel_session`, `PHPSESSID` or `XSRF-TOKEN` cookie;
- URLs containing `/wp-admin`, `/wp-login.php`, `/wp-json`, `/xmlrpc.php`, `/cart`, `/checkout`, `/my-account`, `/feed` or `sitemap`;
- URLs with a query string (search, filters, pagination). A query made only of ad-tracking parameters such as `utm_*`, `fbclid` or `gclid` counts as no query, so campaign visitors still get cached pages.

Responses carry an `X-Cache` header (`HIT`, `MISS`, `BYPASS`…) so you can check the cache with:

```bash
curl -sI https://example.com/ | grep -i x-cache
```

To clear the cache, click **Purge cache** in the same card. On WordPress websites with the cache on, ZoPanel also installs a small must-use plugin (*ZoPanel page cache*) that purges the site's pages whenever a post, comment, menu, theme or plugin changes, so edits appear at once. The plugin is removed when you turn the cache off.

## Static and proxy websites

- **HTML** websites serve files from the document root with long browser caching for images, CSS, JavaScript and fonts.
- **Node / Proxy** websites pass every request to `127.0.0.1:<port>`. For customer accounts, ZoPanel assigns the port of each website; only administrators can choose another one. Use the **Deploy** tab to build and run the application (see [Node.js and Python apps](/docs/apps-node-python)).

## Request rate limit

The **Request rate limit** card on the **PHP & config** tab stops bots and floods from one IP address. Choose **Off**, **Light (20/s)**, **Medium (8/s)** or **Strict (2/s)**; static files are not counted and excess requests get HTTP 429.

## Custom nginx directives

Administrators see an **Advanced** tab where they can add **Custom nginx directives** to the website's server block. The configuration is tested before it is applied (**Test & save**), so a typo never takes nginx down.
