├── .github └── dependabot.yml ├── .gitignore ├── Dockerfile ├── README.md ├── docker-compose.yaml ├── docker-entrypoint.sh ├── monitrc ├── pushover ├── samples ├── README.md └── monitrc └── slack /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: docker 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "10:00" 8 | open-pull-requests-limit: 99 9 | reviewers: 10 | - diogopms 11 | ignore: 12 | - dependency-name: alpine 13 | versions: 14 | - 3.13.3 15 | - 3.13.4 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | credentials.json 2 | create_docker_image.sh 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20.2 2 | 3 | LABEL maintainer="Diogo Serrano " 4 | 5 | # monit environment variables 6 | ENV MONIT_VERSION=5.26.0 \ 7 | MONIT_HOME=/opt/monit \ 8 | MONIT_URL=https://mmonit.com/monit/dist \ 9 | PATH=$PATH:/opt/monit/bin 10 | 11 | COPY slack /bin/slack 12 | COPY pushover /bin/pushover 13 | 14 | # Compile and install monit 15 | RUN \ 16 | apk add --update gcc musl-dev make bash python3 curl libressl-dev file zlib-dev && \ 17 | mkdir -p /opt/src; cd /opt/src && \ 18 | wget -qO- ${MONIT_URL}/monit-${MONIT_VERSION}.tar.gz | tar xz && \ 19 | cd /opt/src/monit-${MONIT_VERSION} && \ 20 | ./configure --prefix=${MONIT_HOME} --without-pam && \ 21 | make && make install && \ 22 | apk del gcc musl-dev make file zlib-dev && \ 23 | rm -rf /var/cache/apk/* /opt/src 24 | 25 | EXPOSE 2812 26 | 27 | COPY docker-entrypoint.sh /usr/local/bin/ 28 | RUN ln -s /usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat 29 | ENTRYPOINT ["/entrypoint.sh"] 30 | 31 | CMD ["monit", "-I", "-B", "-c", "/etc/monitrc_root"] 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Monit - Docker/Kubernetes - UNIX Systems Management 2 | 3 | Run Monit inside docker ( ) 4 | 5 | [![Monit](https://mmonit.com/monit/img/logo.png)](https://mmonit.com/monit/) 6 | 7 | [Monit](https://mmonit.com/monit/) is a free open source utility for managing and monitoring, processes, programs, files, directories and filesystems on a UNIX system. Monit conducts automatic maintenance and repair and can execute meaningful causal actions in error situations. 8 | 9 | ## Supported architectures 10 | 11 | - amd64 12 | - arm32v6 (Raspberry Pi) [diogopms/monit-docker-kubernetes:arm32v6-latest](https://hub.docker.com/r/diogopms/monit-docker-kubernetes/tags?page=1&name=arm) 13 | 14 | ## Docker setup 15 | 16 | Install docker: https://docs.docker.com/engine/installation/ 17 | Install docker compose: https://docs.docker.com/compose/install/ 18 | Docker documentation: https://docs.docker.com/ 19 | 20 | ### Build-in docker image 21 | 22 | - build docker image `docker build -t monit .` 23 | - start monit: `docker run -ti -p 2812:2812 -v $(pwd)/monitrc:/etc/monitrc monit` 24 | 25 | ## ENV VARS 26 | 27 | | ENVs | Description | 28 | |----------------- |---------------------------------------------------------- | 29 | | SLACK_URL | Webhook url for slack notifications (required for slack) | 30 | | PUSH_OVER_TOKEN | Push over api token (required for pushover) | 31 | | PUSH_OVER_USER | Push over api user (requiredfor pushover) | 32 | | DEBUG | If set with 1 it will put monit in verbose mode | 33 | 34 | ### Docker Hub image 35 | 36 | - pull docker image from docker hub: `docker pull diogopms/monit-docker-kubernetes` 37 | - start monit: `docker run -ti -p 2812:2812 -v $(pwd)/monitrc:/etc/monitrc diogopms/monit-docker-kubernetes` 38 | - create a docker container: 39 | 40 | ``` 41 | #Normal mode (support slack and pushover) 42 | docker run -it \ 43 | -p 2812:2812 \ 44 | -v $(pwd)/monitrc:/etc/monitrc \ 45 | -e "SLACK_URL=" \ 46 | -e "PUSH_OVER_TOKEN=" \ 47 | -e "PUSH_OVER_USER=" \ 48 | diogopms/monit-docker-kubernetes 49 | 50 | #Debug mode 51 | docker run -it \ 52 | -p 2812:2812 \ 53 | -v $(pwd)/monitrc:/etc/monitrc \ 54 | -e "SLACK_URL=" \ 55 | -e "PUSH_OVER_TOKEN=" \ 56 | -e "PUSH_OVER_USER=" \ 57 | -e "DEBUG=1" \ 58 | diogopms/monit-docker-kubernetes 59 | ``` 60 | 61 | ### Example monitrc (Slack) 62 | 63 | ``` 64 | set daemon 20 65 | set log syslog 66 | # Web interface 67 | # set httpd port 2812 and allow admin:monit 68 | 69 | check host www.google.com with address www.google.com 70 | if failed 71 | port 443 protocol https 72 | request / 73 | status = 200 74 | for 2 cycles 75 | then exec "/bin/slack" 76 | else if succeeded then exec "/bin/slack" 77 | EOF 78 | ``` 79 | 80 | ### Example monitrc (Pushover) 81 | 82 | ``` 83 | set daemon 20 84 | set log syslog 85 | # Web interface 86 | # set httpd port 2812 and allow admin:monit 87 | 88 | check host www.google.com with address www.google.com 89 | if failed 90 | port 443 protocol https 91 | request / 92 | status = 200 93 | for 2 cycles 94 | then exec "/bin/pushover" 95 | else if succeeded then exec "/bin/pushover" 96 | EOF 97 | ``` 98 | 99 | ### Supported notifications 100 | 101 | - [Slack](https://www.slack.com) 102 | - [Pushover](https://pushover.net) 103 | 104 | ### Kubernetes 105 | 106 | ### Troubleshooting 107 | 108 | If when starting Monit returns the following message: `The control file '/etc/monitrc' permission 0755 is wrong, maximum 0700 allowed`, simply give the appropriate permissions to _monitrc_: `chmod 700 monitrc`. 109 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3.8" 3 | services: 4 | monit: 5 | image: diogopms/monit-docker-kubernetes:latest 6 | container_name: monit 7 | environment: 8 | - PUID=1000 9 | - PGID=1000 10 | - TZ=Europe/Lisbon 11 | volumes: 12 | - ./monitrc:/etc/monitrc 13 | ports: 14 | - 2812:2812 15 | restart: unless-stopped 16 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Setting up monitrc" 4 | chmod 700 /etc/monitrc 5 | cp /etc/monitrc /etc/monitrc_root 6 | chown root:root /etc/monitrc_root 7 | 8 | echo "Removing prior PID file" 9 | rm -f /var/run/monit.pid 10 | 11 | if [ "$DEBUG" = "1" ] 12 | then 13 | exec monit -I -B -v -c /etc/monitrc_root 14 | else 15 | 16 | exec "$@" 17 | fi 18 | -------------------------------------------------------------------------------- /monitrc: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## Monit control file 3 | ############################################################################### 4 | ## 5 | ## Comments begin with a '#' and extend through the end of the line. Keywords 6 | ## are case insensitive. All path's MUST BE FULLY QUALIFIED, starting with '/'. 7 | ## 8 | ## Below you will find examples of some frequently used statements. For 9 | ## information about the control file and a complete list of statements and 10 | ## options, please have a look in the Monit manual. 11 | ## 12 | ## 13 | ############################################################################### 14 | ## Global section 15 | ############################################################################### 16 | ## 17 | ## Start Monit in the background (run as a daemon): 18 | # 19 | set daemon 30 # check services at 30 seconds intervals 20 | # with start delay 240 # optional: delay the first check by 4-minutes (by 21 | # # default Monit check immediately after Monit start) 22 | # 23 | # 24 | ## Set syslog logging. If you want to log to a standalone log file instead, 25 | ## specify the full path to the log file 26 | # 27 | set log syslog 28 | 29 | # 30 | # 31 | ## Set the location of the Monit lock file which stores the process id of the 32 | ## running Monit instance. By default this file is stored in $HOME/.monit.pid 33 | # 34 | # set pidfile /var/run/monit.pid 35 | # 36 | ## Set the location of the Monit id file which stores the unique id for the 37 | ## Monit instance. The id is generated and stored on first Monit start. By 38 | ## default the file is placed in $HOME/.monit.id. 39 | # 40 | # set idfile /var/.monit.id 41 | # 42 | ## Set the location of the Monit state file which saves monitoring states 43 | ## on each cycle. By default the file is placed in $HOME/.monit.state. If 44 | ## the state file is stored on a persistent filesystem, Monit will recover 45 | ## the monitoring state across reboots. If it is on temporary filesystem, the 46 | ## state will be lost on reboot which may be convenient in some situations. 47 | # 48 | # set statefile /var/.monit.state 49 | # 50 | # 51 | 52 | ## Set limits for various tests. The following example shows the default values: 53 | ## 54 | # set limits { 55 | # programOutput: 512 B, # check program's output truncate limit 56 | # sendExpectBuffer: 256 B, # limit for send/expect protocol test 57 | # fileContentBuffer: 512 B, # limit for file content test 58 | # httpContentBuffer: 1 MB, # limit for HTTP content test 59 | # networkTimeout: 5 seconds # timeout for network I/O 60 | # programTimeout: 300 seconds # timeout for check program 61 | # stopTimeout: 30 seconds # timeout for service stop 62 | # startTimeout: 30 seconds # timeout for service start 63 | # restartTimeout: 30 seconds # timeout for service restart 64 | # } 65 | 66 | ## Set global SSL options (just most common options showed, see manual for 67 | ## full list). 68 | # 69 | # set ssl { 70 | # verify : enable, # verify SSL certificates (disabled by default but STRONGLY RECOMMENDED) 71 | # selfsigned : allow # allow self signed SSL certificates (reject by default) 72 | # } 73 | # 74 | # 75 | ## Set the list of mail servers for alert delivery. Multiple servers may be 76 | ## specified using a comma separator. If the first mail server fails, Monit 77 | # will use the second mail server in the list and so on. By default Monit uses 78 | # port 25 - it is possible to override this with the PORT option. 79 | # 80 | # set mailserver mail.bar.baz, # primary mailserver 81 | # backup.bar.baz port 10025, # backup mailserver on port 10025 82 | # localhost # fallback relay 83 | # 84 | # 85 | ## By default Monit will drop alert events if no mail servers are available. 86 | ## If you want to keep the alerts for later delivery retry, you can use the 87 | ## EVENTQUEUE statement. The base directory where undelivered alerts will be 88 | ## stored is specified by the BASEDIR option. You can limit the queue size 89 | ## by using the SLOTS option (if omitted, the queue is limited by space 90 | ## available in the back end filesystem). 91 | # 92 | # set eventqueue 93 | # basedir /var/monit # set the base directory where events will be stored 94 | # slots 100 # optionally limit the queue size 95 | # 96 | # 97 | ## Send status and events to M/Monit (for more informations about M/Monit 98 | ## see https://mmonit.com/). By default Monit registers credentials with 99 | ## M/Monit so M/Monit can smoothly communicate back to Monit and you don't 100 | ## have to register Monit credentials manually in M/Monit. It is possible to 101 | ## disable credential registration using the commented out option below. 102 | ## Though, if safety is a concern we recommend instead using https when 103 | ## communicating with M/Monit and send credentials encrypted. The password 104 | ## should be URL encoded if it contains URL-significant characters like 105 | ## ":", "?", "@". Default timeout is 5 seconds, you can customize it by 106 | ## adding the timeout option. 107 | # 108 | # set mmonit http://monit:monit@192.168.1.10:8080/collector 109 | # # with timeout 30 seconds # Default timeout is 5 seconds 110 | # # and register without credentials # Don't register credentials 111 | # 112 | # 113 | ## Monit by default uses the following format for alerts if the mail-format 114 | ## statement is missing:: 115 | ## --8<-- 116 | ## set mail-format { 117 | ## from: Monit 118 | ## subject: monit alert -- $EVENT $SERVICE 119 | ## message: $EVENT Service $SERVICE 120 | ## Date: $DATE 121 | ## Action: $ACTION 122 | ## Host: $HOST 123 | ## Description: $DESCRIPTION 124 | ## 125 | ## Your faithful employee, 126 | ## Monit 127 | ## } 128 | ## --8<-- 129 | ## 130 | ## You can override this message format or parts of it, such as subject 131 | ## or sender using the MAIL-FORMAT statement. Macros such as $DATE, etc. 132 | ## are expanded at runtime. For example, to override the sender, use: 133 | # 134 | # set mail-format { from: monit@foo.bar } 135 | # 136 | # 137 | ## You can set alert recipients whom will receive alerts if/when a 138 | ## service defined in this file has errors. Alerts may be restricted on 139 | ## events by using a filter as in the second example below. 140 | # 141 | # set alert sysadm@foo.bar # receive all alerts 142 | # 143 | ## Do not alert when Monit starts, stops or performs a user initiated action. 144 | ## This filter is recommended to avoid getting alerts for trivial cases. 145 | # 146 | # set alert your-name@your.domain not on { instance, action } 147 | # 148 | # 149 | ## Monit has an embedded HTTP interface which can be used to view status of 150 | ## services monitored and manage services from a web interface. The HTTP 151 | ## interface is also required if you want to issue Monit commands from the 152 | ## command line, such as 'monit status' or 'monit restart service' The reason 153 | ## for this is that the Monit client uses the HTTP interface to send these 154 | ## commands to a running Monit daemon. See the Monit Wiki if you want to 155 | ## enable SSL for the HTTP interface. 156 | # 157 | set httpd port 2812 and 158 | # use address localhost # only accept connection from localhost 159 | # allow localhost # allow localhost to connect to the server and 160 | allow admin:monit # require user 'admin' with password 'monit' 161 | #with ssl { # enable SSL/TLS and set path to server certificate 162 | # pemfile: /etc/ssl/certs/monit.pem 163 | #} 164 | 165 | ############################################################################### 166 | ## Services 167 | ############################################################################### 168 | ## 169 | ## Check general system resources such as load average, cpu and memory 170 | ## usage. Each test specifies a resource, conditions and the action to be 171 | ## performed should a test fail. 172 | # 173 | # check system $HOST 174 | # if loadavg (1min) > 4 then alert 175 | # if loadavg (5min) > 2 then alert 176 | # if cpu usage > 95% for 10 cycles then alert 177 | # if memory usage > 75% then alert 178 | # if swap usage > 25% then alert 179 | # 180 | # 181 | ## Check if a file exists, checksum, permissions, uid and gid. In addition 182 | ## to alert recipients in the global section, customized alert can be sent to 183 | ## additional recipients by specifying a local alert handler. The service may 184 | ## be grouped using the GROUP option. More than one group can be specified by 185 | ## repeating the 'group name' statement. 186 | # 187 | # check file apache_bin with path /usr/local/apache/bin/httpd 188 | # if failed checksum and 189 | # expect the sum 8f7f419955cefa0b33a2ba316cba3659 then unmonitor 190 | # if failed permission 755 then unmonitor 191 | # if failed uid "root" then unmonitor 192 | # if failed gid "root" then unmonitor 193 | # alert security@foo.bar on { 194 | # checksum, permission, uid, gid, unmonitor 195 | # } with the mail-format { subject: Alarm! } 196 | # group server 197 | # 198 | # 199 | ## Check that a process is running, in this case Apache, and that it respond 200 | ## to HTTP and HTTPS requests. Check its resource usage such as cpu and memory, 201 | ## and number of children. If the process is not running, Monit will restart 202 | ## it by default. In case the service is restarted very often and the 203 | ## problem remains, it is possible to disable monitoring using the TIMEOUT 204 | ## statement. This service depends on another service (apache_bin) which 205 | ## is defined above. 206 | # 207 | # check process apache with pidfile /usr/local/apache/logs/httpd.pid 208 | # start program = "/etc/init.d/httpd start" with timeout 60 seconds 209 | # stop program = "/etc/init.d/httpd stop" 210 | # if cpu > 60% for 2 cycles then alert 211 | # if cpu > 80% for 5 cycles then restart 212 | # if totalmem > 200.0 MB for 5 cycles then restart 213 | # if children > 250 then restart 214 | # if loadavg(5min) greater than 10 for 8 cycles then stop 215 | # if disk read > 500 kb/s for 10 cycles then alert 216 | # if disk write > 500 kb/s for 10 cycles then alert 217 | # if failed host www.tildeslash.com port 80 protocol http and request "/somefile.html" then restart 218 | # if failed port 443 protocol https with timeout 15 seconds then restart 219 | # if 3 restarts within 5 cycles then unmonitor 220 | # depends on apache_bin 221 | # group server 222 | # 223 | # 224 | ## Check filesystem permissions, uid, gid, space usage, inode usage and disk I/O. 225 | ## Other services, such as databases, may depend on this resource and an automatically 226 | ## graceful stop may be cascaded to them before the filesystem will become full and data 227 | ## lost. 228 | # 229 | # check filesystem datafs with path /dev/sdb1 230 | # start program = "/bin/mount /data" 231 | # stop program = "/bin/umount /data" 232 | # if failed permission 660 then unmonitor 233 | # if failed uid "root" then unmonitor 234 | # if failed gid "disk" then unmonitor 235 | # if space usage > 80% for 5 times within 15 cycles then alert 236 | # if space usage > 99% then stop 237 | # if inode usage > 30000 then alert 238 | # if inode usage > 99% then stop 239 | # if read rate > 1 MB/s for 5 cycles then alert 240 | # if read rate > 500 operations/s for 5 cycles then alert 241 | # if write rate > 1 MB/s for 5 cycles then alert 242 | # if write rate > 500 operations/s for 5 cycles then alert 243 | # if service time > 10 milliseconds for 3 times within 5 cycles then alert 244 | # group server 245 | # 246 | # 247 | ## Check a file's timestamp. In this example, we test if a file is older 248 | ## than 15 minutes and assume something is wrong if its not updated. Also, 249 | ## if the file size exceed a given limit, execute a script 250 | # 251 | # check file database with path /data/mydatabase.db 252 | # if failed permission 700 then alert 253 | # if failed uid "data" then alert 254 | # if failed gid "data" then alert 255 | # if timestamp > 15 minutes then alert 256 | # if size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba 257 | # 258 | # 259 | ## Check directory permission, uid and gid. An event is triggered if the 260 | ## directory does not belong to the user with uid 0 and gid 0. In addition, 261 | ## the permissions have to match the octal description of 755 (see chmod(1)). 262 | # 263 | # check directory bin with path /bin 264 | # if failed permission 755 then unmonitor 265 | # if failed uid 0 then unmonitor 266 | # if failed gid 0 then unmonitor 267 | # 268 | # 269 | ## Check a remote host availability by issuing a ping test and check the 270 | ## content of a response from a web server. Up to three pings are sent and 271 | ## connection to a port and an application level network check is performed. 272 | # 273 | # check host myserver with address 192.168.1.1 274 | # if failed ping then alert 275 | # if failed port 3306 protocol mysql with timeout 15 seconds then alert 276 | # if failed port 80 protocol http 277 | # and request /some/path with content = "a string" 278 | # then alert 279 | # 280 | # 281 | ## Check a network link status (up/down), link capacity changes, saturation 282 | ## and bandwidth usage. 283 | # 284 | # check network public with interface eth0 285 | # if failed link then alert 286 | # if changed link then alert 287 | # if saturation > 90% then alert 288 | # if download > 10 MB/s then alert 289 | # if total uploaded > 1 GB in last hour then alert 290 | # 291 | # 292 | ## Check custom program status output. 293 | # 294 | # check program myscript with path /usr/local/bin/myscript.sh 295 | # if status != 0 then alert 296 | # 297 | # 298 | ############################################################################### 299 | ## Includes 300 | ############################################################################### 301 | ## 302 | ## It is possible to include additional configuration parts from other files or 303 | ## directories. 304 | # 305 | # include /etc/monit.d/* 306 | # 307 | -------------------------------------------------------------------------------- /pushover: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "${PUSH_OVER_TOKEN}" || -z "${PUSH_OVER_USER}" ]]; then 4 | echo "Required credentials " \ 10 | -e "PUSH_OVER_TOKEN=" \ 11 | -e "PUSH_OVER_USER=" \ 12 | -e "DEBUG=1" \ 13 | diogopms/monit-docker-kubernetes 14 | ``` 15 | 16 | ## Debug 17 | 18 | ```sh 19 | docker run -it \ 20 | -p 2812:2812 \ 21 | -v $(pwd)/monitrc:/etc/monitrc \ 22 | -e "SLACK_URL=" \ 23 | -e "PUSH_OVER_TOKEN=" \ 24 | -e "PUSH_OVER_USER=" \ 25 | -e "DEBUG=0" \ 26 | diogopms/monit-docker-kubernetes 27 | ``` 28 | -------------------------------------------------------------------------------- /samples/monitrc: -------------------------------------------------------------------------------- 1 | set daemon 20 2 | set log syslog 3 | # Web interface 4 | # set httpd port 2812 and allow admin:monit 5 | 6 | check host www.google.com with address www.google.com 7 | if failed 8 | port 443 protocol https 9 | request / 10 | status = 200 11 | for 2 cycles 12 | then exec "/bin/slack" 13 | else if succeeded then exec "/bin/slack" 14 | EOF 15 | -------------------------------------------------------------------------------- /slack: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ -z "${SLACK_URL}" ]]; then 4 | echo "Missing Slack url" 5 | exit 1 6 | fi 7 | 8 | COLOR=${MONIT_COLOR:-$([[ $MONIT_EVENT == *"succeeded"* ]] && echo good || echo danger)} 9 | TEXT=$(echo -e "$MONIT_EVENT: $MONIT_DESCRIPTION" | python3 -c "import json,sys;print(json.dumps(sys.stdin.read()))") 10 | 11 | PAYLOAD="{ 12 | \"attachments\": [ 13 | { 14 | \"text\": $TEXT, 15 | \"color\": \"$COLOR\", 16 | \"mrkdwn_in\": [\"text\"], 17 | \"fields\": [ 18 | { \"title\": \"Date\", \"value\": \"$MONIT_DATE\", \"short\": true }, 19 | { \"title\": \"Service\", \"value\": \"$MONIT_SERVICE\", \"short\": true } 20 | ] 21 | } 22 | ] 23 | }" 24 | 25 | curl -s -X POST --data-urlencode "payload=$PAYLOAD" $SLACK_URL 26 | 27 | exit 0 28 | --------------------------------------------------------------------------------