-
-
Notifications
You must be signed in to change notification settings - Fork 35
Pre Post Deployment Scripts
In this documentation, we will cover how to run scripts or commands during the deployment and container lifecycle of your Docker Compose services.
For security reasons doco-cd itself does not provide a shell environment for executing scripts. Instead, it relies on the underlying container runtime (e.g., Docker) to execute these scripts within the context of the deployed containers/compose services.
Available options to run scripts/commands during deployment or container lifecycle include:
Init containers are containers that run before the main application containers in your Docker Compose setup and complete their tasks before the main containers start. They are useful for performing setup tasks, such as initializing databases, running migrations, or preparing configuration files.
Some common use cases for init containers include:
- Database migrations: Running database migration scripts before the main application starts.
- Running shell scripts to generate configuration files or perform setup tasks.
- Preloading data into databases or caches.
x-common-env: &common-env
MYVAR: world # We will use this variable in both init and app containers
services:
init:
image: busybox
environment:
<<: *common-env
entrypoint: "sh -c" # Use sh -c as the entrypoint to run multiple commands in "command" section
volumes:
- ./web:/web
working_dir: /web
command:
- |
echo Starting pre-deployment script
echo "Hello $${MYVAR}!" > /web/index.html # Double dollar-sign is required here to use the variable in the shell script
echo Finished pre-deployment script
exit 0 # Exit with code 0 to indicate success, not required if the last command already returns 0 but added here for clarity
app:
image: nginx
environment:
<<: *common-env
volumes:
- ./web:/usr/share/nginx/html:ro
ports:
- 8080:80
depends_on:
init:
condition: service_completed_successfully # Wait for init container to complete/stop with exit code 0- If you have a shell script in your repo for the init stuff, you can remove
entrypointand mount the script directly and run it via thecommandoption:volumes: - ./init/:/init command: /init/initproject.sh
- If you need commands from the app container, try to use the same image as your app container. Many app images also come with a shell (sh, ash, bash)
Sidecar containers are additional containers that run alongside your main application containers. They can be used to provide auxiliary services, such as background tasks, metrics collection, or log forwarding.
Some common use cases for sidecar containers include:
- Background tasks, e.g. cron jobs or scheduled tasks
- Metrics collection for monitoring tools like Prometheus
- Log forwarding to external systems
volumes:
webdata:
services:
app:
image: nginx
ports:
- 8080:80
volumes:
- webdata:/usr/share/nginx/html:ro
sidecar:
image: busybox
volumes:
- webdata:/webdata
depends_on:
- app
entrypoint: "sh -c"
command:
- |
while true; do
echo "Updating web content..."
echo "The current time is $(date)" > /webdata/index.html
sleep 60
doneNote
Requires Docker Compose 2.30.0 or later
Docker Compose lifecycle hooks allow you to run commands/scripts at specific points in the container lifecycle, such as after starting (post_start) or before stopping pre_stop a container.
This example demonstrates how to use the post_start hook to set up the correct volume permissions that the application needs.
How It Works:
- Volume Initialization: Docker creates the data volume with root ownership
- Container Starts: The container runs with user: 1001
-
Permission Setup: Two post-start hooks execute sequentially:
- First hook changes ownership to user 1001
- Second hook sets appropriate read/write permissions
- Application Runs: The application can now access the volume with proper permissions
services:
app:
image: backend
user: "1001"
volumes:
- data:/data
post_start:
- command: ["chown", "-R", "1001:1001", "/data"]
user: root
- command: ["chmod", "-R", "755", "/data"]
user: root
volumes:
data:
driver: localThis example demonstrates how to use the pre_stop hook to run cleanup tasks before the container stops.
How It Works:
- Shutdown Initiated: Container receives shutdown signal (e.g., docker compose down)
-
Pre-Stop Sequence: Hooks execute in order:
- Flush application cache
- Backup important data
- Notify monitoring system
- Container Stops: After hooks complete, container proceeds with shutdown or restart
services:
app:
image: backend
pre_stop:
- command: ["./scripts/flush_cache.sh"]
- command: ["./scripts/backup_data.sh"]
- command: ["curl", "-X", "POST", "http://monitoring.example.com/notify_shutdown"]