comquad

module
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT

README ΒΆ

comquad (Compose + Quadlet 🍊)

comquad is a Docker-compose-like CLI for Podman Quadlets, backed by systemd.

It lets you define your services in a standard compose.yaml file and deploy them as individual systemd units using Podman's Quadlet technology. Instead of running its own orchestrator, comquad prepares the quadlet files and delegates lifecycle management entirely to systemd.

🎯 Design & Architecture Goals

comquad is designed to bridge the developer experience of Docker Compose with the operational guarantees of native systemd process management.

  • State-Aware Reconciliation: Tracks baseline deployment state in $XDG_DATA_HOME/comquad/ to perform unified color-coded diffs and 3-way merges on re-deployments (comquad up).
  • Preserved Manual Adjustments: Direct edits made to generated units via comquad edit are merged with incoming compose.yaml changes rather than blindly overwritten.
  • Label-Based State Recovery: Uses runtime Podman labels to reconstruct local project tracking (comquad regenerate) if the local state file is lost or corrupted.
  • Deterministic Previews: All lifecycle operations support --dry-run and -v to inspect generated quadlet diffs, port offset adjustments, and systemd actions before applying them.

πŸ› οΈ Requirements & Installation

Requirements
  • Podman 4.8+ (quadlet support with .image units)
  • systemd with quadlet support
  • Go 1.25+ (if building from source)
Installation
# Build from source (with version)
go build -ldflags "-X main.version=$(git describe --tags --always 2>/dev/null || echo dev)" -o comquad ./cmd/comquad/
sudo cp comquad /usr/local/bin/

# Or install directly via Go
go install github.com/Inoriol/comquad/cmd/comquad@latest

# Verify
comquad --version
Environment Variables
Variable Default Description
EDITOR auto-detected Editor for comquad edit. Falls back to editor, nano, vim, then vi.
NO_COLOR (unset) Set to any value to disable ANSI color output.
ROOTLESS_PORT_OFFSET 2000 In rootless mode, privileged ports (≀ 1024) are offset by this value.
XDG_DATA_HOME ~/.local/share Base directory for comquad/projects.json state file.

βš™οΈ Core Usage Workflow

1. Deploying a Project (up)

From a directory containing your compose.yaml:

comquad up

  • Follow logs: comquad up -f streams journal logs from the deployment timestamp.
  • Image Pull Control: comquad up --pull [always|missing|never] (default: missing).
  • Override name: comquad up -n my-service overrides the default project name.
  • Progress indication: Pipeline stages are reported during deployment (--verbose/-v for full detail).
  • Re-deploying with a diff: Running comquad up on an already-deployed project shows a color-coded diff of the pending changes and asks for confirmation before applying. Use comquad up --no-diff to skip the diff and prompt.
  • Manual edits are preserved: Changes made with comquad edit are three-way merged with new compose.yaml changes. If both touch the same directive, your edit wins and a warning is logged.
2. Monitoring & Lifecycle (ps, start, stop, logs)
# View container status (Docker Compose style)
comquad ps
comquad ps -a  # Includes exited containers

# Control services
comquad start [service ...]
comquad start --dry-run        # Preview which units would be started
comquad stop [service ...]
comquad stop --dry-run         # Preview which units would be stopped
comquad restart [service ...]
comquad restart --dry-run      # Preview which units would be restarted

# Stream logs (auto-sorted chronologically across units)
comquad logs                 # All services (one-shot)
comquad logs -f              # All services (follow)
comquad logs web             # Single service
comquad logs --tail 50       # Last 50 lines
comquad logs --since 10m     # Last 10 minutes

3. Interacting & Tearing Down (exec, down)
# Run commands inside containers
comquad exec web ls /app
comquad exec web sh                  # Interactive TTY shell
comquad exec -u root web bash        # Run as root

# Tear down the project
comquad down
comquad down -y                  # Skip confirmation prompt
comquad down -d                  # Also removes Podman volumes
comquad down --dry-run           # Preview what would be removed


πŸ” Advanced Features & Inspecting State

Dry Run & Verbose Preview

Before committing changes to systemd, you can preview exactly what comquad will do:

# Preview generated files without writing them
comquad up --dry-run

# Preview lifecycle actions without affecting running units
comquad start --dry-run
comquad stop --dry-run
comquad restart --dry-run
comquad down --dry-run

# Show every transformation (port offsets, path normalizations, etc.)
comquad up -v
comquad down -v     # Also works with all subcommands
comquad ps -v

comquad up --dry-run shows a diff rather than full files: new files as full content, changed files as a color-coded unified diff, and removed files (services dropped from compose.yaml) as a removal diff.

Direct Unit Editing & Viewing

You can view or edit the underlying systemd quadlet files on the fly:

# View the project overview with resource relationships
comquad view                 # Also accessible via `comquad overview`
comquad view web              # Shows the cq-<project>-web.container file content
comquad view db.image         # View a specific .image quadlet file

# Edit unit files directly (automatically triggers systemd daemon-reload)
comquad edit web
comquad edit --no-reload     # Open files without auto-reloading systemd

The view command provides a clean relational display showing each container's image, attached networks, and volumes, plus a separate table of all managed resources (images, networks, volumes) with copy-pasteable names.

Self-Healing & Repair

If your local state gets out of sync, comquad can rebuild its tracking from Podman labels:

comquad regenerate --force           # Reconstruct state file from live labels
comquad regenerate --force --dry-run # Preview what would be reconstructed
comquad check                          # Check prerequisites (tools, podman >= 4.8, D-Bus, target dir)

Managing Projects
# List all deployed projects (also accessible as `comquad ls`)
comquad list

# Shell completion generation
comquad completion bash              # Generate for bash
comquad completion zsh               # Generate for zsh
comquad completion fish              # Generate for fish

# Help with examples
comquad up --help                    # Each command shows usage examples
Getting Help

All commands have built-in examples β€” just append --help:

comquad up --help      # Deploy examples
comquad logs --help    # Logging examples with --since/--tail
comquad exec --help    # Container exec examples

πŸ—οΈ Architecture & Automatic Behaviors

comquad uses the compose2quadlet Go library (bundled in-tree) to map compose files directly into structured quadlet units in a single transpilation step. pull_policy, platform, secrets, and build: blocks are all handled natively by the library.

For a deep dive into how comquad processes compose files, manages state, and maps directories, check out the Architecture Guide.

Behind-the-Scenes Automations:
  • Path Fixing: Relative volume host paths are automatically fully qualified to absolute paths.
  • SELinux Smart Patching: When SELinux is active on the host, Volume= directives get ,z appended and Mount= directives get relabel=shared safely and idempotently.
  • Implicit Networks: A default bridge network (cq-default) is injected when any service lacks an explicit network, including projects that also define user networks.
  • Image Quadlet Generation: Every container gets a companion .image quadlet file. Compose image, pull_policy, and platform fields are extracted into dedicated image units so systemd can manage image pulls separately (enables podman auto-update).
  • Secrets Management: Compose secrets: are intercepted and translated into native quadlet directives; secret and Dockerfile cache write failures are surfaced as warnings.
  • Service Discovery: NetworkAlias= are injected into every .container with <project>-<service> and <service> blueprints so services can resolve each other same way as in docker compose networks.
  • Rootless Port Offsetting: In rootless mode, privileged ports (≀ 1024) are automatically shifted by ROOTLESS_PORT_OFFSET (default: 2000) to prevent deployment failures.
  • Change Detection & Reconcile: On re-deploy, comquad diffs the freshly generated quadlet files against the deployed ones (tracked via a baseline in $XDG_DATA_HOME/comquad/baseline/), preserves manual edit changes through a three-way merge, rolls back partial file/baseline writes on failure, restarts only changed units, and removes units for services dropped from the compose file.

🚧 Project Status: Infra-Built Utility

I am an infrastructure engineer, not a full-time software developer. I built Comquad to solve a specific problem for my own workflow.

  • Bugs: Feel free to open issues if a specific Docker Compose file breaks, but fixes will happen on a "best effort" timeline. I would also appreciate if you include --dry-run and -v outputs!

πŸ“„ License

MIT

Directories ΒΆ

Path Synopsis
cmd
comquad command
internal

Jump to

Keyboard shortcuts

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