02.1 Catalog sites

Chapter 02.1

Catalog sites

A catalog site is three things bound together: a domain, an image, and a folder. Creating one gives you a running container. Everything else in this guide adjusts one of those three — unless you are building a custom stack, which works differently.

Folder — you are here /var/www/virtual/app.example.com Your code. The panel creates it and never touches the contents.
Mounted into /var/www/virtual/app.example.com The identical path inside the container. No translation.
Served by nginx :80 Docroot depends on the image — see below.

The folder

Every site has a folder on the host, under /var/www/virtual/. It is named after the domain, so app.example.com gets /var/www/virtual/app.example.com.

You do not choose it. On the New site form the path fills itself in as you type the domain and cannot be edited — it is there so you know where your files will go, and you can select and copy it before the site even exists.

The important property: the folder is mounted into the container at exactly the same path. There is no mapping to remember. A file at /var/www/virtual/app.example.com/application/artisan on the host is at that same path inside the container. This is why absolute paths in your background programs work in both places — see chapter 05.

The panel creates the folder if it is missing. Beyond that it never reads, writes, or clears the contents — not on a restart, not on a settings change, not when the image changes.

Where the docroot points

This differs by image, and it is the first thing that trips people up.

ImageDocrootSo your files look like
Static Website
web-base
<folder> <folder>/index.html
Single-Page App
web-spa
<folder> <folder>/index.html
<folder>/assets/
Laravel App
laravel
<folder>/application/public <folder>/application/public/index.php
<folder>/application/artisan
<folder>/application/vendor

On the Laravel image the application lives in an application/ subdirectory of the folder, and only its public/ is exposed to the web. That is the standard Laravel layout, and it means your vendor/ and the app's own .env and storage/ symlinks sit outside the docroot where they belong.

Two pieces of durable state live beside application/, not inside it: <folder>/storage/ (uploads, logs, sessions — the standard Laravel tree, scaffolded for you by the image) and <folder>/.env (your secrets). A deploy symlinks both back into application/, so it can wipe and re-publish application/ on every push without ever touching your data or secrets. See chapter 04.

A fresh site is not empty

If the docroot has no index.php or index.html, the Laravel image writes a placeholder page saying the image is running with no app deployed. Seeing that page means the container is healthy and waiting for your code — not that something broke.

The container

One container runs one site. It is named after the domain, with dots turned into dashes and an no- prefix: app.example.com becomes no-app-example-com. You will see this name in the panel and in log output.

Containers have no published host ports. Nothing about your site is reachable at the-box-ip:8080 or similar. Traffic arrives only through the edge proxy, which dials your container by name on the internal network. This is also why your app can reach shared services by name — covered in chapter 06.

Created is not published

These are two separate actions, and the split is deliberate.

Created
The folder exists, the container runs, and the site is reachable from nowhere. Nothing is routed to it and no certificate has been requested.
Published
The domain is routed to your container and a certificate is issued. This is the point at which DNS must already be correct.
Unpublished
The route is withdrawn. The container keeps running and your files are untouched — the site is just unreachable.

You can safely create a site, get your code in place, confirm it works, and publish afterwards. Unpublishing is not destructive and is the right way to take a site offline temporarily.

The sites list carries that state in its Visibility column, and the column answers two questions at once. Published or unpublished is whether the site is served at all. A Locked chip beside it means the site answers only unlocked IP addresses, and 2 folders locked means only some of its URL paths do. The two are independent, so Published with Locked is a perfectly normal row: the site is live and only allowed addresses get in, which is the usual arrangement for a staging site. Chapter 08 is about that gate.

A bar above the table arranges the list. You can order it by domain, site type or visibility, in either direction, and an administrator gets owner as a fourth — a site owner is not offered it, since every row of their own list would give the same answer. Ordering and the owner filter beside it work together: changing one keeps the other. Both are in the address bar, so a particular view of the list is something you can bookmark or send to somebody. On an installation with a single site there is nothing to arrange and the page looks exactly as it always did.

Three of the orderings are worth a word:

  • Site type groups every custom stack together, because a stack has no site type in the sense a catalog site does.
  • Visibility puts published before unpublished, then unlocked before locked.
  • Owner goes by the owner's email address, and the sites with no owner at all group at the end. No owner is a real state rather than missing data — those are the panel owner's own sites.

One row is never sorted with the others: the control panel itself sits at the end of the list whatever order you choose. It is not one of your sites — it is the thing you are reading the list in — so it does not compete for a position. It used to be first, so if you have learned to look at the top of the page for it, look at the bottom.

What the status dot means

The panel shows a live status for each site, derived from the container's health check at the moment you look. It is not stored and not historical.

Up
The container is running and its health check passes.
Starting
The container is running but has not yet reported healthy. The Laravel image allows 20 seconds before it starts counting failures.
Down
The container is stopped, missing, or failing its health check.
Green does not mean your app works

The health check asks nginx for /health, which returns a fixed 200 without touching PHP, and confirms the docroot is readable. On the Laravel image it also checks that php-fpm and supervisor are running as processes.

It never executes your application. A site with a fatal PHP error, a missing vendor/, or a broken database connection reports Up quite happily. Always confirm a deploy by loading a real page.

Restart and Recreate

Two buttons sit together in a small Container box above the site's tabs. They sound alike and they are not, and pressing the wrong one is the usual reason a change seems not to have applied. A custom stack has neither, because it is not one container — you deploy it instead.

Restart
The same container starts again. This is the everyday one, and you will need it more often than you expect: it is how newly deployed PHP code, an edited .env, and newly added background programs take effect. Each of those has a chapter of its own further on.
Recreate
The container is thrown away and a new one is built from the image. Use it when the image behind the site has changed, when a setting only takes effect as the container is created, or when a folder belonging to another of your sites has been attached to this one — chapter 06 covers that arrangement. A restart cannot stand in for it — it re-runs the container that already exists, image and all.

Both take a few seconds, during which the site does not answer. Then it is back at the same address, with the same certificate.

Recreate is not destructive

The word sounds alarming and the operation is not. Your domain and its aliases, the folder and every file in it, the database, the .env, the certificate, the route and all your settings are exactly as they were. Deployments keep working too — the site stays connected to its repository, and the runner is put back for you.

What does not survive is anything a program wrote inside the container instead of into your site folder: a file in /tmp, or anywhere outside /var/www/virtual/, is gone. That is the same rule as a redeploy, and the reason durable data belongs in the folder.