This docker build file is created in order to build monit.
Download the file Dockerfile
to an empty directory and issue:
docker build -t TAG .
where:
TAG
represents a tag to set on the built image (ie: redis:latest
)
After caddy is built, a container can be created and ran either via docker run
or deployed within the swarm with docker stack deploy
.
Note that if the image is to be deployed to a swarm, then more than likely the image should be committed to a local registry serving the local docker swarm.
One of the problem with daemons like Monit is that daemons typically do not reload their configuration file, nor any subsequent "additional files" such that any change to the configuration must be succeeded by a manual reload or signalling of the process.
In cases similar to Docker where there is no direct access to the system, the reload is difficult to perform due to no direct access to the machine. By contrast, changing a configuration is fairly robust, even remotely and is covered by the many remote filesystems available. For this reasons, daemons created by us such as Corrade are built to monitor their own configuration and reload it when changes are perceived, even if that breaks imperative programming tradition in favor of functional, or rather, event-driven programming.
To counter the shortage of this feature, one cool way is to leverage filesystem notifications, for example inotify
, particularly via tools such as inotifywait
and to then (preferrably) schedule an interruptible execution of a daemon reload similar to the alarm(2)
function in systems programming. In what regards Docker, a second program is added, conveniently a simple bash script, that runs continuously and waits for the mapped folder containing the configuration to issue a MODIFY
event. When the MODIFY
event is raised, a configuration reload is scheduled (in this case, via monit reload
, others could consist in delivering a HUP signal) into the future. Whilst the user keeps changing the configuration, any followup MODIFY
events raised by the filesystem increase the wait duration (reset the alarm) by cancelling the previous timer and re-installing it. Once the user stops tampering with the configuration, and when the alarm elapses, the configuration is reloaded.
The script relevant to this scheme is mentioned in the Source section and its applicability extends far beyond this Docker build of the Monit daemon to any daemon that is not able to automatically sense a configuration change and reload its own configuration.
Here are the various components found in the Subversion repository at:
include /conf/*
[supervisord] user=root nodaemon=true [program:monit] command=/usr/local/bin/monit -v -I -l /dev/stdout -c /etc/monitrc autorestart=true stdout_logfile=/dev/stdout stderr_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile_maxbytes=0 [program:monit_config] command=/bin/bash /usr/local/bin/monit-watch-services autorestart=true stdout_logfile=/dev/stdout stderr_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile_maxbytes=0
FROM debian:bookworm-slim # add filesystem requirements ADD rootfs / # update package manager RUN apt-get update -y && \ apt-get upgrade -y && \ apt-get dist-upgrade -y && \ apt-get -y autoremove && \ apt-get clean # install preliminary packages RUN apt-get install -y \ coreutils \ bash \ curl \ ca-certificates \ build-essential \ distcc \ autoconf \ automake \ libtool \ zlib1g \ zlib1g-dev \ libssl3 \ libssl-dev \ supervisor \ inotify-tools # compile WORKDIR /tmp RUN mkdir -p /tmp/build && \ curl -o /tmp/build/source.tar.gz "https://mmonit.com/monit/dist/monit-latest.tar.gz" && \ cd /tmp/build && \ tar --strip=1 -xf source.tar.gz && \ export DISTCC_HOSTS="docker1.internal:35001 docker2.internal:35002 docker3.internal:35003" CC="distcc" CXX="distcc g++" && \ ./configure --without-pam && \ make -j4 && \ make install && \ rm -rf /tmp/build # remove packages that will not be used RUN apt-get purge -y \ curl \ git \ build-essential \ autoconf \ automake \ libtool \ pkgconf && \ apt-get autoremove -y EXPOSE 2812 WORKDIR / ENTRYPOINT [ "supervisord", "-t", "-n", "-c", "/etc/supervisor.conf" ]
#!/usr/bin/env bash ########################################################################### ## Copyright (C) Wizardry and Steamworks 2024 - License: MIT ## ########################################################################### # The following script will reload monit upon configuration changes and # # the script is meant to be ran as a standalone long-runnng process. # # Note that the script uses "inotifywait" and leverages filesystem file # # notifiacations for a lower CPU usage and only asynchronously reloads # # the configuration when changes have been made (ie: instead of polling). # ########################################################################### # alarm(2) function alarm { sleep $1 monit reload } ALARM_PID=0 trap '{ test $ALARM_PID = 0 || kill -9 $ALARM_PID; }' KILL QUIT TERM EXIT INT HUP MONIT_DIRECTORY=/conf inotifywait -q -m "$MONIT_DIRECTORY" -r \ -e "modify" -e "create" -e "delete" | \ while IFS=$'\n' read -r LINE; do if [ -d /proc/"$ALARM_PID" ]; then kill -9 $ALARM_PID fi alarm "5" & ALARM_PID=$! done