reconD is a small deployment agent for single-host container workloads.
It watches deployment metadata, compares the desired image digest with the host's observed state, and runs one configured deployment command when drift is found.
The project is intentionally narrow: it is a reconciliation loop for workload image state. It is not a container orchestrator.
For each configured workload, reconD repeatedly:
- Fetches the latest
deployment-metadata.jsonfor an environment. - Reads the currently committed deployment state from disk.
- Inspects the configured container to detect runtime drift.
- Pulls the desired image.
- Runs an optional deployment preparation strategy.
- Runs the configured
deploy_command. - Waits for the health check.
- Commits deployment state, or attempts rollback on failure.
The desired state is the deployment metadata emitted alongside an image release. The container registry is not treated as the source of truth by itself.
Use reconD when you already have:
- CI that builds and publishes container images.
- CI that publishes
deployment-metadata.jsonalongside image releases. - A single host that should run one named workload at a desired image version.
- A local command that knows how to deploy that workload on the host.
The deploy command can be docker run, a shell script, a Make target, or a
command that invokes Docker Compose. reconD does not understand or manage the
topology behind that command.
reconD does not manage:
- Docker Compose projects.
- Multi-container application topology.
- Service dependencies.
- Networking.
- Volumes.
- Secrets.
- Ingress or traffic routing.
- Load balancing.
- Scaling.
- Scheduling.
- Clusters.
- Infrastructure provisioning.
If a feature requires understanding application topology, dependency ordering, networking, routing, or workload composition, it belongs outside the agent.
The Git provider implementation fetches and unmarshals deployment-metadata.json.
The current GitHub implementation looks at image releases for the configured
environment. In practice, the environment usually corresponds to the prefix used
in image tags, such as dev or prod.
Example metadata:
{
"environment": "prod",
"image": "ghcr.io/my-account/app-repo",
"image_tag": "prod-sha-10a3e42",
"manifest_digest": "sha256:19779d908d890f704a2170d7dde679e266a9137613ea299b38939eb889545f8e",
"git_sha": "10a3e42cc477e9e6da84037474d45c8b1300e9f8",
"created_at": "2026-05-26T04:47:49Z"
}reconD currently loads JSON config files.
Minimal example:
{
"workloads": [
{
"name": "my-app",
"environment": "prod",
"container_name": "my-container",
"deploy_command": "make redploy-app",
"check_interval": "60s",
"state_dir": "/path/to/state/dir",
"git_provider": {
"owner": "my-account",
"repo": "app-repo"
},
"strategy": {
"type": "env_file",
"env_file_path": "/path/to/.env",
"image_tag_key": "IMAGE_TAG"
},
"health_check": {
"type": "http",
"url": "http://localhost:8080/health",
"retries": 12,
"interval": "10s",
"timeout": "5s"
},
"labels": {
"app": "my-app"
}
}
]
}Strategies run after the image is pulled and before deploy_command is
executed.
The first supported strategy is env_file.
{
"strategy": {
"type": "env_file",
"env_file_path": "/opt/gymportal/.env.deploy",
"image_tag_key": "IMAGE_TAG"
}
}This updates or creates the env file and sets:
IMAGE_TAG=<latest image tag>
If image_tag_key is omitted for the env_file strategy, it defaults to
IMAGE_TAG.
This is useful when the deploy command delegates to a local script or Compose file that reads the image tag from an env file.
Supported health check types:
httptcpnone
Recognized but not implemented:
command
HTTP example:
{
"health_check": {
"type": "http",
"url": "http://localhost:8080/health",
"retries": 12,
"interval": "10s",
"timeout": "5s"
}
}State is stored under each workload's state_dir.
Files:
deployed.json: the current successful deployment.previous.json: the previous successful deployment, used for rollback.
The state includes workload name, image, image tag, manifest digest, git SHA, deployment time, and rollback information when applicable.
If deployment fails after there is a previous successful deployment, reconD
attempts rollback using the previous state.
Rollback runs the same deployment flow with previous metadata:
- Pull previous image.
- Run the configured strategy with previous metadata.
- Run
deploy_command. - Wait for health.
- Commit rollback state.
Only one rollback generation is maintained initially.
Prerequisites:
- Go installed.
- Docker installed and available on
PATH. - A GitHub token if the release metadata is private.
- A config file.
Run tests:
env GOCACHE=/private/tmp/recond-go-build go test ./...Run the agent:
GITHUB_TOKEN=your_token_here go run . -config ./test/sample.config.jsonLogging is JSON by default.
Optional logging environment variables:
LOG_FORMAT=text
LOG_LEVEL=debugThe test/ directory contains a sample config and local Docker Compose fixture.
Example:
make -f ./test/Makefile dev-up
GITHUB_TOKEN=your_token_here LOG_FORMAT=text go run . -config ./test/sample.config.jsonThe sample deploy command calls:
make -f ./test/Makefile dev-redeployThat Make target is just the local deployment command. reconD does not parse
or manage the Compose file.
Required workload fields:
nameenvironmentcontainer_namedeploy_commandstate_dirgit_provider.ownergit_provider.repostrategy.type
Common optional fields:
notification_url: Slack webhook URL.check_interval: defaults to60swhen below10s.health_check.retries: defaults to12.health_check.interval: defaults to10s.health_check.timeout: defaults to5s.labels: labels used to scope Docker image pruning.
reconD ensures a single named workload is running the image specified by its
deployment metadata.
Everything else belongs to the deploy command or to external tooling.