Updating the Website Repository on a VPS
Once your site is running on a VPS, updates should be boring.
This is the workflow I use to update the repository and redeploy the current website without surprises.
1) Go to the project and inspect state
cd /opt/website
git status
git branch --show-current
git remote -v
You want a clean working tree before pulling.
If there are local changes:
git stash push -m "vps-local-before-update"
2) Pull the latest code
cd /opt/website
git fetch --all --prune
git pull --ff-only origin main
--ff-only prevents accidental merge commits on the server.
3) Rebuild and restart containers
cd /opt/website
podman-compose -f compose.yml down
podman-compose -f compose.yml up --build -d
or
podman-compose -f compose.yml up --build -d --force-recreate
Check for conflicts:
podman ps -a --filter name=www.adrian-altner.de
podman rm -f www.adrian-altner.de
This rebuilds the image and replaces the running container with the new version.
If you hit:
the container name "website" is already in use
use one of these recovery paths:
# Option A: clean compose state
podman-compose -f compose.yml down
podman-compose -f compose.yml up --build -d
# Option B: remove conflicting container explicitly
podman rm -f website
podman-compose -f compose.yml up --build -d
This is common when container_name: website is fixed in compose.yml and state gets out of sync.
4) Verify application health
podman ps
podman logs --tail=100 website
curl -I http://127.0.0.1:4321
curl -I https://adrian-altner.de
If Caddy is active, the public HTTPS check is the final signal.
5) Fast rollback if something breaks
cd /opt/website
git log --oneline -n 5
git checkout <previous-commit>
podman-compose -f compose.yml up --build -d
After recovery, create a proper fix in the repository and deploy again from main.
6) Optional one-command deploy script
#!/usr/bin/env bash
set -euo pipefail
cd /opt/website
git fetch --all --prune
git pull --ff-only origin main
if ! podman-compose -f compose.yml up --build -d; then
podman rm -f website || true
podman-compose -f compose.yml up --build -d
fi
curl -fsS -I http://127.0.0.1:4321 >/dev/null
echo "Deploy successful"
Save it as deploy.sh, make it executable, and run:
chmod +x deploy.sh
./deploy.sh
A predictable update flow is more important than a complex one.