Deployment
How deployment works
The site code is tracked in a Codeberg git repository. The git repo is cloned directly inside the PHP container at /var/www/html. A cron job on the host runs every minute:
git fetch origin main && git reset --hard origin/main
This keeps the live site in sync with whatever is on the main branch. Push to Codeberg and the change appears on the live site within 60 seconds.
The same cron job also copies images, videos, content JSON, and documents to the CDN volume so cdn.nortonshop.net stays up to date.
.gitignore file excludes them so that git reset --hard does not overwrite content created through the admin panel. See Persistent Data for details.
Setup scripts
Two scripts handle the initial server setup. Both are in the project root and committed to git.
1. server-init.sh (run once as root)
Sets up a fresh Debian 12 VPS: creates a deploy user, installs Docker CE, configures UFW firewall, hardens SSH, sets up fail2ban, automatic updates, and generates an SSH key for Codeberg.
bash server-init.sh
It prompts for: username, timezone, git name/email, and SSH port. After it finishes, add the generated SSH public key to Codeberg.
authorized_keys. If not, password auth stays enabled and the script tells you how to disable it later.
2. server-setup.sh (run once as deploy user)
Creates the Docker Compose stack, obtains SSL certificates from Let's Encrypt, clones the Codeberg repo into the PHP container, configures the webhook, and starts all services.
bash server-setup.sh
It prompts for: domain name, Let's Encrypt email, Codeberg repo URL, and webhook secret. DNS A records must already point to the server for all subdomains before running this.
Manual deploy
To force an immediate deploy without waiting for the cron, use deploy.sh:
sudo bash /var/www/nortonshop.net/deploy.sh
This pulls the latest code from Codeberg, copies site files into the Docker volumes, syncs the nginx config if it has changed, restarts nginx if needed, and writes a deployment marker. It also creates a backup of the current deployment before overwriting.
Alternatively, pull code only (without the full deploy pipeline):
sudo git -C /var/www/nortonshop.net pull
If only the nginx config changed, you can sync and restart nginx manually:
sudo cp /var/www/nortonshop.net/admin/nginx.conf /opt/server-stack/nginx/conf.d/nortonshop.conf
sudo cp /var/www/nortonshop.net/admin/nginx-main.conf /opt/server-stack/nginx/nginx.conf
sudo docker compose -f /opt/server-stack/docker-compose.yml restart nginx
Cron jobs
Two cron jobs run on the host server:
| Schedule | Purpose |
|---|---|
| Every minute | Auto-pull from Codeberg, sync CDN files, fix permissions |
| Twice daily (3am, 3pm) | SSL certificate renewal check |
git reset --hard rather than git pull. This means any manual file edits inside the container (outside of git-ignored paths) will be overwritten. Always make code changes through Codeberg, and content changes through the admin panel.