Timers and operations
Deploy a service safely
Sequence artifact installation, validation, manager reload, restart, health checks, and rollback.
8 minute lesson
A deployment should change one known artifact and preserve a path back to the previous version. Everything else in this lesson follows from that sentence.
Install atomically, validate before restarting
Install files atomically where possible. A versioned directory plus a symlink switch gives you atomic cutover and instant rollback:
sudo cp -r build/ /opt/demo-api/releases/v42
sudo ln -sfn /opt/demo-api/releases/v42 /opt/demo-api/current
The service’s ExecStart= points at /opt/demo-api/current/server.js. Flipping the symlink back to v41 is the whole rollback.
Validate configuration before restart, using whatever check the application offers — nginx -t, node --check, a config linter. A restart is the wrong moment to discover a typo.
Reload the right thing
Use daemon-reload only for unit changes. New application code does not need it; a changed .service file or drop-in does. Cargo-culting daemon-reload into every deploy is harmless but hides the real rule, and then one day someone skips it after actually editing the unit — and the old definition keeps running.
Restart or reload, then check the service, logs, and an application-level health endpoint:
sudo systemctl restart demo-api.service
systemctl is-active demo-api.service # active
journalctl -u demo-api.service --since "2 min ago"
curl -fsS http://localhost:3000/health # {"status":"ok","version":"v42"}
is-active proves systemd’s view. The health endpoint proves the application’s view, including that the new version actually loaded. You want both, because a service can be active while serving errors.
Decide the rollback before you need it
Write down the exact trigger that means “roll back now” — for example: the health check fails for 60 seconds, or the error rate doubles. Vague triggers turn into long incidents while people debate.
sudo ln -sfn /opt/demo-api/releases/v41 /opt/demo-api/current
sudo systemctl restart demo-api.service
Write a deployment checklist for one of your services: artifact install, config validation, whether daemon-reload applies, restart, the exact health checks, the rollback trigger, and the command that restores the previous known-good version. Keep it to one screen so it gets used under pressure.
Lesson completed