docker-ops

module
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: Apache-2.0

README

Technical specification: dq — Docker Quick-ops

Language: English · Русский

Status: Go implementation (draft specification in this file).
CLI binary: the dq executable in this repository; the Bash/Python wrapper has been removed.

Full product name: Docker Quick-ops (binary: dq).


1. Rationale and goals

1.1 Problem (historically)
  • The previous stack based on Bash, rsync/ssh/scp, and Python for YAML led to drift between environments.
1.2 Goal

A single statically linkable dq binary that:

  • reads configuration from **docker-ops.yaml** or **docker-ops.yml** only at the project root (no alternate paths such as scripts/);
  • keeps secrets and sensitive values in a separate **dq.env** file (listed in **.gitignore**), merged into settings;
  • exposes a CLI built with spf13/cobra;
  • generates shell completions (bash/zsh/fish as needed) and man pages from Cobra metadata (or related tooling);
  • transfers files over SSH from Go without requiring rsync/scp on the user machine;
  • supports cross-compilation for major OS/arch combinations (linux/windows/darwin, amd64/arm64, etc.).
1.3 Non-functional expectations
  • Runtime self-sufficiency: no Python and no mandatory rsync on the client.
  • Predictable behaviour and clear error messages.
  • Versioned releases (tags, changelog — as decided).

2. Terminology

Term Meaning
Project root Directory from which the user runs dq (current cwd).
Local mode No remote host configured, or remote explicitly disabled (--local / config flag / environment variable).
Remote mode Host and server path are set; commands run over SSH on the remote machine (dq is not installed on the server).
source deploy mode Sync project tree to the server + remote reup (build on server).
artifacts deploy mode Server receives image-only compose, optional app config if set, image via registry or save/load.

3. Naming and branding

  • Full name: Docker Quick-ops.
  • Executable: dq.
  • Use Docker Quick-ops (dq) in dq version, man NAME, and documentation.

4. Solution architecture

4.1 Language and modules
  • Go (version pinned in go.mod, LTS branch).
  • Cobra — root command dq, subcommands instead of “first argv = command”.
  • Packages (roughly): config, compose (CLI and API if needed), remote/ssh, tree mirroring, deploy, internal/version.
4.2 Configuration
  • Main file: only ./docker-ops.yaml or ./docker-ops.yml at the project root (relative to cwd). No other standard paths (including scripts/).
  • Secrets: separate **dq.env** at project root (dotenv / shell-assignments), must be in .gitignore; values merge into config (precedence vs YAML fields — defined in code; env file usually wins).
  • Validation on startup; clear errors when required fields for a command are missing.
4.3 SSH and file copy
  • Key-based auth (path from config / ssh-agent / OpenSSH defaults).
  • Directory sync without rsync on the client: SFTP + size/mtime comparison; no repo size cap for now (may add later).
  • Image stream docker save | … | docker load: over SSH via stdin or temp file on server — implementation-specific (disk and safety).
4.4 Docker interaction
  • Current: only docker compose (Compose V2 plugin for Docker CLI). Standalone docker-compose (V1) is not supported — if the plugin is missing, dq prints install hints (see Docker docs). Same locally and on the remote host over SSH (remote shell runs commands; dq is not installed on the server).
  • Extensions: may use **docker.sock** (local Docker API).
  • Planned: HTTP Docker API (including remote hosts). Access on the server via SSH to the Docker socket (/var/run/docker.sock on the remote host): forward/tunnel in the SSH session (local Unix socket or TCP proxy on the client), without exposing the Docker API on the network. Transport details — in implementation (see §14.2).
4.5 Remote execution (no dq on server)
  • Subcommands such as up, logs, deploy in remote mode use one SSH session / remote shell running **docker compose …** in remote_path.
  • In artifacts mode, deploy files are delivered (image compose, optional app config, etc.), not the dq binary.
4.6 Cobra: shell completion and man
  • dq completion bash|zsh|fish|powershell.
  • dq man [subcommand…] — man page from Cobra metadata, viewed with man -l (man-db / groff). If man is not in PATH, troff source goes to stdout.
  • Static generation into man/man1/: make gen-man (go run ./tools/genman); install: make install-man (MANPREFIX, default /usr/local/share/man).
  • Single source of truth: Cobra → --help, completion, and man.

5. Functional requirements

5.1 General behaviour
  • Project root: current working directory; optional --project-dir / **DQ_PROJECT_ROOT**.
  • Load docker-ops.yaml | docker-ops.yml + dq.env when present.
  • Setting precedence: §14.1.
5.2 Configuration fields

Minimal set (snake_case in YAML):

Area Fields
Compose compose_project_name, compose_file, compose_service
Remote remote_ssh, remote_path, ssh_identity
Sync exclude list (global); options equivalent to legacy rsync_extra map to internal sync
Deploy deploy_mode (source or artifacts), deploy_image (single built image), optional deploy_images (YAML map: service name → image ref for multiple build: services), optional deploy_build_remote (artifacts: docker build / docker push on the server after mirroring the tree), deploy_push, deploy_use_registry, deploy_save_load, deploy_save_compress. Env: DEPLOY_IMAGE, and DEPLOY_IMAGES=svc=ref,svc2=ref2 in dq.env or process env (same format; overrides YAML deploy_images when set — §14.1).
Extra paths deploy_include — relative to project root
Application **app_config** (or equivalent): optional path to app config for copying in artifacts and for config-check; if unset — check/copy not required (often no file exists)
UX help_show_effective and others as needed
5.3 CLI commands
Command Locally Remotely
help / --help yes yes
man man from Cobra (man -l) yes
env (config template) local only do not proxy
config-check if app_config set — verify file; else no-op or info same over SSH
build, pull, up, down, reup, ps, restart docker compose … SSH + docker compose … in remote_path
status ps + log tail same over SSH
logs, logs-tail, exec follow / tail / exec -it in terminal SSH; PTY for follow and interactive exec
deploy source: SFTP mirror. artifacts: by default local docker (build) + upload; with deploy_build_remote: SFTP mirror, then docker build (and push if not save/load) on the server — no local Docker required for the image build. Needs configured remote. source or artifacts

deploy:

  • source: directory on server, tree sync with exclude, copy app_config when configured and file exists, then remote reup.
  • artifacts: when deploy_push: true or dq deploy --build, images are built with docker build — by default on this machine, then save/load or registry as configured. With deploy_build_remote: true (only with deploy_mode: artifacts, e.g. DEPLOY_BUILD_REMOTE=1) the tree is mirrored over SFTP (like source, honoring exclude) and docker build / registry docker push (when not save/load) run on the server; local Docker is not required for the build. The same image tags apply: deploy_image, or deploy_images in YAML, or DEPLOY_IMAGES=… in env — including when resolving which docker build -t … and push commands run (locally or on the server). Registry vs save/load; deliver docker-compose.image.yml, app_config if set, deploy_include; on the server: config-check (if applicable) → up or pull+up. The dq binary is not copied to the server. Draft docker-compose.image.yml: dq gen-image-compose. For several built services, deploy_images / DEPLOY_IMAGES and dq gen-image-compose --all-built; if no multi-image config, the single-deploy_image (or DEPLOY_IMAGE) flow applies.
  • Data on server (artifacts): by default the whole remote_path project tree is not fully mirrored (only the compose, image delivery, and configured paths) — extra dirs (e.g. db-data) are not removed unless in deploy_include. If you use deploy_build_remote, a full mirror to remote_path runs for the build (see exclude). In all cases, ensure docker-compose.image.yml uses the same volume path for DB data, etc. source can delete server-only extras during sync — riskier for a live DB inside the project tree.
5.4 env command (template)
  • Print docker-ops.yaml template to stdout or --output with --force.
  • --anonymize: do not substitute real remote_ssh / remote_path from config/env.

6. Platforms

  • Linux — primary target.
  • Windows initially: WSL2 is enough (full native Windows not required in v1).

7. Build and distribution

  • Go module: github.com/SomniSom/docker-ops (repo: https://github.com/SomniSom/docker-ops). Install from source: go install github.com/SomniSom/docker-ops/cmd/dq@latest.
  • dq version and the product number: a release build (GitHub Releases asset, or your own go build / make with -ldflags) sets v1.1.0, v1.1.2, etc. — a single line like Docker Quick-ops v1.1.2 (a1b2c3d). A plain go install ...@latest (or @v1.1.2) embeds the Go module pseudo-version (e.g. v1.0.1-0.20260407201612-08053888e894), which comes from the module graph, not the human marketing tag. That is expected; dq version may print a second Note line in that case. To align the string with a git tag, use: make build VERSION=$(git describe --tags --always) or a prebuilt archive from Releases (GoReleaser sets -X .../version.Version={{.Version}} to v1.1.2 for that tag build).
  • go build / make build / make install — see Makefile (VERSION, GIT_COMMIT, ldflags → internal/version).
  • OS/arch matrix: GitHub Actions (.github/workflows/ci.yml) — tests on Linux / macOS / Windows and cross-build linux|darwin|windows × amd64|arm64.
  • GoReleaser (.goreleaser.yaml): same targets, archives (tar.gz / zip on Windows), checksums.txt, injects release semver into the binary. Locally: make goreleaser-check, snapshot: make goreleaser-snapshot (goreleaser required). Pushing a git tag v* runs .github/workflows/release.yml and publishes a GitHub release; that is the usual way to get a binary whose dq version shows exactly the tag.
  • man — make gen-man / make install-man (§4.6).

8. Localization

  • UI language (messages, subcommand help, errors): English by default.
  • If the system locale is Russian (LANGUAGE, LC_ALL, LC_MESSAGES, LANGru prefix) — use Russian (internal/locale).
  • Explicit: DQ_LANG=en|ru|auto (overrides auto) or global dq --lang en|ru|auto (persistent flag; e.g. dq up --lang ru allowed).
  • Product name in dq version and root help: Docker Quick-ops (not translated).

9. SSH security

  • SSH host key behaviour like accept-new for known_hosts (analogous to StrictHostKeyChecking=accept-new in OpenSSH).

10. Licensing

  • Project license: Apache License 2.0 (**LICENSE** in repo root). Fork and use per license terms.
  • Binary signing (cosign, etc.) not required in v1.

11. Legacy file names

  • Old names (**docker-ops.remote.yaml**, **docker-ops.remote.env**, etc.) are not supported: only **docker-ops.yaml / docker-ops.yml** + **dq.env**. Migrate manually per docs.

12. Migration from the Bash version

  • Mapping old docker-ops.remote.* / env vars → docker-ops.yaml + dq.env — document in roadmap table.
  • No automatic migration (optional tool separately).
  • Bash/Python scripts removed from the repo; use dq only.

13. Acceptance criteria (draft)

  • All commands from §5.3 in local mode on Linux with Docker installed.
  • Remote mode without dq on server: e2e deploy (source and artifacts with save/load) over SSH.
  • No Python or mandatory rsync on client; sync via SFTP + size/mtime.
  • Config only at root: docker-ops.yaml | docker-ops.yml; secrets in dq.env; merge order §14.1.
  • dq completion bash|zsh and man per §4.6.
  • Localization: en default, ru for Russian locale / DQ_LANG / --lang (§8).
  • WSL2 user scenario documented and verified where possible.

14. Decisions (clarifications)

14.1 Configuration precedence and dq.env

For each parameter (YAML key, logical env var name), order is weaker → stronger (stronger overrides):

  1. **docker-ops.yaml / docker-ops.yml** — base values from file at project root.
  2. **dq.env** — secrets file; overrides matching parameters from YAML (same key in either file; if both exist, dq.env wins).
  3. Process environment (CI/CD, export, systemd) — highest; overrides YAML and dq.env.

Parameters only in YAML and absent from dq.env and process env come from YAML. Empty or missing lines in dq.env should not wipe YAML without an explicit rule in code (recommendation: treat empty as “unset” and do not override YAML). DEPLOY_IMAGES=app=ghcr.io/ns/a:1,worker=ghcr.io/ns/w:1 in dq.env or the process environment replaces the deploy_images map from YAML when non-empty (same as other DEPLOY_* overrides; see list in internal/config/overlay.go).

14.2 Remote Docker API and SSH socket

Future Docker API access on remote hosts: via SSH to the Docker socket on the server (typically Unix socket /var/run/docker.sock). dq should establish an SSH tunnel (or library equivalent) so the user machine gets a local endpoint (Unix socket or 127.0.0.1:port) pointing at remote Docker; API client talks to that endpoint. No need to expose the Docker daemon on the internet.

14.3 License

Apache License, Version 2.0; full text in LICENSE at repo root.


Implementation (Go)

  • Sources: cmd/dq, internal/config, internal/cli, internal/compose, internal/deploy, internal/sshexec, internal/remote, internal/version, tools/genman.
  • No Bash/Python scripts in the repo (formerly scripts/).
  • Build: make buildbin/dq; make install via go install.
  • Tests: make test / make test-unit (-race); make test-integration-tags=integration (Docker with Compose V2 plugin required).
  • Detailed status — Roadmap below.

Roadmap (implementation status)

Legend: [x] done · [ ] not done / planned.

Configuration and validation
  • docker-ops.yaml / docker-ops.yml only at project root
  • dq.env and merge order §14.1 (YAML → dq.env → process env)
  • Defaults compose_project_name (directory name), compose_file, compose_service
  • dq validate (YAML, deploy_mode, app_config on disk, deploy_build_remote requires deploy_mode: artifacts, dq.env syntax)
  • Clear errors on YAML syntax (line context, indentation hints)
  • dq env (--output, --force, --anonymize)
  • Deeper semantic validation (e.g. all deploy fields, ssh_identity exists)
Local mode (Docker Compose via CLI)
  • build, pull, up, down, reup, ps, restart, exec, status, logs, logs-tail
  • Check app_config before up / reup when path set
  • Integration test with Docker (-tags=integration)
  • Compose V2 required (docker compose); no docker-compose V1 fallback — missing plugin shows install hint
Remote mode (no dq binary on server)
  • Compose commands over SSH in remote_path (internal/sshexec, internal/remote) — build, pull, up, down, reup, ps, restart, exec, status, logs, logs-tail
  • Auth: ssh_identity (path, ~ allowed) and/or ssh-agent (SSH_AUTH_SOCK)
  • New host keys: append to ~/.ssh/known_hosts (accept-new); key change — refuse
  • TTY / PTY for logs -f with interactive terminal
  • Disable remote: DOCKER_OPS_USE_REMOTE=0 or use_remote: false in YAML
Deploy
  • deploy in source mode: SFTP tree sync, exclude list, deploy_include, optional app_config, remote reup
  • deploy in artifacts mode: docker build (local or with deploy_build_remote on the server), registry vs save/load, deliver docker-compose.image.yml and files, remote pull+up or up
  • Map rsync_extra → internal sync options (if still in spec)
Docker beyond docker compose CLI
  • Local docker.sock / API (§4.4)
  • Remote Docker API via SSH tunnel to socket (§14.2)
CLI, docs, release
  • Cobra, dq completion (bash / zsh / fish / powershell)
  • dq version + Makefile ldflags
  • Man pages: dq man, make gen-man / make install-man (§4.6)
  • GoReleaser + CI OS/arch matrix, archives, checksums (§7, .goreleaser.yaml, .github/workflows/)
Localization
  • Messages and help: en default, ru for Russian locale (§8), package internal/locale
  • --lang, DQ_LANG
Other
  • Artifact signing (cosign, etc.) — not required in v1 (§10)

May move to docs/spec-dq.md; this readme.md is the living English spec. Russian: readme.ru.md.

Directories

Path Synopsis
cmd
dq command
dq — Docker Quick-ops CLI (see readme.md).
dq — Docker Quick-ops CLI (see readme.md).
internal
cli
Package cli constructs the dq Cobra command tree: compose helpers, deploy, validation, shell completion, and man-page generation.
Package cli constructs the dq Cobra command tree: compose helpers, deploy, validation, shell completion, and man-page generation.
compose
Package compose runs docker compose as a subprocess (readme §4.4).
Package compose runs docker compose as a subprocess (readme §4.4).
composeimage
Package composeimage rewrites a Compose file for artifacts deploy (build → image).
Package composeimage rewrites a Compose file for artifacts deploy (build → image).
config
Package config loads docker-ops.yaml / docker-ops.yml and dq.env per readme §14.1.
Package config loads docker-ops.yaml / docker-ops.yml and dq.env per readme §14.1.
locale
Package locale selects English (default) or Russian UI strings (readme §8).
Package locale selects English (default) or Russian UI strings (readme §8).
remote
Package remote runs docker compose on a host over SSH (readme §4.5).
Package remote runs docker compose on a host over SSH (readme §4.5).
version
Package version is set at link time via -ldflags, with runtime fallback from build metadata.
Package version is set at link time via -ldflags, with runtime fallback from build metadata.
tools
genman command
Genman writes man pages under man/man1/ (English UI strings).
Genman writes man pages under man/man1/ (English UI strings).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL