Build a Homelab CI Pipeline for Docker Services with Rollback Support
Build one complete GitHub Actions pipeline for a disposable Docker service: test, build, publish a versioned image, deploy it, deliberately fail the new version, and roll back to the previous digest/tag.
Expected Outcome
A small service moves from commit to tested image to controlled deployment with a repeatable rollback that does not depend on rebuilding the previous version.
Assumptions
A GitHub repository with Actions enabled
A container registry such as GHCR and permission to publish a lab image
A disposable Docker/Compose deployment host or self-hosted runner isolated from production
Repository/environment secrets for deployment stored in GitHub rather than committed files
A simple health endpoint used as a deployment gate
Bill of Materials
Homelab server (Linux-based preferred)
Docker installed
Git installed
A text editor (e.g., VSCode, Nano)
GitHub repository for your Docker project
Build Steps
- Make the application testable and versionable
Use a tiny service with a health endpoint and Dockerfile. Pin base-image intent, run an application test before image build, and tag images with the immutable commit SHA in addition to any friendly lab tag.
- Build and publish in GitHub Actions
Create one workflow that checks out the repository, runs tests, authenticates to the registry using GitHub-supported credentials, builds the image, and pushes the commit-SHA tag only after tests pass.
- Deploy by immutable version
On the disposable target, update Compose or the deployment manifest to the newly published SHA tag, pull, and start the service. Record the previously deployed tag/digest before changing it.
- Gate success on the application health path
Poll the real health endpoint with a bounded timeout. Do not call docker compose up success a deployment success. If the health gate fails, stop promotion immediately.
- Exercise rollback deliberately
Commit a controlled broken health behavior or deploy a known-bad test image. Confirm the health gate fails, then redeploy the exact previously recorded image tag/digest without rebuilding it.
- Preserve deployment evidence
Record commit SHA, image digest, target, health result, previous version, rollback action, and final healthy version so a future operator can reconstruct what happened.
Validation
A passing commit produces one immutable image version
A failing test does not publish/deploy an image
A healthy image deploys and passes the application endpoint check
A deliberately bad deployment fails the health gate
Rollback restores the prior immutable image and health endpoint
No deployment secret is stored in repository plaintext
Troubleshooting
Separate workflow-test failure, registry auth, image build, target pull, Compose/runtime, and health-check failures
If rollback requires rebuilding an old commit, the artifact/versioning design is not complete
Do not use an unrestricted production Docker socket or production host for the lab
Cleanup or Rollback
Remove disposable deployment credentials and runner access
Stop/remove the lab stack
Retain a small number of image versions needed to demonstrate rollback and then apply registry retention
Next Improvements
Explore additional CI/CD tools for more advanced features.
Integrate automated testing for your Docker services.
Set up notifications for deployment status.
