LogoRevali

revali compose

Generate a docker-compose.yaml for every service in a repository

The revali compose command writes a docker-compose.yaml covering every Revali service in the repository.

revali_docker produces a Dockerfile per service, which is enough to ship one of them and not enough to run the system. This is the other half: one file that brings the whole fleet up together.

Basic Usage#

dart run revali compose
Wrote 3 service(s) to /repo/docker-compose.yaml

Then:

docker compose up

What It Generates#

docker-compose.yaml
# Generated by `revali compose`. Safe to edit — regenerating
# overwrites, so keep hand-written additions in an override
# file (compose.override.yaml).
#
# Each service is given its port via the PORT environment
# variable, which `AppConfig.fromEnv()` reads. A service that
# hard-codes its port will ignore this and the mapping below
# will point at nothing.

services:
  orders:
    build:
      context: services/orders
      dockerfile: .revali/build/Dockerfile
    environment:
      PORT: '8080'
    ports:
      - '8080:8080'
    restart: unless-stopped

  billing:
    build:
      context: services/billing
      dockerfile: .revali/build/Dockerfile
    environment:
      PORT: '8081'
    ports:
      - '8081:8081'
    restart: unless-stopped

Ports are assigned sequentially from --base-port, in the same path order revali services lists — so a service keeps its port between revali up and docker compose up.

Services Without a Dockerfile#

A service that has not been built yet is still written out, with a comment saying so, and the command warns:

1 service(s) have no Dockerfile yet. Run `revali build` in: services/users

Omitting it would have been quieter and worse: a service silently missing from the compose file is harder to notice than one that fails to build.

Regenerating#

The file is overwritten every run. Keep hand-written additions — a database, a Redis instance, a volume — in compose.override.yaml, which Docker Compose merges automatically:

compose.override.yaml
services:
  redis:
    image: redis:7-alpine
    ports:
      - '6379:6379'

  orders:
    environment:
      REDIS_URL: redis://redis:6379

Options#

FlagMeaning
--root <path> Directory to search from. Defaults to the working directory.
--output, -o <path> Where to write. Defaults to docker-compose.yaml at the root.
--base-port <port> First host port to assign; services take one each in order. Defaults to 8080.
--stdoutPrint instead of writing a file.

Duplicate Service Names#

Compose keys are YAML mapping keys, and package names are not unique across a repository — several example services can legitimately be called hello. A duplicate key does not error in YAML: the later entry silently replaces the earlier one and a service vanishes from the system it was meant to describe.

So colliding names fall back to a key derived from the service's path, which is unique by construction:

services:
  services-orders-hello:
    ...
  examples-hello:
    ...