First Deployment

Checklist: First Deployment

  1. Run server-init.sh as root on a fresh Debian 12 VPS
  2. Add the generated SSH key to Codeberg
  3. Point DNS A records for all subdomains to the server IP (nortonshop.net, www, cdn, api, admin, auth, docs, s)
  4. Run server-setup.sh as the deploy user (prompts for domain, email, repo URL, webhook secret)
  5. Verify the site loads at https://www.nortonshop.net
  6. Verify https://nortonshop.net redirects to https://www.nortonshop.net
  7. Verify the admin panel loads at https://admin.nortonshop.net
  8. 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
  9. Set up the auto-pull cron job (see Cron jobs above)
  10. Back up /var/www/secrets/.encryption-key after the first admin visit (auto-generated); the captcha key at /var/www/secrets/.captcha-key is also auto-generated on first contact-form use
  11. Set $CDN_BASE in config.php and cdnBase/apiBase via the admin Settings tab (or site-config.js directly)
  12. Configure the contact form mailbox — create a mailbox with your SMTP provider (Migadu, etc.), add SMTP_* + CONTACT_* env vars to the php service in docker-compose.yml, and put the password in /opt/server-stack/.env (escape any $ as $$)
  13. Optionally enable WebAuthn and/or YubiKey OTP in config.php
  14. Verify admin subdomain deny rules: curl https://admin.nortonshop.net/users.json should return 403
  15. Verify bot blocking: curl -I -A "GPTBot" https://www.nortonshop.net/ should return 403
  16. Visit https://auth.nortonshop.net/login to create the first owner account (the first account is always owner; after setup you are redirected to admin.nortonshop.net)
  17. 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.
Back to top