Skip to content

hrodrig/dcctl

Repository files navigation

dcctl — Docker Compose Control

version release Go 1.26 License: MIT

Repo: github.com/hrodrig/dcctl · Releases: Releases

CLI to manage Docker Compose stacks per environment using a single YAML config file. You define which manifests belong to each environment; dcctl runs docker compose with exactly those files for up, down, status, logs, and more.

Why dcctl? Onboarding new developers with the full product stack becomes trivial: one config, one command, and the whole stack is up. What used to take weeks of “where’s the compose for X?”, “which env file?” and “how do I run the 12 services?” drops to hours — clone, point dcctl at the config, run dcctl up, and you’re coding.

Documentation: Sequence diagrams (Mermaid) for main flows and terminal demo (recorded with VHS) — see docs/. Examples: examples/ — 10 runnable stacks (counter+Redis, WordPress, API+Postgres+Redis, full-stack, multi-env, Postgres+pgAdmin, Flask+Redis, Nginx+Go, Portainer, Prometheus+Grafana) with ports table and show-ports.

Terminal demo

Requirements

  • Go 1.26+ (to build)
  • Docker and Docker Compose (to run stacks)

Install

From source (recommended): Clone the repo, then:

go install ./cmd/dcctl
# or with version/commit/date baked in:
make install

This installs the binary to $GOBIN (default $HOME/go/bin). Ensure $GOBIN is on your PATH.

Pre-built binaries: Releases provide binaries (.tar.gz, .zip), .deb, and .rpm packages for Linux, macOS, and Windows (amd64 and arm64).

Homebrew (macOS):

brew install hrodrig/dcctl/dcctl

Build: To build in the current directory (e.g. for development):

go build -o dcctl ./cmd/dcctl
# or with version info:
make build
# Custom install path: GOBIN=~/bin make install

Docker

Published image (each release): Multi-arch images (linux/amd64, linux/arm64) are published to GitHub Container Registry as ghcr.io/hrodrig/dcctl. Use a version tag or latest.

docker pull ghcr.io/hrodrig/dcctl:v0.1.5
# or
docker pull ghcr.io/hrodrig/dcctl:latest

Build from source: The repo includes a multi-stage Dockerfile (Go 1.26, Alpine 3.19): build stage compiles the binary with version/commit/build date injected via build args; runtime stage is minimal and runs as non-root. Use make docker-build to build locally with version info.

Image details:

  • Runtime base: Alpine 3.19. Only ca-certificates for HTTPS. No shell or extra tools in the runtime image.
  • User: Runs as non-root user dcctl (binary in /home/dcctl/dcctl).
  • Labels: OCI image labels (title, description, source).

Build (from repo root): Use make docker-build so the image gets version, commit, and build date from the VERSION file and git (same as release builds).

Run with your config: dcctl inside the container reads config from ~/.dcctl/dcctl.yml (i.e. /home/dcctl/.dcctl/dcctl.yml). Mount your config directory and the Docker socket so the container can use your manifests and talk to the host Docker daemon:

docker run --rm -it \
  -v ~/.dcctl:/home/dcctl/.dcctl \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/hrodrig/dcctl:latest up

Use any dcctl command in place of up (down, status, logs, show-ports, etc.). If the host Docker socket is only readable by the docker group, run the container with that group (e.g. --group-add $(stat -c '%g' /var/run/docker.sock) on Linux, or ensure the numeric GID matches). For a project-specific config, mount the project dir and pass --config-file:

docker run --rm -it \
  -v /path/to/project:/home/dcctl/project:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/hrodrig/dcctl:latest --config-file=/home/dcctl/project/dcctl.yml up

Quick start

  1. Create a config file:
mkdir -p ~/.dcctl
dcctl config > ~/.dcctl/dcctl.yml
  1. Edit ~/.dcctl/dcctl.yml: set dcctl.default_environment and dcctl.environments.<name>.services (list of manifest names).

  2. Create compose manifests next to the config:

  • Path pattern: <config_dir>/<environment>/<service>.yml
  • Example: ~/.dcctl/default/app.yml for environment default and service app.
  • Or run dcctl manifests to write a sample sample-app.yml (rename to app.yml and add app to services if needed).
  1. Start services:
dcctl up
dcctl status
dcctl show-ports    # see published ports and where to connect
dcctl logs -f
dcctl down

Try without a config: run an example with dcctl --config-file=examples/01-counter-redis/dcctl.yml up (see examples/; you must pass --config-file because dcctl does not look in the current directory).

Config file

dcctl looks for config in one place only when you don’t pass --config-file: ~/.dcctl/dcctl.yml. It does not look in the current directory.

  • Default (only): ~/.dcctl/dcctl.yml
  • Any other path (e.g. project dir): dcctl --config-file=/path/to/dcctl.yml (required for per-project configs)

Concept: You define environments (e.g. default, uat, prod, fix — any names you want). You choose which one to use either from the CLI with -e/--environment or by setting default_environment in the config. Inside each environment you list the services (manifest names) that dcctl should run; the actual Compose files live at <config_dir>/<environment>/<service>.yml. So one config file, multiple environments, each with its own set of manifests.

Schema (see dcctl config output):

  • schema_version: config format version
  • common.compose.project_name: Docker Compose project name
  • common.compose.ignore_orphans: whether to remove orphan containers
  • common.dcctl.verbose_level: 0=quiet, 1=normal, 2=verbose, 3=debug
  • dcctl.default_environment: environment used when you don’t pass -e
  • dcctl.environments: map of environment name → list of service (manifest) names

Commands

Command Description
dcctl config Print default dcctl.yml template
dcctl up [service...] Start services (optional --health-check)
dcctl down [service...] Stop and remove services
dcctl restart Restart all services
dcctl status Show container status (compose ps)
dcctl logs [service] View logs (-f follow, --tail N)
dcctl exec <service> <cmd> [args...] Run command in container
dcctl manifests Write sample compose file to environment dir
dcctl image ls [service] List images from current environment manifests
dcctl image pull [service] Pull those images (latest)
dcctl image remove [service] Remove those images (with confirmation)
dcctl show-ports List published ports per service (where to connect: browser, API, DB)
dcctl volumes clean [volume...] Remove volumes (interactive or by name, --match regex)
dcctl version Show version (-s short, -o json|yaml|text)
dcctl completion bash|zsh|fish|powershell Shell completion

Use -e / --environment to select an environment; --config-file to use a different config file; --debug for debug logging.

Build and release

Local build (version from VERSION file):

make build
# override: make build VERSION=v0.2.0

Docker image (local):

make docker-build
# image tagged as dcctl, with version/commit/build date from VERSION and git

Release (from main, requires goreleaser):

brew install goreleaser   # or see goreleaser install docs
git tag v0.1.0
make release
  • Builds binaries for linux/darwin/windows (amd64, arm64), archives, checksums, .deb/.rpm, Docker image (ghcr.io), and Homebrew tap.
  • Create a Homebrew tap repo (e.g. homebrew-dcctl) and set HOMEBREW_TAP_TOKEN in CI for brew install hrodrig/dcctl/dcctl.

Snapshot (no tag): make snapshot — outputs to dist/.

License

MIT. See LICENSE.

About

Manage Docker Compose stacks per environment with one YAML config.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors