Checklist: First Deployment
- Run
server-init.shas root on a fresh Debian 12 VPS - Add the generated SSH key to Codeberg
- Point DNS A records for all subdomains to the server IP (
nortonshop.net,www,cdn,api,admin,auth,docs,s) - Run
server-setup.shas the deploy user (prompts for domain, email, repo URL, webhook secret) - Verify the site loads at
https://www.nortonshop.net - Verify
https://nortonshop.netredirects tohttps://www.nortonshop.net - Verify the admin panel loads at
https://admin.nortonshop.net - Verify health endpoints return 200:
curl https://www.nortonshop.net/health curl https://api.nortonshop.net/health curl https://admin.nortonshop.net/health curl https://docs.nortonshop.net/health curl https://s.nortonshop.net/health - Set up the auto-pull cron job (see Cron jobs above)
- Back up
/var/www/secrets/.encryption-keyafter the first admin visit (auto-generated); the captcha key at/var/www/secrets/.captcha-keyis also auto-generated on first contact-form use - Set
$CDN_BASEinconfig.phpandcdnBase/apiBasevia the admin Settings tab (orsite-config.jsdirectly) - Configure the contact form mailbox — create a mailbox with your SMTP provider (Migadu, etc.), add
SMTP_*+CONTACT_*env vars to thephpservice indocker-compose.yml, and put the password in/opt/server-stack/.env(escape any$as$$) - Optionally enable WebAuthn and/or YubiKey OTP in
config.php - Verify admin subdomain deny rules:
curl https://admin.nortonshop.net/users.jsonshould return 403 - Verify bot blocking:
curl -I -A "GPTBot" https://www.nortonshop.net/should return 403 - Visit
https://auth.nortonshop.net/loginto create the first owner account (the first account is always owner; after setup you are redirected toadmin.nortonshop.net) - Test the admin panel login, contact form, and 404 page
Git and GD are baked into the PHP container image via the
Dockerfile in /opt/server-stack/. The image is built once with docker compose build and starts instantly on every restart — no runtime install step required. The Dockerfile also runs git config --global --add safe.directory /var/www/html so the auto-pull cron works immediately.