Docker Container Updater
7.8K
For all the lazier and automation-loving nerds, constantly updating Docker containers can be a tedious chore. Enter the Docker Container Updater to save the day. It handles updates without relying on the "latest" tag or sticking to the current image tag, which might cause you to miss important updates. Instead, it plays by your rules!
🌱 This project is currently in its early stages, and any feedback on potential issues would be greatly appreciated.
⚠️ The default configuration has test mode enabled. Safety first 😉! After you've run your first test, checked for errors, and reviewed the generated Docker run commands, you can disable test mode in your configuration (see Configuration).
Use the following command to run Docker Container Updater with basic configuration and test mode explicitly enabled:
docker run -d \
--name=Docker-Container-Updater \
--hostname=Docker-Container-Updater \
--restart=always \
--privileged \
--tty \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/etc/localtime,target=/etc/localtime,readonly \
--env DCU_TEST_MODE=true \
--env DCU_CRONTAB_EXECUTION_EXPRESSION='30 2 * * *' \
janjk/docker-container-updater:latest
ℹ️ Explanation
The bind mount of
/var/run/docker.sockis necessary to provide full access to the Docker environment on the host. This socket file enables the container to communicate with your Docker daemon, allowing it to manage Docker containers, images, and other resources. Without this bind mount,Docker Container Updaterwould be isolated from the host's Docker environment and unable to perform tasks like creating, starting, stopping, removing containers, pulling new images etc.
The--privilegedflag is needed to grant the Docker container elevated permissions on the host system. This flag provides the container with extended capabilities, allowing it to perform tasks that require higher levels of access to the host’s resources and hardware. Specifically, it:
- Gives the container access to all resources on the host, similar to the root user.
- Allows the container to modify kernel parameters using sysctl or sysfs.
- Grants the container additional capabilities that are typically restricted for security reasons.
Using the
--privilegedflag is essential for certain operations that involve deep integration with the host system, such as managing network configurations, mounting filesystems, or interacting with hardware devices directly.
Docker Container Updaterrelies on these extended permissions to perform its intended tasks effectively.
To ensure data persistence, you should configure the following mounts:
--mount type=bind,source=<YOUR_LOCAL_PRE_SCRIPTS_PATH>,target=/usr/local/etc/container_update/pre-scripts \
--mount type=bind,source=<YOUR_LOCAL_POST_SCRIPTS_PATH>,target=/usr/local/etc/container_update/post-scripts \
--mount type=bind,source=<YOUR_LOCAL_LOGS_PATH>,target=/var/log \
After successfully starting Docker Container Updater, a cron job inside the container will automatically manage the update mechanism for your Docker containers based on the cron expression defined in DCU_CRONTAB_EXECUTION_EXPRESSION.
To manually execute the update process, run:
docker exec -it Docker-Container-Updater dcu --run
If you have already disabled test mode in your configuration, you can enforce using test mode for this one time execution by running the following command (>= v2024.06.07-1):
docker exec -it Docker-Container-Updater dcu --dry-run
You can fully configure Docker Container Updater by setting environment variables in your docker run command.
| Docker Environment Variable | Description | Default Value | Possible Values |
|---|---|---|---|
| DCU_TEST_MODE | Enables or disables test mode | true | true, false |
| DCU_PRUNE_IMAGES | Automatically prune unused images | true | true, false |
| DCU_PRUNE_CONTAINER_BACKUPS | Automatically prune old container backups | true | true, false |
| DCU_CONTAINER_BACKUPS_RETENTION | Number of days to retain container backups | 7 | Any positive integer |
| DCU_CONTAINER_BACKUPS_KEEP_LAST | Number of last container backups to keep regardless of retention time | 1 | Any positive integer |
| DCU_CONTAINER_UPDATE_VALIDATION_TIME | Time in seconds to validate if a container runs successfully after an update | 120 | Any positive integer |
| DCU_UPDATE_RULES | Rules for updating containers (see detailed explanation below) | *[0.1.1-1,true] | Custom rules (separated by space) |
| DCU_DOCKER_HUB_API_URL | URL for the Docker Hub API | https://registry.hub.docker.com/v2 | Any valid URL |
| DCU_DOCKER_HUB_API_IMAGE_TAGS_PAGE_SIZE_LIMIT | Number of tags to fetch per page from Docker Hub | 100 | Positive integer (1-100) |
| DCU_DOCKER_HUB_API_IMAGE_TAGS_PAGE_CRAWL_LIMIT | Number of pages to crawl for tags from Docker Hub | 10 | Any positive integer |
| DCU_DOCKER_HUB_IMAGE_MINIMUM_AGE | Minimum age in seconds threshold for a newly pulled Docker image | 21600 | Any positive integer |
| DCU_PRE_SCRIPTS_FOLDER | Folder containing pre-update scripts | /usr/local/etc/container_update/pre-scripts | Any valid directory path |
| DCU_POST_SCRIPTS_FOLDER | Folder containing post-update scripts | /usr/local/etc/container_update/post-scripts | Any valid directory path |
| DCU_LOG_FILEPATH | Path to the log file | /var/log/container_update.log | Any valid file path |
| DCU_LOG_LEVEL | Log level | INFO | DEBUG, INFO, WARN, ERROR |
| DCU_LOG_RETENTION | Number of days to retain log file entries | 7 | Any positive integer |
| DCU_MAIL_NOTIFICATIONS_ENABLED | Enable or disable email notifications | false | true, false |
| DCU_MAIL_NOTIFICATION_MODE | Mode of sending emails (currently only sendmail is supported) | sendmail | sendmail |
| DCU_MAIL_FROM | Email address for sending notifications | Any valid email address | |
| DCU_MAIL_RECIPIENTS | Space-separated list of recipient email addresses | Any valid email addresses (separated by space) | |
| DCU_MAIL_SUBJECT | Subject of the notification email | Docker Container Update Report from <hostname> | Any valid string |
| DCU_MAIL_RELAYHOST | The relay host to which the Docker container's Postfix forwards its mails | IP address or hostname and port (e.g.: [10.1.1.30]:25 ) | |
| DCU_TELEGRAM_NOTIFICATIONS_ENABLED | Enable or disable telegram notifications | false | true, false |
| DCU_TELEGRAM_RETRY_LIMIT | Number of retry attempts for sending a message | 2 | Any positive integer |
| DCU_TELEGRAM_RETRY_INTERVAL | Time interval between retry attempts (in seconds) | 10 | Any positive integer |
| DCU_TELEGRAM_CHAT_ID | Unique identifier for the target chat or user | A single valid chat ID | |
| DCU_TELEGRAM_BOT_TOKEN | Access token for the Telegram Bot API | A single valid Telegram Bot token | |
| DCU_CRONTAB_EXECUTION_EXPRESSION | Crontab expression for automating the update process execution. You can utilize this site to generate the expression | Any valid crontab expression | |
| DCU_CONFIG_FILE | Path to the INI configuration file inside the container. Do not persist this! | Any valid file path | |
| DCU_REPORT_REAL_HOSTNAME | Specify the hostname of your Docker host to override it in the reports. Otherwise, you will see the container's hostname instead | Any string | |
| DCU_REPORT_REAL_IP | Specify the IP address of your Docker host to override it in the reports. Otherwise, you will see the container's IP address instead | Any string | |
| DCU_REPORT_REAL_DOCKER_VERSION | Specify the Docker version used by your Docker host to override it in the reports. Otherwise, you will see the container's Docker version instead | Any string |
In order to receive E-Mail notifications you need to have a Mail Transfer Agent (MTA) (e.g., Postfix) installed, configured and reachable in your network, to which the Docker container can relay its emails. The IP address or the hostname of your MTA needs be specified in the environment variable DCU_MAIL_RELAYHOST when running the container.
--env DCU_REPORT_REAL_HOSTNAME="$(hostname)" \
--env DCU_REPORT_REAL_IP="$(hostname -I | awk '{print $1}')" \
--env DCU_REPORT_REAL_DOCKER_VERSION="$(docker --version | awk '{print $3}' | tr -d ',')" \
--env DCU_MAIL_NOTIFICATIONS_ENABLED=true \
--env DCU_MAIL_FROM='<[email protected]>' \
--env DCU_MAIL_RECIPIENTS='<[email protected]>' \
--env DCU_MAIL_SUBJECT="🐳 Docker Container Update Report from $(hostname)" \
--env DCU_MAIL_RELAYHOST='[<IP address or hostname>]:<Port>' \
To receive Telegram notifications, you first need to obtain a Chat ID and a Bot Token.
--env DCU_REPORT_REAL_HOSTNAME="$(hostname)" \
--env DCU_REPORT_REAL_IP="$(hostname -I | awk '{print $1}')" \
--env DCU_REPORT_REAL_DOCKER_VERSION="$(docker --version | awk '{print $3}' | tr -d ',')" \
--env DCU_TELEGRAM_NOTIFICATIONS_ENABLED=true \
--env DCU_TELEGRAM_BOT_TOKEN='<your_bot_token>' \
--env DCU_TELEGRAM_CHAT_ID='<your_chat_id' \
The DCU_UPDATE_RULES environment variable allows you to define the update behavior for your containers. The default rule is *[0.1.1-1,true], which means:
*: Applies to all containers.0.1.1-1: Specifies the update policy, where each number represents:
0: Major updates (0 means no major updates, 1 means allow major updates to the next available, 2 means always stay one version behind the latest major release, and so on)1: Minor updates (0 means no minor updates, 1 means allow minor updates to the next available, 2 means always stay one version behind the latest minor release, and so on)1: Patch updates (0 means no patch updates, 1 means allow patch updates to the next available, 2 means always stay one version behind the latest patch release, and so on)1: Build updates (0 means no build updates, 1 means allow build updates to the next available, 2 means always stay one version behind the latest build release, and so on)true: Indicates that digest updates are allowed.You can customize these rules for each container by specifying different patterns and update policies separated by spaces.
*[0.1.1-1,true] mycontainer[1.0.0-1,true] another[0.0.1-1,false] further[2.1.1-1,true]
This example configuration means:
- All containers are allowed to apply only minor, patch, build, and digest updates.
- The container named
mycontaineris allowed to apply major, build, and digest updates.- The container named
anotheris allowed to apply only patch and build updates.- The container named
furtheris allowed to apply major updates only when the latest release is two versions higher (e.g., if Nextcloud releases version 29.0.0 and your Nextcloud is on version 27.0.0, an update to version 28.0.0 will be performed).
You can also create more specific rule sets that allow, for example, major updates for a container if at least one patch has been released for that major version. In the rules, 'M' stands for Major, 'm' for Minor, 'p' for Patch, and 'b' for Build.
mycontainer[1&(p>1).1.1-1,true]
This rule allows major updates for the container
mycontainerif at least one patch version greater than 1 has been released for this major version.
mycontainer[0.1&(b>2).1-1,true]
This rule allows minor updates for the container
mycontainerif the build version is greater than 2.
These precise rules provide granular control over the update behavior of specific containers based on various conditions such as patch versions, build versions, and more.
ℹ️ These rules do not affect the order in which updates are installed! An update is never skipped.
To give you more control, you can integrate your own pre- and post-scripts. These are created by default in the directories /usr/local/etc/container_update/pre-scripts and /usr/local/etc/container_update/post-scripts within the container, and they must be named after the relevant container. These are standard bash scripts that you can create and customize as needed. For example, you can create backups of databases, configuration files, etc., before updating a container, and make adjustments such as customized branding or changes to file permissions after any update. Essentially, you can tailor these scripts to your specific needs. The output of these scripts is redirected to the log of Docker Container Updater, so you have all logs in one place.
A pre-script is executed as soon as all conditions for an update are met:
The effective rule for the respective container allows an update
The age of the image on Docker Hub meets the configured minimum age in DCU_DOCKER_HUB_IMAGE_MINIMUM_AGE
The new image has been successfully downloaded
Only at this point is the pre-script executed. Once the pre-script has been processed, the procedure continues as follows...
The original container is renamed (to allow for a backup of the container)
The startup policy of the original container is overwritten (to prevent simultaneous startups)
The original container is stopped
The new container with the new image is started
If the new container was successfully started, the post-script is now executed.
ℹ️ A little tip:
To gain full access to the directories of individual Docker containers, you may need to mount additional directories into
Docker Container Updater. There are various approaches to this, which vary depending on the system your architecture/design. Decide for yourself what works best for you.
Usage: dcu [ [--dry-run|--run] [--filter name|id=VALUE] [--force] ] [--help] [--version]
Options:
--dry-run -dr Run DCU in dry-run mode (this temporarily enforces test mode to be enabled)
--force -f Force lock acquisition
--help -? Display this help
--run -r Run DCU (considering the current configuration for test mode)
--version -v Display the current version
--debug Set log level to debug mode
Usage: dcu [--dry-run|--run] [ --filter [options|--help] ]
Options:
--filter Filter processed containers by the following conditions:
name=My_Container_Name
id=My_Container_ID
Content type
Image
Digest
sha256:3ea2e3320…
Size
93.1 MB
Last updated
over 1 year ago
docker pull janjk/docker-container-updater