Skip to content

dokku/docker-orchestrate

docker-orchestrate

A Docker CLI plugin to deploy Docker Compose services with support for rolling updates, custom healthchecks, and container naming conventions.

Why

Docker Compose is often used as a way to deploy workloads on single servers, but does not natively support rolling restarts, despite support in the specification. This tool aims to fill that gap by implementing the deploy.update_config against a locally run docker compose project.

Installation

To install as a Docker CLI plugin, build the binary and move it to your Docker plugins directory:

make install

Once installed, this plugin is available via docker orchestrate.

Usage

Deploy all services in a compose file:

docker orchestrate deploy

Deploy a specific service:

docker orchestrate deploy web

Deploy a service with a specific number of replicas:

docker orchestrate deploy web --replicas 5

Deploy with one or more profiles enabled:

docker orchestrate deploy --profile production
docker orchestrate deploy --profile production --profile monitoring
docker orchestrate deploy --profile production,monitoring

Deploy while skipping database services:

docker orchestrate deploy --skip-databases
docker orchestrate deploy web --skip-databases

Arguments

  • service-name: The name of a service in the compose file to deploy

Flags

  • -f, --file: Path to the Compose configuration file (defaults to docker-compose.yaml or docker-compose.yml).
  • -p, --project-name: Specify an alternate project name (defaults to the directory name).
  • --project-directory: Specify an alternate working directory.
  • --container-name-template: Go template for container names. Available variables: .ProjectName, .ServiceName, .InstanceID. Default: {{.ProjectName}}-{{.ServiceName}}-{{.InstanceID}}.
  • --profile: One or more profiles to enable. Can be specified multiple times or as a comma-separated list.
  • --replicas: Override the number of replicas for a specific service. This flag requires a service-name argument.
  • --skip-databases: Skip deploying database services - as detected by image - when deploying the entire project or a specific service.

Deployment Order

When deploying a project, services are deployed in the following order:

  • If a web service exists with no dependencies, it is deployed first
  • All other services are deployed in dependency order (dependencies before dependents)
  • If the web service has dependencies, it follows normal dependency ordering

Detected Database Services

When using the --skip-databases flag, docker-orchestrate automatically detects database services by examining the service's image repository. A service is considered a database if its image matches any of the following repositories:

  • clickhouse/clickhouse-server
  • couchdb (library/couchdb)
  • elasticsearch (library/elasticsearch)
  • dokku/docker-grafana-graphite
  • mariadb
  • getmeili/meilisearch
  • memcached (library/memcached)
  • mongo (library/mongo)
  • mysql (library/mysql)
  • nats (library/nats)
  • omnisci/core-os-cpu
  • postgres (library/postgres)
  • fanout/pushpin
  • rabbitmq (library/rabbitmq)
  • redis (library/redis)
  • rethinkdb (library/rethinkdb)
  • solr (library/solr)
  • typesense/typesense

Detection is based on the image repository name (short name), so it works regardless of the image tag or registry. For example, both postgres:14 and myregistry.com/library/postgres:latest would be detected as database services.

Skipping Services by Label

You can skip individual services by adding the com.dokku.orchestrate/skip label with a value of "true" to the service definition. This is useful when you want to exclude specific services from deployment without using the --skip-databases flag.

services:
  web:
    image: nginx:alpine
    labels:
      com.dokku.orchestrate/skip: "true"
  api:
    image: myapp/api:latest
    # This service will be deployed normally

When a service has this label set to "true", it will be skipped during deployment.

Note: The label value must be exactly the string "true" (case-sensitive). Other values like "false", "yes", or "1" will not trigger skipping.

Skipping Model Services

Services that define models (via the models field) are automatically skipped during deployment. Model services are typically used for service composition and should not be deployed directly by docker-orchestrate.

services:
  app:
    models:
      model1:
        # model configuration
  web:
    image: nginx:alpine
    # This service will be deployed normally

Skipping Provider Services

Services that use external providers (defined via the provider field) are automatically skipped during deployment. Provider services are typically managed by external systems (like cloud providers) and should not be deployed by docker-orchestrate.

services:
  database:
    provider:
      type: awesomecloud
      options:
        type: mysql
        foo: bar
  web:
    image: nginx:alpine
    # This service will be deployed normally

Script Extensions

In addition to native healthchecks, docker-orchestrate supports extended functionality via custom fields within the update_config section of a service.

Script Healthchecks

The tool supports an extended healthcheck mechanism via the x-healthcheck-host-command field.

services:
  web:
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        order: start-first
        x-healthcheck-host-command: |
          curl -f http://{{.ContainerIP}}:8080/health

The script healthcheck runs after the standard Docker healthcheck (if defined) succeeds.

Stop Commands

The tool supports several types of stop commands that are executed before and after a container is terminated (e.g., during a rolling update or scale down):

  • x-pre-stop-host-command: Executed on the host before stopping a container
  • x-pre-stop-command: Executed inside the container before stopping (synchronously via Docker SDK)
  • x-post-stop-host-command: Executed on the host after stopping a container
services:
  web:
    deploy:
      update_config:
        x-pre-stop-host-command: |
          curl -f http://{{.ContainerIP}}:8080/shutdown
        x-pre-stop-command: |
          #!/bin/sh
          echo "Stopping service gracefully..."
          kill -TERM 1
        x-post-stop-host-command: |
          echo "Container {{.ContainerShortID}} has been stopped"

Container Pre-Stop Commands

The x-pre-stop-command field allows you to run scripts inside the container before it is stopped. This is useful for graceful shutdowns, cleanup tasks, or any operations that need to run within the container's environment.

services:
  app:
    deploy:
      update_config:
        x-pre-stop-command: |
          #!/bin/bash
          # Graceful shutdown
          pkill -TERM -P 1
          sleep 2
          # Cleanup
          rm -f /tmp/app.lock
  • Scripts are written to /tmp/pre-stop.sh inside the container
  • Scripts run synchronously - docker-orchestrate waits for completion before stopping the container
  • Interpreter selection:
    • If the script has a shebang (e.g., #!/usr/bin/env bash), that interpreter is used
    • Otherwise, the container's Config.Shell property is used
    • Falls back to /bin/sh if neither is available
  • Shebang parsing:
    • #!/usr/bin/env bash/bin/bash -c
    • #!/bin/sh/bin/sh -c
    • #!/usr/bin/python3/usr/bin/python3 -c
    • Other interpreters are supported based on the shebang

Note: The container must have the following binaries available:

  • /bin/sh (or the shell specified in Config.Shell) - required for script execution
  • The interpreter specified in the shebang (if present) - must be available in the container's PATH

Detached Execution

By default, stop commands run synchronously and docker-orchestrate waits for them to complete before proceeding. You can configure commands to run in detached mode using x-pre-stop-host-command-detached and x-post-stop-host-command-detached. When set to true, the command runs asynchronously and will continue executing even if docker-orchestrate exits.

services:
  web:
    deploy:
      update_config:
        x-pre-stop-host-command: |
          # Long-running cleanup task
          ./cleanup-script.sh {{.ContainerID}}
        x-pre-stop-host-command-detached: true
        x-post-stop-host-command: |
          # Send notification asynchronously
          curl -X POST http://monitoring.example.com/notify
        x-post-stop-host-command-detached: true
  • Detached commands run in the background and do not block deployment
  • Detached commands continue running even if docker-orchestrate exits or is interrupted
  • Only boolean values (true or false) are allowed
  • If not specified, the default is false (synchronous execution)
  • Invalid values (non-boolean types) will result in an error

Script Templating

Both x-healthcheck-host-command, x-pre-stop-host-command, and x-post-stop-host-command are treated as Go templates and have access to:

  • .ContainerID: Full ID of the container.
  • .ContainerShortID: First 12 characters of the container ID.
  • .ContainerIP: Internal IP address of the container.
  • .ServiceName: Name of the service.

About

A docker plugin for orchestrating compose deploys

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Contributors

Languages