diff --git a/Dockerfile b/Dockerfile index d505bf9..5886560 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,6 +53,7 @@ RUN \ wheel && \ pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.19/ \ apprise \ + minio \ mysqlclient && \ pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.19/ -r requirements.txt && \ cd /app/healthchecks && \ diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 index 3419dc1..8261cdd 100644 --- a/Dockerfile.aarch64 +++ b/Dockerfile.aarch64 @@ -13,7 +13,7 @@ ENV PYTHONUNBUFFERED=1 RUN \ echo "**** install build packages ****" && \ - apk add --no-cache --upgrade --virtual=build-dependencies \ + apk add --no-cache --virtual=build-dependencies \ build-base \ cargo \ curl-dev \ @@ -25,7 +25,7 @@ RUN \ python3-dev \ zlib-dev && \ echo "**** install runtime packages ****" && \ - apk add --no-cache --upgrade \ + apk add --no-cache \ grep \ mariadb-client \ postgresql-client \ @@ -53,6 +53,7 @@ RUN \ wheel && \ pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.19/ \ apprise \ + minio \ mysqlclient && \ pip install -U --no-cache-dir --find-links https://wheel-index.linuxserver.io/alpine-3.19/ -r requirements.txt && \ cd /app/healthchecks && \ diff --git a/README.md b/README.md index 0b7cb29..5589d93 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Find us at: [Healthchecks](https://github.com/healthchecks/healthchecks) is a watchdog for your cron jobs. It's a web server that listens for pings from your cron jobs, plus a web interface. -[![healthchecks](https://raw.githubusercontent.com/healthchecks/healthchecks/master/static/img/welcome.png)](https://github.com/healthchecks/healthchecks) +[![healthchecks](https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/healthchecks-logo.png")](https://github.com/healthchecks/healthchecks) ## Supported Architectures @@ -61,6 +61,8 @@ The architectures supported by this image are: Access the WebUI at :8000. For more information, check out [Healthchecks](https://github.com/healthchecks/healthchecks). +See [here](https://healthchecks.io/docs/self_hosted_configuration/) for a complete list of available environment variables. + ## Usage To help you get started creating a container from this image you can either use docker-compose or the docker cli. @@ -79,21 +81,21 @@ services: - TZ=Etc/UTC - SITE_ROOT= - SITE_NAME= - - DEFAULT_FROM_EMAIL= - - EMAIL_HOST= - - EMAIL_PORT= - - EMAIL_HOST_USER= - - EMAIL_HOST_PASSWORD= - - EMAIL_USE_TLS= - SUPERUSER_EMAIL= - SUPERUSER_PASSWORD= - - REGENERATE_SETTINGS= #optional - ALLOWED_HOSTS= #optional + - APPRISE_ENABLED=False #optional - CSRF_TRUSTED_ORIGINS= #optional - - APPRISE_ENABLED= #optional - - DEBUG= #optional + - DEBUG=True #optional + - DEFAULT_FROM_EMAIL= #optional + - EMAIL_HOST= #optional + - EMAIL_PORT= #optional + - EMAIL_HOST_USER= #optional + - EMAIL_HOST_PASSWORD= #optional + - EMAIL_USE_TLS= #optional - INTEGRATIONS_ALLOW_PRIVATE_IPS= #optional - PING_EMAIL_DOMAIN= #optional + - RP_ID= #optional - SECRET_KEY= #optional - SITE_LOGO_URL= #optional volumes: @@ -114,21 +116,21 @@ docker run -d \ -e TZ=Etc/UTC \ -e SITE_ROOT= \ -e SITE_NAME= \ - -e DEFAULT_FROM_EMAIL= \ - -e EMAIL_HOST= \ - -e EMAIL_PORT= \ - -e EMAIL_HOST_USER= \ - -e EMAIL_HOST_PASSWORD= \ - -e EMAIL_USE_TLS= \ -e SUPERUSER_EMAIL= \ -e SUPERUSER_PASSWORD= \ - -e REGENERATE_SETTINGS= `#optional` \ -e ALLOWED_HOSTS= `#optional` \ + -e APPRISE_ENABLED=False `#optional` \ -e CSRF_TRUSTED_ORIGINS= `#optional` \ - -e APPRISE_ENABLED= `#optional` \ - -e DEBUG= `#optional` \ + -e DEBUG=True `#optional` \ + -e DEFAULT_FROM_EMAIL= `#optional` \ + -e EMAIL_HOST= `#optional` \ + -e EMAIL_PORT= `#optional` \ + -e EMAIL_HOST_USER= `#optional` \ + -e EMAIL_HOST_PASSWORD= `#optional` \ + -e EMAIL_USE_TLS= `#optional` \ -e INTEGRATIONS_ALLOW_PRIVATE_IPS= `#optional` \ -e PING_EMAIL_DOMAIN= `#optional` \ + -e RP_ID= `#optional` \ -e SECRET_KEY= `#optional` \ -e SITE_LOGO_URL= `#optional` \ -p 8000:8000 \ @@ -149,26 +151,26 @@ Containers are configured using parameters passed at runtime (such as those abov | `-e PUID=1000` | for UserID - see below for explanation | | `-e PGID=1000` | for GroupID - see below for explanation | | `-e TZ=Etc/UTC` | specify a timezone to use, see this [list](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List). | -| `-e SITE_ROOT=` | The site's top-level URL and the port it listens to if differrent than 80 or 443 (e.g., https://healthchecks.example.com:8000) | -| `-e SITE_NAME=` | The site's name (e.g., "Example Corp HealthChecks") | -| `-e DEFAULT_FROM_EMAIL=` | From email for alerts | -| `-e EMAIL_HOST=` | SMTP host | -| `-e EMAIL_PORT=` | SMTP port | -| `-e EMAIL_HOST_USER=` | SMTP user | -| `-e EMAIL_HOST_PASSWORD=` | SMTP password | -| `-e EMAIL_USE_TLS=` | Use TLS for SMTP (`True` or `False`) | -| `-e SUPERUSER_EMAIL=` | Superuser email | -| `-e SUPERUSER_PASSWORD=` | Superuser password | -| `-e REGENERATE_SETTINGS=` | Defaults to False. Set to True to always override the `local_settings.py` file with values from environment variables. Do not set to True if you have made manual modifications to this file. | -| `-e ALLOWED_HOSTS=` | A [list](https://docs.python.org/3/tutorial/introduction.html#lists) of valid hostnames for the server. Default is: `["*"]` | +| `-e SITE_ROOT=` | The site's top-level URL and the port it listens to if different than 80 or 443 (e.g., https://healthchecks.example.com:8000). | +| `-e SITE_NAME=` | The site's name (e.g., "Example Corp HealthChecks"). | +| `-e SUPERUSER_EMAIL=` | Superuser email. | +| `-e SUPERUSER_PASSWORD=` | Superuser password. | +| `-e ALLOWED_HOSTS=` | A comma-separated list of valid hostnames for the server. Default is: `*`. | +| `-e APPRISE_ENABLED=False` | Set to `True` to enable the Apprise integration (https://github.com/caronc/apprise). | | `-e CSRF_TRUSTED_ORIGINS=` | A [list](https://docs.python.org/3/tutorial/introduction.html#lists) of trusted origins for unsafe requests (e.g. POST). Defaults to the value of `SITE_ROOT`. | -| `-e APPRISE_ENABLED=` | Defaults to False. A boolean that turns on/off the Apprise integration (https://github.com/caronc/apprise) | -| `-e DEBUG=` | Defaults to True. Debug mode relaxes CSRF protections and increases logging verbosity but should be disabled for production instances as it will impact performance and security. | +| `-e DEBUG=True` | Set to `False` to disable. Debug mode relaxes CSRF protections and increases logging verbosity but should be disabled for production instances as it will impact performance and security. | +| `-e DEFAULT_FROM_EMAIL=` | From email for alerts. | +| `-e EMAIL_HOST=` | SMTP host. | +| `-e EMAIL_PORT=` | SMTP port. | +| `-e EMAIL_HOST_USER=` | SMTP user. | +| `-e EMAIL_HOST_PASSWORD=` | SMTP password. | +| `-e EMAIL_USE_TLS=` | Use TLS for SMTP (`True` or `False`). | | `-e INTEGRATIONS_ALLOW_PRIVATE_IPS=` | Defaults to False. Set to True to allow integrations to connect to private IP addresses. | -| `-e PING_EMAIL_DOMAIN=` | The domain to use for generating ping email addresses. | -| `-e SECRET_KEY=` | A secret key used for cryptographic signing. Will generate a secure value if one is not supplied | -| `-e SITE_LOGO_URL=` | Full URL to custom site logo | -| `-v /config` | Persistent config files | +| `-e PING_EMAIL_DOMAIN=` | The domain to use for generating ping email addresses. Defaults to `localhost`. | +| `-e RP_ID=` | If using webauthn for 2FA set this to match your Healthchecks domain. Webauthn will only work over https. | +| `-e SECRET_KEY=` | A secret key used for cryptographic signing. Will generate a random value if one is not supplied and save it to `/config/local_settings.py`. | +| `-e SITE_LOGO_URL=` | Full URL to custom site logo. | +| `-v /config` | Persistent config files. | ## Environment variables from files (Docker secrets) @@ -331,6 +333,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64 ## Versions +* **24.01.24:** - No longer write envs to local_settings.py. Envs will take precedence over any existing values in config file. Removed `REGENERATE_SETTINGS` as it is now obsolete. * **22.01.24:** - Fix CSRF handling. * **23.12.23:** - Rebase to Alpine 3.19. * **31.05.23:** - Rebase to Alpine 3.18. Deprecate armhf. diff --git a/readme-vars.yml b/readme-vars.yml index c7ccce3..9e09c72 100644 --- a/readme-vars.yml +++ b/readme-vars.yml @@ -3,7 +3,7 @@ # project information project_name: healthchecks project_url: "https://github.com/healthchecks/healthchecks" -project_logo: "https://raw.githubusercontent.com/healthchecks/healthchecks/master/static/img/welcome.png" +project_logo: https://raw.githubusercontent.com/linuxserver/docker-templates/master/linuxserver.io/img/healthchecks-logo.png" project_blurb: | [{{ project_name|capitalize }}]({{ project_url }}) is a watchdog for your cron jobs. It's a web server that listens for pings from your cron jobs, plus a web interface. project_lsio_github_repo_url: "https://github.com/linuxserver/docker-{{ project_name }}" @@ -17,30 +17,30 @@ available_architectures: param_container_name: "{{ project_name }}" param_usage_include_vols: true param_volumes: - - { vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/config", desc: "Persistent config files" } + - { vol_path: "/config", vol_host_path: "/path/to/{{ project_name }}/config", desc: "Persistent config files." } param_usage_include_env: true param_env_vars: - - { env_var: "SITE_ROOT", env_value: "", desc: "The site's top-level URL and the port it listens to if differrent than 80 or 443 (e.g., https://healthchecks.example.com:8000)" } - - { env_var: "SITE_NAME", env_value: "", desc: "The site's name (e.g., \"Example Corp HealthChecks\")"} - - { env_var: "DEFAULT_FROM_EMAIL", env_value: "", desc: "From email for alerts" } - - { env_var: "EMAIL_HOST", env_value: "", desc: "SMTP host" } - - { env_var: "EMAIL_PORT", env_value: "", desc: "SMTP port"} - - { env_var: "EMAIL_HOST_USER", env_value: "", desc: "SMTP user"} - - { env_var: "EMAIL_HOST_PASSWORD", env_value: "", desc: "SMTP password"} - - { env_var: "EMAIL_USE_TLS", env_value: "", desc: "Use TLS for SMTP (`True` or `False`)"} - - { env_var: "SUPERUSER_EMAIL", env_value: "", desc: "Superuser email"} - - { env_var: "SUPERUSER_PASSWORD", env_value: "", desc: "Superuser password"} + - { env_var: "SITE_ROOT", env_value: "", desc: "The site's top-level URL and the port it listens to if different than 80 or 443 (e.g., https://healthchecks.example.com:8000)." } + - { env_var: "SITE_NAME", env_value: "", desc: "The site's name (e.g., \"Example Corp HealthChecks\")."} + - { env_var: "SUPERUSER_EMAIL", env_value: "", desc: "Superuser email."} + - { env_var: "SUPERUSER_PASSWORD", env_value: "", desc: "Superuser password."} opt_param_usage_include_env: true opt_param_env_vars: - - { env_var: "REGENERATE_SETTINGS", env_value: "", desc: "Defaults to False. Set to True to always override the `local_settings.py` file with values from environment variables. Do not set to True if you have made manual modifications to this file."} - - { env_var: "ALLOWED_HOSTS", env_value: "", desc: "A [list](https://docs.python.org/3/tutorial/introduction.html#lists) of valid hostnames for the server. Default is: `[\"*\"]`"} + - { env_var: "ALLOWED_HOSTS", env_value: "", desc: "A comma-separated list of valid hostnames for the server. Default is: `*`."} + - { env_var: "APPRISE_ENABLED", env_value: "False", desc: "Set to `True` to enable the Apprise integration (https://github.com/caronc/apprise)." } - { env_var: "CSRF_TRUSTED_ORIGINS", env_value: "", desc: "A [list](https://docs.python.org/3/tutorial/introduction.html#lists) of trusted origins for unsafe requests (e.g. POST). Defaults to the value of `SITE_ROOT`."} - - { env_var: "APPRISE_ENABLED", env_value: "", desc: "Defaults to False. A boolean that turns on/off the Apprise integration (https://github.com/caronc/apprise)" } - - { env_var: "DEBUG", env_value: "", desc: "Defaults to True. Debug mode relaxes CSRF protections and increases logging verbosity but should be disabled for production instances as it will impact performance and security."} + - { env_var: "DEBUG", env_value: "True", desc: "Set to `False` to disable. Debug mode relaxes CSRF protections and increases logging verbosity but should be disabled for production instances as it will impact performance and security."} + - { env_var: "DEFAULT_FROM_EMAIL", env_value: "", desc: "From email for alerts." } + - { env_var: "EMAIL_HOST", env_value: "", desc: "SMTP host." } + - { env_var: "EMAIL_PORT", env_value: "", desc: "SMTP port."} + - { env_var: "EMAIL_HOST_USER", env_value: "", desc: "SMTP user."} + - { env_var: "EMAIL_HOST_PASSWORD", env_value: "", desc: "SMTP password."} + - { env_var: "EMAIL_USE_TLS", env_value: "", desc: "Use TLS for SMTP (`True` or `False`)."} - { env_var: "INTEGRATIONS_ALLOW_PRIVATE_IPS", env_value: "", desc: "Defaults to False. Set to True to allow integrations to connect to private IP addresses."} - - { env_var: "PING_EMAIL_DOMAIN", env_value: "", desc: "The domain to use for generating ping email addresses."} - - { env_var: "SECRET_KEY", env_value: "", desc: "A secret key used for cryptographic signing. Will generate a secure value if one is not supplied" } - - { env_var: "SITE_LOGO_URL", env_value: "", desc: "Full URL to custom site logo"} + - { env_var: "PING_EMAIL_DOMAIN", env_value: "", desc: "The domain to use for generating ping email addresses. Defaults to `localhost`."} + - { env_var: "RP_ID", env_value: "", desc: "If using webauthn for 2FA set this to match your Healthchecks domain. Webauthn will only work over https."} + - { env_var: "SECRET_KEY", env_value: "", desc: "A secret key used for cryptographic signing. Will generate a random value if one is not supplied and save it to `/config/local_settings.py`." } + - { env_var: "SITE_LOGO_URL", env_value: "", desc: "Full URL to custom site logo."} param_usage_include_ports: true param_ports: @@ -54,8 +54,11 @@ app_setup_block_enabled: true app_setup_block: | Access the WebUI at :8000. For more information, check out [Healthchecks](https://github.com/healthchecks/healthchecks). + See [here](https://healthchecks.io/docs/self_hosted_configuration/) for a complete list of available environment variables. + # changelog changelogs: + - { date: "24.01.24:", desc: "No longer write envs to local_settings.py. Envs will take precedence over any existing values in config file. Removed `REGENERATE_SETTINGS` as it is now obsolete."} - { date: "22.01.24:", desc: "Fix CSRF handling."} - { date: "23.12.23:", desc: "Rebase to Alpine 3.19."} - { date: "31.05.23:", desc: "Rebase to Alpine 3.18. Deprecate armhf."} diff --git a/root/etc/s6-overlay/s6-rc.d/init-healthchecks-config/run b/root/etc/s6-overlay/s6-rc.d/init-healthchecks-config/run index f8c994f..16b13d2 100755 --- a/root/etc/s6-overlay/s6-rc.d/init-healthchecks-config/run +++ b/root/etc/s6-overlay/s6-rc.d/init-healthchecks-config/run @@ -4,82 +4,9 @@ lsiown -R abc:abc \ /app/healthchecks/hc/api/migrations -#From https://healthchecks.io/docs/self_hosted_configuration/ -HC_CONF=( -ADMINS -ALLOWED_HOSTS -APPRISE_ENABLED -DEBUG -DEFAULT_FROM_EMAIL -DISCORD_CLIENT_ID -DISCORD_CLIENT_SECRET -EMAIL_HOST -EMAIL_HOST_PASSWORD -EMAIL_HOST_USER -EMAIL_PORT -EMAIL_USE_TLS -EMAIL_USE_VERIFICATION -INTEGRATIONS_ALLOW_PRIVATE_IPS -LINENOTIFY_CLIENT_ID -LINENOTIFY_CLIENT_SECRET -MASTER_BADGE_LABEL -MATRIX_ACCESS_TOKEN -MATRIX_HOMESERVER -MATRIX_USER_ID -MATTERMOST_ENABLED -MSTEAMS_ENABLED -OPSGENIE_ENABLED -PAGERTREE_ENABLED -PD_APP_ID -PD_ENABLED -PING_EMAIL_DOMAIN -PING_ENDPOINT -PROMETHEUS_ENABLED -PUSHBULLET_CLIENT_ID -PUSHBULLET_CLIENT_SECRET -PUSHOVER_API_TOKEN -PUSHOVER_EMERGENCY_EXPIRATION -PUSHOVER_EMERGENCY_RETRY_DELAY -PUSHOVER_SUBSCRIPTION_URL -REGISTRATION_OPEN -REMOTE_USER_HEADER -RP_ID -S3_ACCESS_KEY -S3_BUCKET -S3_ENDPOINT -S3_REGION -S3_SECRET_KEY -S3_TIMEOUT -SHELL_ENABLED -SIGNAL_CLI_ENABLED -SITE_LOGO_URL -SITE_NAME -SITE_ROOT -SLACK_CLIENT_ID -SLACK_CLIENT_SECRET -SLACK_ENABLED -SPIKE_ENABLED -TELEGRAM_BOT_NAME -TELEGRAM_TOKEN -TRELLO_APP_KEY -TWILIO_ACCOUNT -TWILIO_AUTH -TWILIO_FROM -TWILIO_MESSAGING_SERVICE_SID -TWILIO_USE_WHATSAPP -USE_PAYMENTS -VICTOROPS_ENABLED -WEBHOOKS_ENABLED -ZULIP_ENABLED -) - -function insert_config() { - if grep -E "^$1 = " /config/local_settings.py &> /dev/null; then - sed -i -E "s|^$1 = .*\$|$1 = $2|" /config/local_settings.py - else - echo "$1 = $2" >> /config/local_settings.py - fi -} +if [[ ! -f "/config/local_settings.py" ]]; then + touch /config/local_settings.py +fi if [[ -z ${SITE_ROOT} ]] && ! grep -q "^SITE_ROOT" /config/local_settings.py; then echo "No SITE_ROOT provided, halting init" @@ -88,37 +15,23 @@ elif [[ -z ${SITE_ROOT} ]] && grep -q "^SITE_ROOT" /config/local_settings.py; th SITE_ROOT=$(grep -Po "^SITE_ROOT\s*=\s*\K(.*)" /config/local_settings.py | tr -d '"') fi -if [[ ! -f "/config/local_settings.py" ]] || [[ "${REGENERATE_SETTINGS,,}" == "true" ]]; then - touch /config/local_settings.py - for CONF in "${HC_CONF[@]}"; do - if [[ -n "${!CONF}" ]]; then - if [[ "${!CONF}" == "True" ]] || [[ "${!CONF}" == "False" ]] || [[ "${!CONF:0:1}" == "[" ]]; then #booleans or arrays - insert_config "$CONF" "${!CONF}" - else - insert_config "$CONF" "\"${!CONF}\"" - fi - fi - done - if [[ -n ${CSRF_TRUSTED_ORIGINS} ]]; then - insert_config "CSRF_TRUSTED_ORIGINS" "${CSRF_TRUSTED_ORIGINS}" - else - insert_config "CSRF_TRUSTED_ORIGINS" "[\"${SITE_ROOT}\"]" - fi - if [[ -n ${PING_BODY_LIMIT} ]]; then - insert_config "PING_BODY_LIMIT" "$(printf '%d\n' "${PING_BODY_LIMIT}")" - fi +# Need to inject SITE_ROOT into CSRF_TRUSTED_ORIGINS if not specified by the user because it defaults to an empty list +if [[ -z ${CSRF_TRUSTED_ORIGINS} ]] && ! grep -q "^CSRF_TRUSTED_ORIGINS" /config/local_settings.py; then + CSRF_TRUSTED_ORIGINS=[\"${SITE_ROOT}\"] + echo "${CSRF_TRUSTED_ORIGINS}" > /run/s6/container_environment/CSRF_TRUSTED_ORIGINS fi -if [[ -z "$SECRET_KEY" ]] && ! grep "SECRET_KEY" /config/local_settings.py &> /dev/null; then - insert_config "SECRET_KEY" "\"$(tr -dc A-Za-z0-9 > /config/local_settings.py + echo "*** No SECRET_KEY specified so a random one has been generated an written to /config/local_settings.py **" fi - -if [[ ! -f "/app/healthchecks/hc/local_settings.py" ]]; then +if [[ ! -L "/app/healthchecks/hc/local_settings.py" ]]; then ln -s /config/local_settings.py /app/healthchecks/hc/local_settings.py fi -if [[ ! -f "/app/healthchecks/hc.sqlite" ]]; then +if [[ ! -L "/app/healthchecks/hc.sqlite" ]]; then ln -s /config/hc.sqlite /app/healthchecks/hc.sqlite fi