Skip to Content
⚠️ Dockflow is currently under development. Bugs may occur. Please report any issues on GitHub.
ConfigurationBuild Strategy

Build Strategy

Dockflow supports different strategies for building and transferring Docker images to your servers.

Strategies Overview

StrategyBuild LocationTransfer MethodBest For
Local (default)CI/CD runnerSSH streamingSingle-node, small clusters
Local + RegistryCI/CD runnerDocker registryLarge multi-node clusters
RemoteTarget serverNone (built in place)Large contexts, slow networks

Local Build (Default)

Images are built in your CI/CD pipeline and transferred to the server via SSH. No additional configuration required.

How it works:

  1. Dockflow parses docker-compose.yml to extract build commands
  2. Images are built locally (in parallel if multiple services)
  3. Images are streamed to all Swarm nodes via SSH:
    docker save IMAGE | gzip -1 | ssh user@host "gunzip | docker load"

This is the simplest strategy and works for both single-node deployments and multi-node clusters. For larger clusters with many nodes or heavy images, consider using a registry instead.

Multiple images are built in parallel automatically. Build times are displayed per-service after completion.

Registry Build

For larger multi-node Swarm clusters, use a Docker registry so all nodes can pull images independently. This avoids streaming large images over SSH to each node individually.

How it works:

  1. Images are built locally (same as default)
  2. Images are pushed to your configured registry
  3. During docker stack deploy, each Swarm node pulls the image from the registry

See Docker Registry for full configuration (GHCR, GitLab, Docker Hub, self-hosted).

When to use:

  • Large multi-node clusters where SSH streaming becomes a bottleneck
  • When you want image versioning in a registry
  • CI/CD pipelines with native registry support

Remote Build

Build images directly on the server instead of transferring them:

# .dockflow/config.yml options: remote_build: true

How it works:

  1. Dockflow clones your repository on the target server (supports Git token authentication)
  2. Images are built directly on the server
  3. No image transfer needed — images are already where they need to be

For private repositories, add a GIT_TOKEN secret to your CI/CD environment. Dockflow auto-constructs authenticated URLs for GitHub and GitLab.

When to use:

  • Large build contexts that would be slow to transfer
  • Slow network connections between CI/CD and server
  • When the server has more build resources than your CI runner

Remote builds prune the Docker builder cache after each build to free disk space. Docker’s layer cache still works within a single build but is not preserved across deployments.

Trade-Offs

LocalLocal + RegistryRemote
Setup complexityNoneRegistry config neededGit access on server
Network usageSSH stream per nodeSingle push, nodes pullGit clone only
Build cacheFull local cacheFull local cachePruned between deploys
Multi-nodeStreaming to each nodeNative Swarm pullStreaming to workers
CI resourcesNeeds Docker on runnerNeeds Docker on runnerMinimal CI resources
Private reposN/AN/ANeeds GIT_TOKEN

Build-Only Mode

Use dockflow build to build images without deploying:

dockflow build production # Build all services dockflow build production --services app # Build specific service dockflow build production --push # Build and push to registry

This is useful for validating builds in CI before deploying, or for pre-building images.

Docker Cache

Docker caches image layers by default. When nothing changes in your source code or Dockerfile, subsequent builds reuse cached layers and complete in seconds.

To maximize cache efficiency:

  • Order Dockerfile instructions from least to most frequently changing
  • Copy dependency files (package.json, requirements.txt) before source code
  • Use multi-stage builds to separate build and runtime dependencies
# Example: good cache utilization FROM node:20-alpine AS build WORKDIR /app COPY package.json package-lock.json ./ # Changes rarely RUN npm ci # Cached if lockfile unchanged COPY . . # Changes often RUN npm run build FROM node:20-alpine COPY --from=build /app/dist ./dist COPY --from=build /app/node_modules ./node_modules CMD ["node", "dist/index.js"]

Next: Deployment — understand what happens when you deploy.