Localzet Deployer is a self-hosted CI/CD control plane for teams that want to run their own delivery pipeline with GitHub Webhooks, private container registries, and Portainer-based deployments.
Localzet Deployer is designed for teams that want:
- GitHub Webhooks instead of GitHub-hosted build minutes
- a focused Rust control plane instead of a full CI platform
- private image publishing
- Portainer redeploy hooks
- deployment history, logs, health checks, and rollback
Core capabilities:
- GitHub push webhook ingestion
- HMAC webhook signature validation
- authenticated UI and API
- queued job execution with per-repository locking
- action-aware pipelines for
webhook,retry,manual, androllback - immutable image references such as
image:sha-<shortsha> - deployment history and health checks
- manual redeploy and rollback
- PostgreSQL-backed history and logs
- GitHub sends a
pushwebhook toPOST /api/webhooks/github. - The orchestrator validates
X-Hub-Signature-256. - UI and API access are protected with a bearer token.
- The service resolves a project by
repository + branchfromconfig/app.toml. - A job is created, queued, and locked by
repo:branch. - The worker executes action-aware steps such as:
- checkout
- build and push
- promote immutable tag to stable tag
- redeploy
- health check
- Logs are stored in PostgreSQL and streamed to the UI with SSE.
- Operators can inspect jobs and deployments, then trigger
retry,redeploy, orrollback.
- Keep the platform focused on deployment control instead of becoming a generic CI suite.
- Describe pipelines declaratively in TOML.
- Support redeploy and rollback without forcing a rebuild.
- Provide a lightweight built-in UI that can be replaced later.
- Persist operational history while keeping runtime queue state simple.
- The repository contains the Rust backend, built-in web UI, example configuration, and deployment assets.
- Operators typically only need the released image plus a mounted
app.toml. config/app.prod.toml.exampleis the reference runtime template.scripts/smoke.shis useful after first startup.
GET /healthzGET /api/dashboardGET /api/projectsGET /api/jobsGET /api/jobs/:idGET /api/jobs/:id/eventsGET /api/deploymentsPOST /api/deployments/:id/rollbackPOST /api/projects/:id/redeployPOST /api/jobs/:id/cancelPOST /api/jobs/:id/retryPOST /api/webhooks/github
The main runtime file is config/app.toml.
The configuration model supports:
- webhook secret validation
- bearer token authentication for the operator API
- PostgreSQL connectivity
- project-to-repository mapping
- action-aware pipeline steps
- environment variables for registry credentials and deployment commands
Step templates support variables such as:
$IMAGE_REFERENCE$STABLE_IMAGE_REFERENCE$JOB_ACTION$SOURCE_DEPLOYMENT_ID
Steps can also be filtered with:
only_actionsskip_actions
For operators who want to run the released container image:
- Download the production config template from the repository into a local runtime directory:
mkdir -p /opt/deployer
curl -fsSL https://raw.githubusercontent.com/localzet/deployer/main/config/app.prod.toml.example \
-o /opt/deployer/app.toml-
Edit
/opt/deployer/app.tomland set real values for:github_webhook_secretauth.api_token- PostgreSQL connection settings
- registry credentials
- Portainer webhook URL
- health check URL
-
Use a Compose file that mounts the config into the container, for example:
services:
orchestrator:
image: localzet/deployer:latest
environment:
CICD_CONFIG: /app/config/app.toml
RUST_LOG: info,tower_http=info
ports:
- "8080:8080"
volumes:
- /opt/deployer:/app/config:ro
- cicd-workspace:/workspace/repos
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
postgres:
image: postgres:16-bookworm
environment:
POSTGRES_DB: cicd
POSTGRES_USER: cicd
POSTGRES_PASSWORD: cicd
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped
registry:
image: registry:2
volumes:
- registry-data:/var/lib/registry
restart: unless-stopped
volumes:
cicd-workspace:
postgres-data:
registry-data:- Start the stack:
docker compose up -d-
Open
http://localhost:8080. -
Run the smoke check:
API_TOKEN='your-token' ./scripts/smoke.sh http://localhost:8080Implemented:
- GitHub push webhooks
- HMAC validation
- authenticated API and UI
- job queue and step execution
- live log streaming
- retry, redeploy, and rollback actions
- immutable image references
- deployment history
- health checks
- Docker Compose stack with service health checks
- PostgreSQL persistence for jobs and logs
Operationally important notes:
- manual redeploy and rollback can avoid rebuilding by promoting an immutable tag to the stable tag before redeploy
- image digest support is partially implemented and currently relies on registry/build tooling with a log-based fallback
Planned hardening and product work:
- Move rollback from SHA-oriented replay to strict artifact-based redeploy by digest
- Improve digest capture so it does not rely on shell heuristics
- Add RBAC on top of the current token-based authentication
- Replace the built-in UI with a richer standalone frontend if needed
This project is licensed under the GNU Affero General Public License v3.0 only. See LICENSE.