Maintaining up-to-date Docker containers is critical for security and functionality, but manually updating containers across all your deployments can be tedious and error-prone. This is where Watchtower comes in – a powerful tool that automates the process of keeping your Docker containers fresh and updated.
„I am actively using it locally and externally on my servers.„
What is Watchtower?
Watchtower is an open-source container-based solution that automates Docker container base image updates. Once deployed, Watchtower monitors your running containers and automatically updates them whenever a new image is available in the Docker Hub or your own private registry.
The beauty of Watchtower is its simplicity – it pulls the new image, gracefully shuts down the existing container, and restarts it with the same options that were used when it was initially deployed. This means you don’t need to write complex update scripts or manually apply updates across your infrastructure.
Key Benefits of Using Watchtower
- Automated Updates: Set it and forget it – Watchtower handles updates without manual intervention
- Improved Security: Ensure your containers always run the latest secure base images
- Reduced Maintenance Overhead: No need to manually track and apply updates
- Flexible Configuration: Monitor all containers or just the ones you specify
- Notification Options: Get alerts when updates occur via various notification services
- Resource Efficient: Lightweight container with minimal resource requirements
Installing Watchtower with Docker
Since Watchtower itself is packaged as a Docker container, installation is as simple as pulling and running the containrrr/watchtower image.
Basic Installation
The simplest way to get started with Watchtower is by running:
1 2 3 4 5 6 7 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower |
This command:
- Runs Watchtower as a daemon (
-d
) - Names the container „watchtower“ (
--name watchtower
) - Mounts the Docker socket to allow Watchtower to interact with the Docker API (
-v /var/run/docker.sock:/var/run/docker.sock
) - Uses the official Watchtower image (
containrrr/watchtower
)
With this basic setup, Watchtower will check for updates to all running containers once every 24 hours.
Using Docker Compose
For those using Docker Compose, you can add Watchtower to your docker-compose.yml
file:
1 2 3 4 5 6 7 8 9 10 |
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock restart: unless-stopped |
Then start it with:
1 2 3 4 |
docker-compose up -d |
Advanced Configuration Options
Watchtower is highly configurable through command-line arguments or environment variables. Here are some useful options to customize your deployment:
Monitoring Specific Containers
By default, Watchtower monitors all running containers. To monitor only specific containers, specify their names as arguments:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ nginx redis |
This will only update containers named „nginx“ and „redis“.
Changing Update Frequency
The default 24-hour check interval might not suit all needs. You can adjust this with the --interval
flag:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --interval 30 |
This sets Watchtower to check for updates every 30 seconds.
In Docker Compose, you would add this as a command:
1 2 3 4 5 6 7 8 9 |
services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock command: --interval 3600 # Check every hour |
Cleanup Option
To prevent accumulation of old images after updates, use the --cleanup
flag:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --cleanup |
This will remove the old image after updating a container.
Run Once Mode
If you prefer to manually trigger updates rather than having Watchtower run as a daemon, use the --run-once
flag:
1 2 3 4 5 6 7 |
docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --run-once |
The --rm
flag removes the container after it completes its execution.
Schedule Updates with Cron
Instead of using a fixed interval, you can schedule updates using cron expressions:
1 2 3 4 5 6 7 8 9 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e TZ=America/New_York \ containrrr/watchtower \ --schedule "0 0 2 * * *" |
This schedules updates to occur at 2:00 AM every day. The TZ
environment variable ensures the schedule uses your local timezone.
Setting Up Notifications
Watchtower can notify you when containers are updated, which is especially useful in production environments.
Using Shoutrrr for Notifications
Watchtower integrates with Shoutrrr to send notifications via various services like Slack, Discord, Email, and more:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATION_URL="discord://token@channel slack://watchtower@token-a/token-b/token-c" \ containrrr/watchtower |
Email Notifications Example
To receive email notifications:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATION_URL="smtp://username:password@smtp.gmail.com:587/?fromAddress=from@example.com&toAddresses=to@example.com" \ containrrr/watchtower |
Slack Notifications Example
For Slack notifications:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATION_URL="slack://watchtower@token-a/token-b/token-c" \ containrrr/watchtower |
Working with Private Registries
If you’re pulling images from private Docker registries, you’ll need to provide authentication credentials:
Using Environment Variables
1 2 3 4 5 6 7 8 9 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e REPO_USER=username \ -e REPO_PASS=password \ containrrr/watchtower |
Using Docker Config File
For systems using 2FA or more complex authentication:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v $HOME/.docker/config.json:/config.json \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower |
Complete Docker Compose Example
Here’s a more complete example using Docker Compose with various configuration options:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
version: "3" services: watchtower: image: containrrr/watchtower container_name: watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - $HOME/.docker/config.json:/config.json # For private registry auth environment: - TZ=Europe/London - WATCHTOWER_CLEANUP=true - WATCHTOWER_REMOVE_VOLUMES=false - WATCHTOWER_INCLUDE_STOPPED=true - WATCHTOWER_REVIVE_STOPPED=true - WATCHTOWER_POLL_INTERVAL=86400 # 24 hours in seconds - WATCHTOWER_NOTIFICATION_URL=slack://watchtower@token-a/token-b/token-c - WATCHTOWER_DEBUG=false restart: unless-stopped labels: - "com.centurylinklabs.watchtower.enable=true" |
Advanced Features
Label-Based Control
Watchtower supports controlling updates through Docker labels:
- Enable updates for specific containers using the
com.centurylinklabs.watchtower.enable
label:
1 2 3 4 5 6 7 8 |
services: my-service: image: my-image labels: - "com.centurylinklabs.watchtower.enable=true" |
- Disable pulling new images for specific containers:
1 2 3 4 5 6 7 8 |
services: my-local-build: image: my-local-image labels: - "com.centurylinklabs.watchtower.no-pull=true" |
Monitor-Only Mode
To monitor for updates without actually performing them:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --monitor-only |
This is useful for testing or when you want to receive notifications about available updates without automatically applying them.
Troubleshooting
Debugging Issues
If you’re experiencing problems with Watchtower, enable debug or trace mode:
1 2 3 4 5 6 7 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --debug |
For more detailed logs, use:
1 2 3 |
docker logs watchtower |
Common Problems
- No updates happening: Check if your containers have the enable label set correctly if you’re using label filtering.
- Authentication failures: Ensure your credentials for private registries are correct and properly mounted.
- Timezone issues with scheduled updates: Make sure you’ve set the
TZ
environment variable correctly.
Security Considerations
- Watchtower needs access to the Docker socket, which essentially gives it root access to your host. Ensure it’s protected and only used in trusted environments.
- Consider running Watchtower with minimal privileges and only monitor the containers that need updating.
- Use the
--stop-timeout
parameter to ensure proper shutdown of your containers.
Thoughts
Watchtower simplifies Docker container maintenance by automating the update process. With its flexible configuration options, you can tailor the automation to your specific needs, whether you’re running a small personal server or managing a large production environment.
By implementing Watchtower in your Docker environment, you’ll save time on manual updates while ensuring your containers remain current with the latest features and security patches.
Common Questions
What is Watchtower and what does it do?
Watchtower is an open-source container-based solution that automates Docker container updates. It monitors your running containers and automatically updates them whenever new images are pushed to Docker Hub or your private registry. Watchtower pulls the new image, gracefully shuts down the existing container, and restarts it with the same options that were used during its initial deployment.
How do I install Watchtower?
Since Watchtower is a Docker container itself, installation is simple. Run the following command:
1 2 3 4 5 6 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower |
Or with Docker Compose, add to your docker-compose.yml:
1 2 3 4 5 6 7 8 9 |
version: "3" services: watchtower: image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock restart: unless-stopped |
How does Watchtower access other containers to update them?
Watchtower accesses other containers through the Docker socket, which is mounted as a volume when you run Watchtower (-v /var/run/docker.sock:/var/run/docker.sock
). This gives Watchtower access to the Docker API, allowing it to monitor and manage other containers running on the same Docker daemon. This is why Watchtower requires this volume mount to function properly.
Are there any security concerns with using Watchtower?
Yes, there are security considerations. Mounting the Docker socket gives Watchtower essentially root access to your host system through the Docker API. This is necessary for its functionality but creates a potential security risk. To mitigate this:
- Only use Watchtower in trusted environments
- Keep Watchtower itself updated
- Consider using Docker’s security features like user namespaces
- Monitor Watchtower’s activities through logs
How often does Watchtower check for updates?
By default, Watchtower checks for updates every 24 hours (86400 seconds). You can change this interval using the --interval
flag or WATCHTOWER_POLL_INTERVAL
environment variable. For example, to check every hour:
1 2 3 4 5 6 7 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --interval 3600 |
Alternatively, you can use a cron schedule with the --schedule
flag to run checks at specific times.
How can I exclude specific containers from being updated?
There are several ways to exclude containers from Watchtower updates:
- Using the label approach: Add
com.centurylinklabs.watchtower.enable=false
label to the containers you want to exclude - Using the
--disable-containers
flag: List containers you want to exclude by name - Using the inclusion approach: Specify only the containers to update as arguments to Watchtower
Example using labels in docker-compose.yml:
1 2 3 4 5 6 7 |
services: my-service: image: my-image labels: - "com.centurylinklabs.watchtower.enable=false" |
Does Watchtower remove old images after updating?
By default, Watchtower does not remove old images after updating containers. This can lead to disk space issues over time as old images accumulate. To enable cleanup of old images, use the --cleanup
flag or set the WATCHTOWER_CLEANUP
environment variable to true:
1 2 3 4 5 6 7 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_CLEANUP=true \ containrrr/watchtower |
How can I set up notifications for Watchtower updates?
Watchtower integrates with various notification services through Shoutrrr. You can configure notifications via environment variables or command line arguments. Here are examples for popular services:
Slack:
1 2 3 |
-e WATCHTOWER_NOTIFICATION_URL="slack://watchtower@token-a/token-b/token-c" |
Discord:
1 2 3 |
-e WATCHTOWER_NOTIFICATION_URL="discord://token@channel" |
Email:
1 2 3 |
-e WATCHTOWER_NOTIFICATION_URL="smtp://username:password@smtp.example.com:587/?fromAddress=from@example.com&toAddresses=to@example.com" |
You can customize notification content with the WATCHTOWER_NOTIFICATION_TEMPLATE
environment variable.
How do I update containers from private registries?
To update containers from private registries, you need to provide authentication credentials to Watchtower. You can do this in two ways:
1. Using environment variables:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e REPO_USER=username \ -e REPO_PASS=password \ containrrr/watchtower |
2. By mounting your Docker config file (required for 2FA):
1 2 3 4 5 6 7 |
docker run -d \ --name watchtower \ -v $HOME/.docker/config.json:/config.json \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower |
Can Watchtower monitor containers without updating them?
Yes, Watchtower has a „monitor-only“ mode that checks for updates but doesn’t automatically apply them. This is useful for receiving notifications about available updates without automatic deployment. Enable it with the --monitor-only
flag or WATCHTOWER_MONITOR_ONLY=true
environment variable:
1 2 3 4 5 6 7 8 |
docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_MONITOR_ONLY=true \ -e WATCHTOWER_NOTIFICATION_URL="slack://watchtower@token-a/token-b/token-c" \ containrrr/watchtower |
You can also set this mode on a per-container basis using the com.centurylinklabs.watchtower.monitor-only=true
label.
What happens if a container update fails?
When a container update fails, Watchtower’s behavior depends on the nature of the failure:
- If the new image cannot be pulled or the container fails to start with the new image, Watchtower will log the error
- By default, Watchtower does not roll back to the previous version of the container
- If enabled, Watchtower will send notifications about the failure
For critical services, it’s recommended to implement health checks and monitoring outside of Watchtower to detect and respond to update failures.
Can Watchtower update itself?
Yes, Watchtower can update itself! Since Watchtower is just another Docker container, it will check for updates to its own image and restart itself when a new version is available. This self-updating behavior works out of the box without any special configuration.
Why isn’t Watchtower updating my containers?
Common reasons why Watchtower might not be updating containers:
- No new images available: Watchtower only updates when a newer image is available
- Authentication issues: Check credentials for private registries
- Container excluded: The container might be excluded via labels or command-line arguments
- Network issues: DNS or connectivity problems to Docker Hub or your registry
- Tag issues: Using „latest“ tag but no actual changes to the image
- Image building approach: Some images fetch updates during startup and don’t change their actual image
Enable debug mode (--debug
flag) to see more detailed logs that might help identify the issue.
Is using the „latest“ tag recommended with Watchtower?
Using the „latest“ tag with Watchtower can be problematic because:
- The „latest“ tag might be overwritten with the same digest, so Watchtower won’t detect changes
- It makes it harder to roll back to specific versions
- Different behavior might be introduced without version tracking
For production environments, it’s generally better to use specific version tags and update them deliberately. For test environments or non-critical services, using „latest“ with Watchtower can be convenient for getting the newest features automatically.
How can I run Watchtower just once manually?
To run Watchtower just once for a manual update check, use the --run-once
flag:
1 2 3 4 5 6 |
docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ containrrr/watchtower \ --run-once |
The --rm
flag automatically removes the Watchtower container after it completes its execution. You can also specify container names after the --run-once
flag to check only specific containers.
Additional Resources
- Official Watchtower Documentation
- Watchtower GitHub Repository
- Shoutrrr Documentation (for notification settings)
Get started with Watchtower today and enjoy the benefits of automated Docker container updates!