Give your containers time to clean up. Configure grace periods to ensure database connections close, transactions complete, and data saves properly.
The problem
By default, Docker gives containers 10 seconds to stop before forcefully killing them:
services:
app:
image: myapp:latest
# Container gets SIGTERM, then SIGKILL after 10s
This can interrupt long-running operations and corrupt data.
The solution
Use stop_grace_period to extend shutdown time:
services:
worker:
image: myworker:latest
stop_grace_period: 2m # 2 minutes to finish current job
stop_signal: SIGTERM # Signal to send first (default)
Real-world examples
Different services need different grace periods:
services:
# Web server - quick shutdown
nginx:
image: nginx
stop_grace_period: 30s
# API - finish active requests
api:
image: api:latest
stop_grace_period: 45s
environment:
SHUTDOWN_TIMEOUT: 40 # App-level timeout
# Background worker - complete current job
worker:
image: worker:latest
stop_grace_period: 5m
environment:
WORKER_SHUTDOWN_TIMEOUT: 290 # Slightly less than grace period
# Database - flush and close properly
postgres:
image: postgres:15
stop_grace_period: 2m
command: postgres -c max_wal_size=2GB
Handle signals properly
Your application must respond to SIGTERM:
// Node.js example
process.on('SIGTERM', async () => {
console.log('SIGTERM received, shutting down gracefully...');
server.close(() => {
console.log('HTTP server closed');
});
// Close database connections
await db.close();
// Finish current jobs
await jobQueue.shutdown();
process.exit(0);
});
Test graceful shutdown
Verify your grace period works:
# Start services
docker compose up -d
# Trigger long operation in container
docker compose exec worker trigger-long-job
# Stop with timing
time docker compose stop worker
# Should take close to your grace period
# real 2m3.456s
Compose commands respect grace period
All these commands honor stop_grace_period:
docker compose stop
docker compose down
docker compose restart
docker compose rm -s # Stop first
Common patterns
Quick web services:
stop_grace_period: 30s # Finish HTTP requests
Job processors:
stop_grace_period: 5m # Complete current job
Databases:
stop_grace_period: 2m # Flush buffers, close connections
Message consumers:
stop_grace_period: 1m # Process remaining messages
Pro tip
For critical data operations, combine grace period with health checks:
services:
processor:
image: processor:latest
stop_grace_period: 5m
healthcheck:
test: ["CMD", "pgrep", "-x", "processor"]
interval: 30s
retries: 10 # Keep checking during shutdown
This ensures the container stays healthy during graceful shutdown.