Reference
Files and services
Everything the installer sets up, and where each app's builds, data, settings and logs live on the server.
Nothing is hidden: every app is a folder, a Linux user, a systemd unit and a Caddy file, and this page lists where each one is.
What the installer does
In order:
- Checks: the OS and CPU architecture, that systemd runs the server (containers and WSL aren't supported), free disk, that ports 80 and 443 are free, and the public IP address. If one fails, it stops before changing anything.
- Swap: on servers with less than 4 GB of RAM, a 2 GB swap file, so a
next buildcan't exhaust memory and take the server down. - Packages:
- Caddy, from its own apt repository.
- ufw, and fail2ban watching SSH logins.
- unattended-upgrades, for security updates.
- Node: official Node.js builds, checked against their published checksums, unpacked read-only in
/opt/layer/node/<version>/. Each app's unit names the exact version it runs. There's no nvm, fnm or pm2. - Users:
layerfor the panel, alayer-appsgroup for app users, and alayer-webgroup that lets Caddy reach the panel's socket. Each app gets its own user later, when you create it. - Caddy: a main config that loads one file per site from
/etc/caddy/sites/. Its admin API listens on a unix socket, not a port. - The release: the panel, the agent and the
layercommand, unpacked read-only in/opt/layer/releases/<version>/and linked as/opt/layer/current. The last 3 releases are kept. - Secrets: the key that encrypts environment variables and other secrets in the panel's database (
/etc/layer/secret.key), and the setup token's hash. - Services:
layer-agent: runs as root, but only takes a fixed list of actions over a unix socket.layer-panel: the web UI, running aslayer.
- The panel's site:
/etc/caddy/sites/_panel.caddy, which proxies to the panel's unix socket. - Firewall: incoming traffic is denied except SSH, 80 and 443 (TCP, plus UDP for HTTP/3).
- SSH, if an SSH key is present and you agree (or pass
--yes): password login off, root only with a key.
The full log is in /var/log/layer-install.log.
Where things are
| Where | What |
|---|---|
/opt/layer/current, /opt/layer/releases/<version>/ |
The panel, the agent and the CLI. Read-only, owned by root. |
/opt/layer/node/<version>/ |
Node runtimes, shared by all apps. |
/srv/apps/<app>/ |
Each app's builds (releases/<sha>/, current) and its data/ folder, owned by the app's own Linux user, app-<app>. |
/etc/layer/apps/<app>/ |
The app's env files: app.env (your variables), services.env (database URLs), blue.env and green.env (ports). All root-only. |
/etc/systemd/system/app-<app>@.service |
The app's sandboxed unit, with instances blue and green. Cron jobs are app-<app>-cron-<name>.timer units; Redis is layer-redis-<app>.service. |
/etc/caddy/sites/<app>.caddy |
The app's Caddy site. _panel.caddy is the panel. |
/var/log/caddy/<app>.log |
The app's access log, as JSON. |
/etc/layer/config.json |
The server's settings: panel address, apps domain, who can open the panel, update feed. |
/var/lib/layer/panel.db |
The panel's database (SQLite, owned by layer). |
/var/log/layer/audit.jsonl |
Every change the agent made. Root-only. |
/var/lib/layer-agent/archive/ |
Final dumps and data folders kept when you remove a database or delete an app. Root-only. |
Services
systemctl status layer-panel layer-agent caddy # the panel, the agent and the web server
systemctl list-units 'app-*' # every app, cron job and Redis
journalctl -u layer-agent -f # what the agent is doing