# Vhost and Apache

> Source: https://www.allsweb.com/sixpanel/docs/vhost-and-apache
> Markdown for agents: https://www.allsweb.com/sixpanel/docs/vhost-and-apache.md
> Publisher: AllsWeb (www.allsweb.com)

Part of: SixPanel documentation

**What this page is for:** see exactly what your web server is told about a website or a
6amMart shop, add nginx directives of your own to it, and look after Apache — its sizes,
its modules and its own settings — when a PHP website runs behind it.

**The rule that does not move:** with nothing typed, nothing changes. Every web server
file stays byte for byte what SixPanel renders, and SixPanel keeps writing those files
itself. What you write lives in a file of its own, and every save is tested by the web
server before it goes live.

**You need**

- The owner's login. A temporary login, the read-only demo and every other account see
  neither page — the files name the server's folders and ports, and what you type may
  hold a password (a proxy's `Authorization` header, for instance).
- For your own nginx directives: the website (or the shop's host) has an HTTPS address.
  The directives go into its HTTPS server, so a domain with its certificate comes first
  (**Domain & SSL**).
- For the Apache page: Apache installed (the page installs it).

---

## Where the pages are

- **A website → Vhost.** In every website's menu, after Web Rules.
- **A 6amMart project → Vhost.** In the project's menu, after Web Rules. A picker at the
  top chooses the host: the **admin panel** or the **customer website**.
- **Software → Apache.** **Manage Apache** on the Apache card of
  **Server → Services** opens it too.

## The files SixPanel renders

The Vhost page lists every web server file SixPanel writes for that website or host:

| File | What it is |
|---|---|
| HTTPS server | The server your visitors reach: certificate, security headers, caches, the refusals of `.env`, `.git` and dumps, and the website's own locations. |
| Behind Varnish (loopback) | While Varnish serves the website (its **Caching** page): the website's own server block, on this server only. The HTTPS server in front of it then keeps the certificate, the security headers and Web Rules, and hands every request to Varnish. |
| HTTP server | Port 80: the redirect to HTTPS, and the certificate checks (`/.well-known/acme-challenge/`). |
| Redirects to the main address | A 6amMart host's other names, sent to the main one. |
| The app behind it | A Node.js app's or the storefront's upstream. |
| Page cache | A PHP website's or WordPress site's page cache. |
| Web Rules | Your header rules and redirects, from the Web Rules page. |
| Your own directives | The files of what you type on this page (below). |
| Apache | A PHP website's Apache file, while Apache serves it. |
| Live updates | A shop's live order tracking (WebSocket) host. |
| Shared with this server's first project | The admin locations of the first 6amMart project, in the installer's own file. |

Each file is **read-only** here and says one of three things:

- **As SixPanel wrote it** — exactly what SixPanel last wrote.
- **Changed since SixPanel wrote it** — somebody edited it by hand, or a release has not
  rendered it yet. SixPanel writes these files again whenever it renders them (a
  certificate, a domain, a deploy), and an edit by hand is gone then. Write your change
  under **Your own directives** instead.
- **Not in the record** — a file SixPanel has not written since it started keeping a
  record of what it writes.

## Your own directives

nginx directives of your own, added to the HTTPS server. A website takes up to four
blocks, each in a tab:

| Block | Where it goes |
|---|---|
| **Server block** | At the end of the `server { }` block. |
| **Every page (location /)** | At the end of `location / { … }`. |
| **PHP files (location ~ \.php$)** | At the end of the PHP location (PHP websites and WordPress). |
| **The app's answers (location @app)** | At the end of the location that hands requests to a Node.js app. |

A block is only offered when the website's server has that location. A 6amMart host takes
the **server block** only: its locations are the shop's own.

A header (`add_header …`) written in the server block is **repeated inside every
location that sets headers of its own**. nginx drops a server's headers in a location
that adds any — SixPanel's own locations do — so a header written once would otherwise
be missing from most answers. The same rule holds in a location of your own: one that
adds a header of its own drops the server's headers (the security headers too) for the
answers it gives — add the ones you need there as well, or use **Web Rules**, which
repeats them for you.

Up to 16 KB and 300 lines a block. A line starting with `#` is a note and does nothing.

### What is taken

Plain nginx directives, and location blocks of your own inside the server block. For
example:

```nginx
gzip_comp_level 6;
add_header X-Robots-Tag "noindex" always;

location /downloads/ {
    autoindex on;
}
```

```nginx
# in "Every page (location /)"
expires 1h;
client_max_body_size 64m;
```

A value for PHP (`fastcgi_param APP_REGION "eu";` in the PHP block), a header to the app
(`proxy_set_header X-Region "eu";` in the app's), `limit_except`, `types { … }`, `if`
inside a location, and a `proxy_pass` to the website's **own** app by the name its server
already uses for it.

A directive SixPanel already sets in the same place — `try_files` in `location /`, the
app's timeouts in `location @app`, `fastcgi_read_timeout` in the PHP block — is refused
with the reason: nginx takes most directives once in a block. Set it in a location of your
own instead (a PHP website's time limit is on its PHP page).

### What is refused

Each refusal names the line and the reason:

- Anything that loads code or reads another file into nginx: `include`, `load_module`,
  Lua, Perl, njs.
- `root`, `alias` and `auth_basic_user_file` outside the website's own folder, a `..`
  step, and a path built from `$request_uri` (nginx does not clean it; use `$uri`).
- nginx's own main and http levels: `user`, `worker_*`, `map`, `upstream`,
  `log_format`, and `listen` and `server_name` (Domain & SSL sets those).
- Every `*_pass` except a `proxy_pass` to the website's own app, and `resolver` and
  `proxy_bind`. nginx looks a name up when it reads its configuration and again at every
  reload — a website that fetches its pages from another address is a reverse proxy of
  its own, not a few lines in another server.
- The certificate and every `ssl_*` directive that names a file (Domain & SSL owns them).
- The page caches, WebDAV, and anything that writes visitors' answers to disk.
- `return`, `rewrite` and `if` at the server level — they would answer the certificate
  check before its own location, and renewals would stop. Put them in a location, or
  use **Web Rules** for a redirect.
- A header SixPanel already sends from that server — **Web Rules** changes those.
- A `=` or `^~` location, and a regex location inside another location (in a location
  block, or inside a location of your own): nginx matches those before the server's
  refusals of `.env`, `.git` and database dumps, so they would step around them. A regex
  location in the server block is taken — it comes after the refusals.
- A location, `root`, `alias`, rewrite, `try_files` or `error_page` that names a dotfile
  or a dot folder, and a location under `/.well-known/acme-challenge/` (the certificate
  checks are answered there).
- A `try_files` file that does not start with `/` or `$uri` (nginx puts the root and it
  together as they are, so it would reach the folders beside the root), and an `alias`,
  `try_files` or `rewrite … break` path whose segment starts with a capture (`$1`) when
  that capture's group does not itself start after a `/` in its pattern — it could begin
  with a dot the server's refusals never saw. Capture whole segments: `^/files/(.*)$`.
- `stub_status` (the whole server's connection counts), `client_body_in_file_only`
  (every request body kept on disk) and the directives of modules that run programs or
  check passwords against this server's accounts.
- `access_log` other than `access_log off;` — SixPanel writes the visit log itself.

### How a save goes live

**Check with nginx** sends what is on the screen to the server, which checks it, puts it
in a copy of nginx's **whole** configuration and runs `nginx -t` on that copy. Nothing is
saved and nothing is reloaded.

**Save and reload** is a job:

1. The same test on a copy. If nginx refuses, nothing is changed and you see nginx's own
   sentence on **your** line.
2. The files are written, nginx reloads.
3. SixPanel asks the website's address again, on the server itself. If it answered before
   and does not answer now (or answers with a server error), your previous directives are
   put back and the job says so.

**Clear all** empties every block, and the server goes back to exactly what SixPanel
renders.

### When nginx refuses them later

A release, a module or a renamed setting can make nginx refuse a block it once took.
Your directives must never be what stops SixPanel's own work — renewing a certificate,
a deploy, connecting a domain. So when nginx refuses its configuration, SixPanel takes
your files out, asks nginx again, and puts back every block it can show is not the
cause. The one that is is **held**: kept on the page with nginx's sentence, written
nowhere, until you change it and save it again.

### While Varnish serves the website

With Varnish on (the website's **Caching** page), the website has two server blocks: the
HTTPS server your visitors reach, which hands every request to Varnish, and the website's
own server block behind Varnish. Then:

- Your **add_header** lines are sent from the HTTPS server in front of Varnish — on every
  answer, the ones Varnish keeps included.
- Everything else you wrote — the rest of the server block, your own locations, and the
  `location /`, PHP and app blocks — is **kept**, still checked and tested against the
  website's own server block, and applies again the moment Varnish is off for the website.
  The page says so.

Why not elsewhere: the server in front of Varnish has none of the website's files or its
refusals of `.env` and `.git`, so a location of yours there would answer from the wrong
folder or step around those refusals; and behind Varnish, an answer kept for one visitor is
handed to the next, so a rule that answers visitors differently (`allow` and `deny`, an `if`
on who is asking) would not hold.

## On a 6amMart project

The same page, one host at a time: pick **Admin panel** or **Customer website**. Each
host has its own server block. The shop's own locations — the admin panel, the API, the
uploads under `/storage/app/public/`, the deploy receiver, live updates — never change.
It works the same on an untouched CodeCanyon 6amMart and on an optimised one.

## Apache

**Software → Apache.** Apache behind nginx, for PHP websites whose app keeps
its rules in `.htaccess` files (see *Apache and .htaccess* in
[PHP and Node.js versions](https://www.allsweb.com/sixpanel/docs/php-and-node-versions)). It answers nginx only, on
`127.0.0.1` — never a public port — and PHP stays in each website's own pool.

The page shows whether Apache is installed and running, its version, and which PHP
websites use it (each links to its PHP page, where Apache is turned on or off for that
website). **Install**, **Repair**, **Remove** and **Restart** are here; Remove refuses
while a website still uses Apache, and Restart is only offered while one does — with
none, Apache is stopped on purpose.

### Workers

Apache runs the **event** MPM. SixPanel sizes it for this server's memory: how many
requests it answers at once (`MaxRequestWorkers`) and after how many connections one of
its processes is replaced (`MaxConnectionsPerChild`). You may set your own within the
bounds the page gives — from 25 requests at once up to 100 for every GB of memory (at
least 100, at most 800) — and **Use this server's own** goes back to SixPanel's size. Apache is asked about the new sizes
in a copy of its configuration first and they are written only when it takes them; it restarts (a second or two) only
when a website uses it.

### Modules

Every module of this server's Apache, on or off:

- **Stays on** — the modules SixPanel's own files need (`proxy_fcgi`, `rewrite`,
  `headers`, `remoteip`, …), each with the reason.
- **Kept off** — the ones that would break what this setup promises: `mod_php` and the
  other MPMs, CGI and anything that runs programs, `userdir`, WebDAV, `status` and
  `info` (every website would show this server's state), Apache's own TLS, and the
  proxy modules other than `proxy_fcgi`. That includes the modules that run code inside
  Apache itself (`mod_perl`, `mod_python`, `mod_wsgi`, `mod_fcgid`, Passenger) and
  `mod_xsendfile`: a website's `.htaccess` can hand its files to them, and they would
  run that website's code — or send any file — as the web server's account, outside the
  website's own PHP pool.
- Every other module can be turned on or off. It is switched first in a copy of Apache's
  configuration, which Apache is asked about, and on the server only when Apache takes it —
  a module Apache refuses never reaches the configuration it serves from.

### Apache's own directives

Apache directives for every website it serves, in a file of their own that Apache reads
after SixPanel's (`zz-sixpanel-owner.conf`). Taken: timeouts and keep-alive, request
limits, `Header` and `RequestHeader`, compression and cache lifetimes (`mod_deflate`,
`mod_expires`), MIME types and charsets, environment flags, the log level, and
`<IfModule>` sections. Refused, with the line: anything that loads code or a module,
reads or writes a file elsewhere, opens another port, changes who Apache runs as, or
reaches another address; a website's own rules (`RewriteRule`, `Options`,
`<Directory>` — they belong in its `.htaccess`); an Apache expression (`expr=`); and a
variable PHP reads as its settings or as the request (`PHP_VALUE`, `PHP_ADMIN_VALUE`,
`SCRIPT_FILENAME`, `HTTPS` …) — Apache hands every variable it sets to the website's PHP.
Up to 16 KB and 200 lines.

**Check** runs the checks; **Save and reload** tests Apache's whole configuration with the
new text in a copy of it, and writes the file only when Apache takes it — refused, the
previous text stays and Apache's sentence is put on your line. Like nginx's, a file
Apache stops taking later (a package update) is **held** with Apache's sentence, so a
website behind Apache is never down because of it. Every change to Apache's files — these,
the sizes, a module, a website moved to Apache, Repair — waits for the one before it.

### Logs

The newest lines of Apache's own error log, or of one PHP website's Apache log — 50, 200
or 500 of them.

## Tia

Tia can read both pages and change what you would type there: "Tia, on the Vhost page
of my blog, set a one-hour cache lifetime for every page." She changes one block at a
time, and you see the block as it will be written before anything is — every change of
directives asks you first. A password in a block reaches her masked, and the blocks she
does not change are taken from the panel when she saves, never from her masked copy.

## How to check it worked

- The Vhost page says **Live** beside **Your own directives**, and the file **Your own
  directives** is listed under the files.
- The header is on the answer: `curl -sI https://your-domain/ | grep -i x-robots-tag`.
- The job's last step says the address still answers.

## If it went wrong

- **nginx refused them, so nothing was changed** — read the sentence; it names the line
  of your block. Fix it and press **Check with nginx** until it says nginx takes them.
- **The address answered 502 after the change, so your previous directives were put
  back** — something in the block stops the website from answering; your previous
  directives are live again.
- **Held** — nginx (or Apache) stopped taking the block after a release. Change it and
  save again, or **Clear all**.
- **"There is no HTTPS server here yet"** — give the website a domain with its
  certificate on Domain & SSL first.
