When using docker-compose run
for one-off tasks (like database migrations or batch jobs), leftover containers accumulate unless manually removed. While the CLI's --rm
flag solves this, embedding this behavior directly in docker-compose.yml
maintains consistency across teams and CI/CD pipelines.
As of Docker Compose v2.3+ (Compose Specification), you can define this at the service level:
services:
migrations:
image: postgres:alpine
profiles: ["tools"]
labels:
com.docker.compose.autoremove: "true" # Key configuration
command: ["sh", "-c", "psql -U $$DB_USER -d $$DB_NAME -f /migrations/*.sql"]
For older versions or more control, combine healthchecks with depends_on
:
services:
batch-job:
image: python:3.9
healthcheck:
test: ["CMD", "test", "-f", "/tmp/.finished"]
interval: 5s
retries: 1
labels:
on-success: "remove"
command: ["python", "process_data.py"]
For a Node.js test runner that should self-destruct:
version: '3.8'
services:
tester:
build: .
autoremove: true # Works in some community plugins
environment:
- NODE_ENV=test
volumes:
- ./tests:/app/tests
command: ["npm", "test"]
- The
com.docker.compose.autoremove
label requires Docker Engine 20.10+ - For production containers, consider
restart: on-failure
instead - Always test in your specific environment - some Docker versions implement this differently
When using docker-compose run
for temporary service operations, manually adding the --rm
flag every time becomes tedious. Developers need a way to enforce this behavior directly in the Compose file.
As of Docker Compose v2.x, there's no native auto_remove
or rm
option that can be specified under a service in docker-compose.yml
. This differs from the docker run --rm
functionality available in plain Docker.
# What we WANT (but doesn't work):
services:
my_service:
image: alpine
rm: true # Invalid Compose syntax
Option 1: Using Compose Overrides
Create a separate override file that modifies the runtime configuration:
# docker-compose.override.yml
services:
my_service:
command: sh -c "your_command && exit"
restart: "no"
This won't automatically remove containers but prevents them from restarting.
Option 2: Custom Entrypoint Script
Create an entrypoint that ensures container termination:
# Dockerfile
FROM alpine
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
#!/bin/sh
# entrypoint.sh
trap "exit 0" SIGTERM
"$@"
Option 3: Using Healthchecks
Configure a healthcheck that forces container exit:
services:
my_service:
image: alpine
healthcheck:
test: ["CMD", "exit", "0"]
interval: 1s
retries: 1
restart: "no"
For development environments, consider using project-level defaults in ~/.docker/config.json
:
{
"compose": {
"run": {
"auto-remove": true
}
}
}
Combine this with shell aliases for maximum efficiency:
alias dcrun='docker compose run --rm'
The Docker community has discussed adding native support for this feature. Track GitHub issue #6476 for updates. Meanwhile, the workarounds above provide functional alternatives.