Running with Docker
In the Healthchecks source code, /docker/ directory, you can find a sample configuration for running the project with Docker and Docker Compose.
Note: For the sake of simplicity, the sample configuration starts a single database node and a single web server node, both on the same host. It does not handle TLS termination.
Getting Started
- Grab the Healthchecks source code from the GitHub repository.
-
Copy
docker/.env.exampletodocker/.envand add your configuration in it. As a minimum, set the following fields:ALLOWED_HOSTS– the domain name of your Healthchecks instance. Example:ALLOWED_HOSTS=hc.example.org.DEFAULT_FROM_EMAIL– the "From:" address for outbound emails.EMAIL_HOST– the SMTP server.EMAIL_HOST_PASSWORD– the SMTP password.EMAIL_HOST_USER– the SMTP username.SECRET_KEY– secures HTTP sessions, set to a random value.SITE_ROOT– The base public URL of your Healthchecks instance. Example:SITE_ROOT=https://hc.example.org.
-
Create and start containers:
$ cd docker $ docker compose up -
Create a superuser:
$ docker compose run web /opt/healthchecks/manage.py createsuperuserThis will trigger an interactive prompt.
You can also provide credentials via parameters, bypassing the interactive prompt:
$ docker compose run web /opt/healthchecks/manage.py createsuperuser --email [email protected] --password changeme123 -
Open http://localhost:8000 in your browser and log in with the credentials from the previous step.
uWSGI Configuration
The reference Dockerfile uses uWSGI
as the WSGI server. You can configure uWSGI by setting UWSGI_... environment
variables in docker/.env. For example, to disable HTTP request logging, set:
UWSGI_DISABLE_LOGGING=1
To adjust the number of uWSGI processes (for example, to save memory), set:
UWSGI_PROCESSES=2
Read more about configuring uWSGI in uWSGI documentation.
SMTP Listener Configuration via SMTPD_PORT
Healthchecks comes with a smtpd management command, which runs a SMTP listener
service. With the command running, you can ping your checks by sending email messages
to [email protected] email addresses.
The container is configured to start the SMTP listener conditionally, based
on the value of the SMTPD_PORT environment value:
- If
SMTPD_PORTenvironment variable is not set, the SMTP listener will not run. - If
SMTPD_PORTis set, the listener will run and listen on the specified port. You may also need to editdocker-compose.ymlto expose the listening port (see the "ports" section under the "web" service indocker-compose.yml).
The conditional logic lives in uWSGI configuration file, uwsgi.ini.
See also: the PING_EMAIL_DOMAIN environment variable for customizing the domain part of the email addresses.
Reverse Proxy, TLS Termination, and CSRF Protection
If you plan to expose your Healthchecks instance to the public internet, make sure you put a TLS-terminating reverse proxy or a load balancer in front of it.
Important: configure the reverse proxy to set the X-Forwarded-For request
header. Healthchecks trusts it to determine the client's IP address. If the proxy
does not set the X-Forwarded-For header, the clients can pass their own value and
circumvent, among other things, the IP-based rate limiting in the login form.
Important: This Dockerfile uses uWSGI, which relies on the X-Forwarded-Proto header to determine if a request is secure or not. Without this information you may run into HTTP 403 "CSRF verification failed." errors when using your Healthchecks instance. See this issue comment for more information.
Make sure your TLS-terminating reverse proxy:
- Discards the
X-Forwarded-Protoheader sent by the end user. - Sets the
X-Forwarded-Protoheader value to match the protocol of the original request ("http" or "https").
For example, in NGINX you can use the $scheme variable like so:
proxy_set_header X-Forwarded-Proto $scheme;
If you are using haproxy, you can do the same like so:
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http unless { ssl_fc }
Making Healthchecks Trust Your Self-signed TLS Certificate
If you configure Healthchecks to deliver notifications to a server that uses a self-signed TLS certificate, you may see a "TLS handshake failed" error when sending a notification.
Healthchecks uses libcurl for making outbound HTTP(S) requests. curl and libcurl validates certificates and refuses to continue if a certificate cannot be validated. It is possible to turn off certificate validation, but doing so is strongly discouraged in curl docs.
To make curl accept a self-hosted certificate, add your self-signed certificate to the Healthchecks container's trust store.
First, mount the certificate inside the container running the healthchecks
web application. In docker-compose.yml, add the following in the web: section:
volumes:
- /path/to/cert.pem:/usr/local/share/ca-certificates/my-selfsigned-cert.crt:ro
Note: /path/to/cert.pem must be an absolute path in the host system pointing
to the certificate.
Then reload configuration and run update-ca-certificates inside the container
as the root user:
docker compose up
docker compose exec -u root web update-ca-certificates
Upgrading Database
When you upgrade the database version in docker-compose.yml (for example,
from postgres:12 to postgres:16), you will also need to upgrade your postgres
data directory. One way to do this is using the
pgautoupgrade container.
Steps:
- As the very first step, take a full backup of your database.
- Stop the
dbandwebcontainers:docker compose stop - Look up the name of the postgres data volume name using
docker volume ls - Run
pgautoupgradelike so:
docker run --rm --name pgauto -it \
--mount type=volume,source=<pg-volume-name-here>,target=/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=password \
-e PGAUTO_ONESHOT=yes \
pgautoupgrade/pgautoupgrade:16-bookworm
- Update the
docker-compose.ymlfile to use thepostgres:16image - Start containers:
docker compose up
Pre-built Images
Pre-built Docker images, built from the Dockerfile in the /docker/ directory,
are available on Docker Hub.
The images are built automatically for every new release.
The Docker images:
- Support amd64, arm/v7 and arm64 architectures.
- Use uWSGI as the web server. uWSGI is configured to perform database migrations
on startup, and to run
sendalerts,sendreports, andsmtpdin the background. You do not need to run them separately. - Ship with both PostgreSQL and MySQL database drivers.
- Serve static files using the whitenoise library.
- Have the apprise library preinstalled.
- Do not handle TLS termination. In a production setup, you will want to put the Healthchecks container behind a reverse proxy or load balancer that handles TLS termination.
To use a pre-built image for Healthchecks version X.Y, in the docker-compose.yml file
replace the "build" section with:
image: healthchecks/healthchecks:vX.Y