Container-Mon

September 12, 2025 ยท View on GitHub

Get notified when your Docker containers are unhealthy.

screenshot

Prerequisites

  • A notification service supported by Shoutrrr and the required API keys or other configuration for your chosen service (e.g: Telegram, Discord, Slack, Teams etc)

Building

Build the app:

go build

Format:

gofmt -w -s .

Installation

  • If you have go installed, you can clone the repository and directly run the go file
  • You can download the latest release artifact from GitHub Releases
  • If you have Docker installed, you can run the Docker image

Configuration

Configuration can be set via environment variables or command line flags. Command line flags take precedence over environment variables. Only CONTAINERMON_NOTIFICATION_URL (or --notification-url) is mandatory; all other fields are optional.

Environment VariableCommand Line FlagTypeDefault ValueDescription
CONTAINERMON_FAIL_LIMIT--fail-limitInt1Number of consecutive 'unhealthy' checks to reach before sending a notification
CONTAINERMON_CRON--cronString/5 ** *Standard Cron schedule of when to run healthchecks
CONTAINERMON_NOTIFICATION_URL--notification-urlStringN/ANotification URL for Shoutrrr. Multiple services can be used with the | (pipe) character as a separator.
CONTAINERMON_HEALTHY_NOTIFICATION_URL--healthy-notification-urlStringN/ANotification URL for healthy state notifications
CONTAINERMON_USE_LABELS--use-labelsBoolfalseIf true, only monitor containers with the label containermon.enable=true set
CONTAINERMON_NOTIFY_HEALTHY--notify-healthyBooltrueIf true, send a notification when an 'unhealthy' container returns to being 'healthy'
CONTAINERMON_CHECK_STOPPED--check-stoppedBooltrueIf true, consider stopped containers as 'unhealthy'. If false, only containers with a healthcheck set are monitored
CONTAINERMON_MESSAGE_PREFIX--message-prefixStringN/ACustom text to be prefixed to all notification messages.
CONTAINERMON_CHECK_EXIT_CODE--check-exit-codeBoolfalseWhen set to true, only exited containers with a non-zero exit code will be marked as unhealthy
DOCKER_HOSTString/var/run/docker.sockPath for the Docker API socket
DOCKER_API_VERSIONStringdocker defaultDocker API version to use
DOCKER_CERT_PATHStringdocker defaultPath to load the TLS certificates from
DOCKER_TLS_VERIFYBoolfalseEnable or disable TLS verification

Usage

Go

go run app.go --notification-url "telegram://token@telegram?channels=channel-1" --fail-limit=1 --cron="*/2 * * * *"

Executable

./container-mon --notification-url "telegram://token@telegram?channels=channel-1" --fail-limit=1 --cron="*/2 * * * *"

Docker

docker run \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINERMON_NOTIFICATION_URL=telegram://token@telegram?channels=channel-1 \
  ghcr.io/rafhaanshah/container-mon:latest

Docker-Compose

services:
  container-mon:
    container_name: container-mon
    image: ghcr.io/rafhaanshah/container-mon:latest
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - CONTAINERMON_NOTIFICATION_URL=telegram://token@telegram?channels=channel-1

Troubleshooting

  • Docker API version issues: if you get error messages like client version 1.43 is too new. Maximum supported API version is 1.42 then please set the DOCKER_API_VERSION environment variable to the latest version supported by your Docker engine (e.g. DOCKER_API_VERSION=1.42), which you can check by running docker version.
  • Notifier issues: please check if your URL works with the Shoutrrr CLI here.

Security Considerations

  • It can be considered a security risk to directly map your Docket socket inside a container. A proxy such as Socket-Proxy can be used to give fine-grained access to parts of the Docker API, this application only needs to be able to read a list of running containers ->

    
    docker run \
     -e DOCKER_HOST=tcp://socket-proxy:2375
    ...
    
    
  • This container runs as root by default to access the Docker socket. You may run it as another user that has access to the socket as described here: Running a Docker container as a non-root user ->

    docker run \
    -u $(id -u):$(stat -c '%g' "/var/run/docker.sock") \
    ...
    
    

License

MIT