SystemD CI/CD Pipeline Deep Dive
The Architecture
No Jenkins, no Actions—just systemd doing what it was born to do.
deploy-base3.service → /usr/share/base3
deploy-nimbus.service → /usr/share/caddy
deploy-weblog.service → /usr/share/weblog
deploy-server-config.service → Caddy config & unit files
deploy-*.timer → automated triggers
Deployment Flow
- Pull latest git commits.
- rsync files into place.
- Compress assets.
- Set permissions.
- Validate Caddy config.
- Restart Caddy.
- curl the site to prove it works.
Features
Atomic Deployments
Validation happens before restart, so broken configs stay safely unused.
Asset Optimization
- Brotli + gzip for text.
- gzip for WAV files.
- Permissions aligned with caddy's expectations.
Phone-Friendly Management
alias da='sudo systemctl start deploy-*'
alias st='systemctl status deploy-* caddy'
alias logs='journalctl -f -u deploy-*'
alias check='curl -s https://base3.deanfam.net && curl -s https://nimbus.deanfam.net'
Great for playground ops.
Why SystemD?
"I'm sure it's better to get good CI/CD, but systemd is everywhere and bash still works."
- Services, timers, logging, and dependencies all in one place.
- No extra layers to debug.
Example Script
#!/usr/bin/env bash
set -euo pipefail
# pulls repo, syncs files, compresses, validates, restarts, and checks health
# see repository for full script
Next Steps
- Add testing before deploys.
- Keep previous versions for rollbacks.
- Track deployment success in Nimbus.
- Maybe send alerts when things go sideways.
Turns out you can build a credible CI/CD pipeline with the tools already sitting on a Linux box. Who knew? (SystemD, apparently.)