CLI Reference

build & pussh

Build Docker images and transfer them to servers.


build

Build Docker images locally or on a remote host.

Synopsis

odysseus build [options]

Options

--config FILE

Path to configuration file. Default: deploy.yml

odysseus build --config production.yml --image v1.0.0

--image TAG

Docker image tag. Optional: from a clean git repository, build takes the version from the commit SHA, the same way deploy does. --image is the quick, works-anywhere alternative. See deploy's --image TAG for what each route records.

odysseus build                  # clean git repo: version = commit SHA
odysseus build --image v1.0.0

--push

Push to registry after building.

odysseus build --image v1.0.0 --push

Requires registry configuration:

registry:
  server: ghcr.io
  username: myuser
  password: ${GITHUB_TOKEN}

--context PATH

Override build context path.

odysseus build --image v1.0.0 --context ./app

--verbose, -v

Same as --debug for build: the commands it runs are logged as they run. See Global options for what that does and does not redact.

odysseus build --verbose --image v1.0.0

Examples

# Build with default settings
odysseus build --image v1.0.0

# Build and push to registry
odysseus build --image v1.0.0 --push

# Build with custom context
odysseus build --image v1.0.0 --context ./backend

# Build for staging
odysseus build --config staging.yml --image staging-v1.0.0

pussh

Transfer Docker images directly to servers without a registry.

Synopsis

odysseus pussh [options]

How it works

pussh doesn't implement image transfer itself — it shells out to docker pussh IMAGE user@host once per configured host, the CLI plugin from docker-pussh/unregistry. That plugin has to be installed on the machine running odysseus first:

# macOS/Linux
mkdir -p ~/.docker/cli-plugins
curl -fsSL https://github.com/psviderski/unregistry/releases/latest/download/docker-pussh-$(uname -s)-$(uname -m) \
  -o ~/.docker/cli-plugins/docker-pussh && chmod +x ~/.docker/cli-plugins/docker-pussh

This is useful when:

  • You don't have a Docker registry
  • You want to avoid registry latency
  • You're deploying to a single server

Options

--config FILE

Path to configuration file. Default: deploy.yml

odysseus pussh --config production.yml --image v1.0.0

--image TAG

Docker image tag to transfer. Optional, resolved the same way as deploy's: the commit SHA from a clean git repository, or an explicit tag anywhere.

odysseus pussh                  # clean git repo: version = commit SHA
odysseus pussh --image v1.0.0

--build

Build the image before transferring.

odysseus pussh --build --image v1.0.0

--verbose, -v

Same as --debug for pussh. See Global options for what that does and does not redact.

odysseus pussh --verbose --image v1.0.0

Examples

# Transfer existing image
odysseus pussh --image v1.0.0

# Build and transfer
odysseus pussh --build --image v1.0.0

# Verbose output
odysseus pussh --verbose --build --image v1.0.0

Output

  Odysseus Pussh
  Image: myapp:v1.0.0

  01  ✓  Pushing image via SSH...
  02  ✓  Pussh complete (2 host(s))

With --build, an extra step builds the image first:

  Odysseus Pussh
  Image: myapp:v1.0.0

  01  ✓  Building image myapp:v1.0.0
  02  ✓  Pussh complete (2 host(s))

There's no per-host transfer detail or transfer speed in the output — each host's result comes back from its own docker pussh invocation, and only the count of hosts that succeeded is reported.


Build strategies

Local builds

Build on the machine running Odysseus:

builder:
  strategy: local
  arch: amd64
odysseus build --image v1.0.0

Remote builds

Build on a dedicated server:

builder:
  strategy: remote
  host: build-server.example.com
  arch: amd64
odysseus build --image v1.0.0

Remote builds:

  1. Sync source files to build server
  2. Run Docker build remotely
  3. Image is available on build server

Registry vs Pussh

With registry

registry:
  server: ghcr.io
  username: myuser
  password: ${GITHUB_TOKEN}
odysseus build --image v1.0.0 --push
odysseus deploy --image v1.0.0

Flow: Build → Push to registry → Servers pull → Deploy

Without registry (pussh)

odysseus pussh --build --image v1.0.0
odysseus deploy --image v1.0.0

Or combined:

odysseus deploy --build --image v1.0.0

Flow: Build → Transfer directly to servers → Deploy


Build configuration

Full configuration reference:

builder:
  strategy: local          # or 'remote'
  host: build.example.com  # for remote strategy
  arch: amd64              # or 'arm64'
  dockerfile: Dockerfile   # path to Dockerfile
  context: .               # build context
  build_args:              # build-time arguments
    RUBY_VERSION: "3.2"
    NODE_VERSION: "20"
  cache: true              # use Docker cache
  push: false              # push after build
  multiarch: false         # multi-architecture build
  platforms:               # for multiarch builds
    - linux/amd64
    - linux/arm64

Exit codes

CodeMeaning
0Success
1Configuration failed to load, the build failed, the registry push failed, or the transfer failed
Previous
rollback