Skip to content
PithLab

↑↓ to move · Enter to open · Esc to close

Docker Run to Docker Compose Converter

Turn one or more docker run commands into a compose.yaml file.

Use via API

Convert one or more docker run commands into a docker-compose.yml: ports, volumes, env vars, networks, restart policy, healthchecks, resource limits and more. Unsupported flags come back as warnings. Send JSON, get JSON back.

POST https://pithlab.com/api/v1/tools/docker-run-to-compose

curl https://pithlab.com/api/v1/tools/docker-run-to-compose \
  -H "Authorization: Bearer $PITHLAB_KEY" \
  -H "Content-Type: application/json" \
  -d '{"command":"docker run -d --name web -p 8080:80 -e NGINX_HOST=example.com -v ./html:/usr/share/nginx/html:ro --restart unless-stopped nginx:1.27"}'

Fields and responseOpenAPI documentGet an API key

About the Docker Run to Compose

Convert docker run commands into a docker compose YAML file. Ports, volumes, env vars, networks, health checks, limits and logging are mapped for you.

How to use the Docker Run to Compose

  1. Paste one or more docker run commands. Put each on its own line, or join them with && or ;.
  2. Choose how memory and CPU limits are written: deploy.resources or the older mem_limit and cpus keys.
  3. Check the warnings for flags that compose cannot express, such as --rm.
  4. Copy the YAML or download it as compose.yaml, then start it with docker compose up -d.

Examples

Web server with ports, a bind mount and a restart policy

Input

docker run -d --name web -p 80:80 -p 443:443 -v ./html:/usr/share/nginx/html:ro --restart unless-stopped nginx:alpine

Output

services:
  web:
    image: nginx:alpine
    container_name: web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/usr/share/nginx/html:ro
Two containers on a shared network

Input

docker run -d --name db --network appnet -e POSTGRES_PASSWORD=secret -e POSTGRES_DB=app -v pgdata:/var/lib/postgresql/data postgres:16
docker run -d --name api --network appnet -p 3000:3000 -e DATABASE_URL=postgres://db/app --health-cmd "curl -f http://localhost:3000/health || exit 1" --health-interval 30s --health-retries 3 --memory 512m --cpus 0.5 ghcr.io/acme/api:1.4 node server.js

Output

services:
  db:
    image: postgres:16
    container_name: db
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - appnet
  api:
    image: ghcr.io/acme/api:1.4
    container_name: api
    command: ["node", "server.js"]
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://db/app
    networks:
      - appnet
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
      interval: 30s
      retries: 3
    deploy:
      resources:
        limits:
          memory: 512m
          cpus: "0.5"
volumes:
  pgdata: {}
networks:
  appnet:
    external: true

Frequently asked questions

Why is there no version: line at the top?

The current Compose Specification no longer uses the version key, and docker compose warns that it is obsolete. The file works with Docker Compose v2 as it is.

Why are some values in quotes?

Values like "80:80", "no" or "0.5" can be misread by older YAML parsers as numbers or booleans. The converter quotes them so compose always reads them as text.

What happens to --rm?

Compose has no setting for it, so it is left out with a warning. Use docker compose run --rm for one-off containers, or docker compose down to remove the stack.

Why is my network marked external?

A network used with --network is usually created first with docker network create, so it is declared external. Remove external: true to let compose create and manage it.

Should I pick deploy.resources or mem_limit?

Docker Compose v2 applies deploy.resources limits, and the Compose Specification prefers them. Choose mem_limit and cpus if you use older tools that only read those keys.