Overview

migetpacks supports Docker Compose files for building multi-service applications. When a compose file is detected, all services with a build section are built and pushed to the registry as separate images.

Detection Priority

migetpacks looks for compose files in the following order:
1

COMPOSE_FILE environment variable

If set, this path is used directly.
2

compose.yaml

The modern default compose file name.
3

compose.yml

Alternative YAML extension.
4

docker-compose.yaml

Legacy Docker Compose file name.
5

docker-compose.yml

Legacy alternative YAML extension.
If none of these files are found, migetpacks falls back to standard language detection and single-image build.

Image Naming

Each service’s image is named by appending the service name to OUTPUT_IMAGE:
OUTPUT_IMAGE-{service_name}
For example, with OUTPUT_IMAGE=registry.io/myapp:latest:
ServiceImage Name
apiregistry.io/myapp-api:latest
webregistry.io/myapp-web:latest
workerregistry.io/myapp-worker:latest

Example

compose.yaml

services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    ports:
      - "5000:5000"

  web:
    build:
      context: ./web
      dockerfile: Dockerfile
    ports:
      - "3000:3000"

  worker:
    build: ./worker  # shorthand syntax

Project Structure

my-project/
├── compose.yaml
├── api/
│   ├── Dockerfile
│   ├── main.go
│   └── go.mod
├── web/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
└── worker/
    ├── Dockerfile
    ├── requirements.txt
    └── worker.py

Build Command

docker run --rm \
  -v /path/to/my-project:/workspace/source:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=registry.io/myapp:latest \
  miget/migetpacks:latest

Build Output

The build produces three images:
  • registry.io/myapp-api:latest
  • registry.io/myapp-web:latest
  • registry.io/myapp-worker:latest

Custom Compose File

Use COMPOSE_FILE to specify a non-standard compose file:
docker run --rm \
  -v /path/to/project:/workspace/source:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=registry.io/myapp:latest \
  -e COMPOSE_FILE=docker-compose.prod.yaml \
  miget/migetpacks:latest

Compose File Syntax

migetpacks supports both the full and shorthand build syntax:
services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
      args:
        NODE_ENV: production

Services Without Build Sections

Services without a build section (e.g., database services using pre-built images) are skipped:
services:
  api:
    build: ./api          # Built and pushed

  web:
    build: ./web          # Built and pushed

  postgres:
    image: postgres:16    # Skipped (no build section)

  redis:
    image: redis:7        # Skipped (no build section)
Only api and web are built; postgres and redis are ignored.

Build Caching with Compose

Registry-based caching works with compose builds. Each service gets its own cache image:
docker run --rm \
  -v /path/to/project:/workspace/source:ro \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e OUTPUT_IMAGE=registry.io/myapp:latest \
  -e CACHE_IMAGE=registry.io/myapp:buildcache \
  miget/migetpacks:latest

CI/CD Example

GitHub Actions

name: Build Multi-Service App

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: self-hosted

    steps:
      - uses: actions/checkout@v4

      - name: Log into registry
        uses: docker/login-action@v3
        with:
          registry: your-registry.io
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}

      - name: Build all services
        run: |
          docker run --rm \
            -v ${{ github.workspace }}:/workspace/source:ro \
            -v /var/run/docker.sock:/var/run/docker.sock \
            -e OUTPUT_IMAGE=your-registry.io/myapp:${{ github.sha }} \
            miget/migetpacks:latest
This produces:
  • your-registry.io/myapp-api:{sha}
  • your-registry.io/myapp-web:{sha}
  • your-registry.io/myapp-worker:{sha}