Export running Docker containers as a docker-compose.yml file.
dexport inspects your running containers and generates a ready-to-use
Compose file from their actual configuration — ports, volumes, environment
variables, networks, restart policies, resource limits, and more.
Using Go Install
go install github.com/onyxhat/dexport@latest
From source (requires Go 1.25+):
git clone https://github.com/onyxhat/dexport cd dexport go build -o dexport .
Cross-compilation is supported for any OS and architecture Go targets:
GOOS=linux GOARCH=amd64 go build -o dexport-linux-amd64 . GOOS=linux GOARCH=arm64 go build -o dexport-linux-arm64 . GOOS=darwin GOARCH=arm64 go build -o dexport-darwin-arm64 . GOOS=windows GOARCH=amd64 go build -o dexport.exe .
Convenience build script automatically handles cross-compilation builds (requires Powershell/pwsh 5.0+)
./build.ps1
-
Docker must be running and accessible. The tool connects to the Docker daemon directly (no
dockerCLI required) using the default socket:- Linux/macOS:
/var/run/docker.sock - Windows:
//./pipe/docker_engine
The
DOCKER_HOST,DOCKER_TLS_VERIFY, andDOCKER_CERT_PATHenvironment variables are respected for remote or TLS-secured daemons. - Linux/macOS:
dexport [flags] [CONTAINER...]
Export all running containers to stdout:
dexport
Write to a file:
dexport -o compose.yml
Export specific containers by name or ID:
dexport nginx postgres redis dexport -o stack.yml nginx postgres
Include stopped containers:
dexport -a dexport -a -o compose.yml
Print version:
dexport -v
| Flag | Default | Description |
|---|---|---|
-o <file> |
stdout | Write output to a file instead of stdout |
-a |
false | Include stopped containers (when no names are given) |
-v |
— | Print version and exit |
Given a running nginx container started with:
docker run -d \ --name web \ -p 8080:80 \ -v /data/html:/usr/share/nginx/html \ -e NGINX_HOST=example.com \ --restart unless-stopped \ --network webnet \ nginx:1.25
Running dexport produces:
services: web: image: nginx:1.25 container_name: web ports: - "8080:80" volumes: - /data/html:/usr/share/nginx/html environment: - NGINX_HOST=example.com networks: webnet: {} restart: unless-stopped networks: webnet: {}
The following container configuration is captured when present:
- Image name and tag
- Ports — published port bindings (host→container)
- Volumes — bind mounts and named volumes
- Environment variables
- Networks — named networks with aliases
- Restart policy —
always,unless-stopped,on-failure[:N] - Labels (Docker Compose internal labels are filtered out)
- Command and entrypoint overrides
- Working directory, user, hostname, domainname
- Healthcheck — test command, interval, timeout, retries
- Resource limits — memory (
mem_limit), CPU (cpus) - Capabilities —
cap_add,cap_drop - Security options, devices, extra hosts, DNS
- Tmpfs mounts, sysctls, ulimits
- Logging driver and options (default
json-fileis omitted) - Init, privileged, read-only rootfs, stdin_open, tty
- Stop signal and stop grace period
Fields that are default or empty are omitted to keep the output clean.
- The
version:field is intentionally omitted. It is deprecated in Compose V2 and causes warnings with moderndocker compose. - Named volumes appear in both the service
volumes:list and a top-levelvolumes:section. If the volume was created externally (e.g. by another Compose project), you may need to addexternal: truemanually. depends_onrelationships cannot be inferred from a running container and must be added manually if needed.- Runtime-only state (container ID, creation time, exit codes) is not included.