├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature.yml ├── SUPPORT.md ├── dependabot.yml ├── docker-healthchecks.jpg ├── labels.yml └── workflows │ ├── build.yml │ ├── labels.yml │ └── test.yml ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── docker-bake.hcl ├── examples ├── compose │ ├── .env │ ├── compose.yml │ ├── healthchecks.env │ └── msmtpd.env ├── mysql │ ├── .env │ ├── compose.yml │ ├── healthchecks.env │ └── msmtpd.env └── traefik │ ├── .env │ ├── README.md │ ├── compose.yml │ ├── healthchecks.env │ └── msmtpd.env ├── rootfs ├── etc │ └── cont-init.d │ │ ├── 00-fix-logs.sh │ │ ├── 01-fix-uidgid.sh │ │ ├── 02-fix-perms.sh │ │ ├── 03-config.sh │ │ └── 04-svc-main.sh ├── opt │ └── healthchecks │ │ └── uwsgi.ini └── tpl │ └── img │ ├── apple-touch-180.png │ ├── logo-512-green.png │ ├── logo-full.png │ ├── logo-full@2x.png │ ├── logo.png │ └── logo@2x.png └── test ├── compose.yml └── healthchecks.env /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | /*.sh linguist-detectable=false 2 | /rootfs/** linguist-detectable=false 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @crazy-max 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: crazy-max 2 | custom: https://www.paypal.me/crazyws 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 2 | name: Bug Report 3 | description: Report a bug 4 | labels: 5 | - kind/bug 6 | - status/triage 7 | 8 | body: 9 | - type: checkboxes 10 | attributes: 11 | label: Support guidelines 12 | description: Please read the support guidelines before proceeding. 13 | options: 14 | - label: I've read the [support guidelines](https://github.com/crazy-max/docker-healthchecks/blob/master/.github/SUPPORT.md) 15 | required: true 16 | 17 | - type: checkboxes 18 | attributes: 19 | label: I've found a bug and checked that ... 20 | description: | 21 | Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why. 22 | options: 23 | - label: ... the documentation does not mention anything about my problem 24 | - label: ... there are no open or closed issues that are related to my problem 25 | 26 | - type: textarea 27 | attributes: 28 | label: Description 29 | description: | 30 | Please provide a brief description of the bug in 1-2 sentences. 31 | validations: 32 | required: true 33 | 34 | - type: textarea 35 | attributes: 36 | label: Expected behaviour 37 | description: | 38 | Please describe precisely what you'd expect to happen. 39 | validations: 40 | required: true 41 | 42 | - type: textarea 43 | attributes: 44 | label: Actual behaviour 45 | description: | 46 | Please describe precisely what is actually happening. 47 | validations: 48 | required: true 49 | 50 | - type: textarea 51 | attributes: 52 | label: Steps to reproduce 53 | description: | 54 | Please describe the steps to reproduce the bug. 55 | placeholder: | 56 | 1. ... 57 | 2. ... 58 | 3. ... 59 | validations: 60 | required: true 61 | 62 | - type: textarea 63 | attributes: 64 | label: Docker info 65 | description: | 66 | Output of `docker info` command. 67 | render: text 68 | validations: 69 | required: true 70 | 71 | - type: textarea 72 | attributes: 73 | label: Docker Compose config 74 | description: | 75 | Output of `docker compose config` command. 76 | render: yaml 77 | 78 | - type: textarea 79 | attributes: 80 | label: Logs 81 | description: | 82 | Please provide the container logs (set `LOG_LEVEL=debug` if applicable). 83 | render: text 84 | validations: 85 | required: true 86 | 87 | - type: textarea 88 | attributes: 89 | label: Additional info 90 | description: | 91 | Please provide any additional information that seem useful. 92 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser 2 | blank_issues_enabled: true 3 | contact_links: 4 | - name: Questions and Discussions 5 | url: https://github.com/crazy-max/docker-healthchecks/discussions/new 6 | about: Use Github Discussions to ask questions and/or open discussion topics. 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 2 | name: Feature request 3 | description: Missing functionality? Come tell us about it! 4 | labels: 5 | - kind/enhancement 6 | - status/triage 7 | 8 | body: 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Description 13 | description: What is the feature you want to see? 14 | validations: 15 | required: true 16 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support [](https://isitmaintained.com/project/crazy-max/docker-healthchecks) 2 | 3 | ## Reporting an issue 4 | 5 | Please do a search in [open issues](https://github.com/crazy-max/docker-healthchecks/issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed. 6 | 7 | If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment. 8 | 9 | :+1: - upvote 10 | 11 | :-1: - downvote 12 | 13 | If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below. 14 | 15 | ## Writing good bug reports and feature requests 16 | 17 | File a single issue per problem and feature request. 18 | 19 | * Do not enumerate multiple bugs or feature requests in the same issue. 20 | * Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes. 21 | 22 | The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix. 23 | 24 | You are now ready to [create a new issue](https://github.com/crazy-max/docker-healthchecks/issues/new/choose)! 25 | 26 | ## Closure policy 27 | 28 | * Support directly related to Healthchecks will not be provided if your problem is not related to the operation of this image. 29 | * Issues that don't have the information requested above (when applicable) will be closed immediately and the poster directed to the support guidelines. 30 | * Issues that go a week without a response from original poster are subject to closure at my discretion. 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | time: "08:00" 8 | timezone: "Europe/Paris" 9 | labels: 10 | - "kind/dependencies" 11 | - "bot" 12 | -------------------------------------------------------------------------------- /.github/docker-healthchecks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crazy-max/docker-healthchecks/eef77d758b6c8b06220adc3e4b4f11da1eca6a89/.github/docker-healthchecks.jpg -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | ## more info https://github.com/crazy-max/ghaction-github-labeler 2 | - 3 | name: "bot" 4 | color: "69cde9" 5 | description: "" 6 | - 7 | name: "good first issue" 8 | color: "7057ff" 9 | description: "" 10 | - 11 | name: "help wanted" 12 | color: "4caf50" 13 | description: "" 14 | - 15 | name: "area/ci" 16 | color: "ed9ca9" 17 | description: "" 18 | - 19 | name: "area/dockerfile" 20 | color: "03a9f4" 21 | description: "" 22 | - 23 | name: "kind/bug" 24 | color: "b60205" 25 | description: "" 26 | - 27 | name: "kind/dependencies" 28 | color: "0366d6" 29 | description: "" 30 | - 31 | name: "kind/docs" 32 | color: "c5def5" 33 | description: "" 34 | - 35 | name: "kind/duplicate" 36 | color: "cccccc" 37 | description: "" 38 | - 39 | name: "kind/enhancement" 40 | color: "0054ca" 41 | description: "" 42 | - 43 | name: "kind/invalid" 44 | color: "e6e6e6" 45 | description: "" 46 | - 47 | name: "kind/upstream" 48 | color: "fbca04" 49 | description: "" 50 | - 51 | name: "kind/wontfix" 52 | color: "ffffff" 53 | description: "" 54 | - 55 | name: "status/automerge" 56 | color: "8f4fbc" 57 | description: "" 58 | - 59 | name: "status/needs-investigation" 60 | color: "e6625b" 61 | description: "" 62 | - 63 | name: "status/needs-more-info" 64 | color: "795548" 65 | description: "" 66 | - 67 | name: "status/stale" 68 | color: "237da0" 69 | description: "" 70 | - 71 | name: "status/triage" 72 | color: "dde4b7" 73 | description: "" 74 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | schedule: 9 | - cron: '0 8 */6 * *' # every 6 days to keep cache 10 | push: 11 | branches: 12 | - 'master' 13 | tags: 14 | - '*' 15 | paths-ignore: 16 | - '**.md' 17 | pull_request: 18 | paths-ignore: 19 | - '**.md' 20 | 21 | env: 22 | DOCKERHUB_SLUG: crazymax/healthchecks 23 | GHCR_SLUG: ghcr.io/crazy-max/healthchecks 24 | 25 | jobs: 26 | prepare: 27 | runs-on: ubuntu-latest 28 | outputs: 29 | matrix: ${{ steps.platforms.outputs.matrix }} 30 | steps: 31 | - 32 | name: Checkout 33 | uses: actions/checkout@v4 34 | - 35 | name: Create matrix 36 | id: platforms 37 | run: | 38 | echo "matrix=$(docker buildx bake image-all --print | jq -cr '.target."image-all".platforms')" >>${GITHUB_OUTPUT} 39 | - 40 | name: Show matrix 41 | run: | 42 | echo ${{ steps.platforms.outputs.matrix }} 43 | - 44 | name: Docker meta 45 | id: meta 46 | uses: docker/metadata-action@v5 47 | with: 48 | images: | 49 | ${{ env.DOCKERHUB_SLUG }} 50 | ${{ env.GHCR_SLUG }} 51 | tags: | 52 | type=match,pattern=(.*)-r,group=1 53 | type=ref,event=pr 54 | type=edge 55 | labels: | 56 | org.opencontainers.image.title=Healthchecks 57 | org.opencontainers.image.description=Cron Monitoring Tool 58 | org.opencontainers.image.vendor=CrazyMax 59 | - 60 | name: Rename meta bake definition file 61 | run: | 62 | mv "${{ steps.meta.outputs.bake-file }}" "/tmp/bake-meta.json" 63 | - 64 | name: Upload meta bake definition 65 | uses: actions/upload-artifact@v4 66 | with: 67 | name: bake-meta 68 | path: /tmp/bake-meta.json 69 | if-no-files-found: error 70 | retention-days: 1 71 | 72 | build: 73 | runs-on: ubuntu-latest 74 | timeout-minutes: 480 75 | needs: 76 | - prepare 77 | strategy: 78 | fail-fast: false 79 | matrix: 80 | platform: ${{ fromJson(needs.prepare.outputs.matrix) }} 81 | steps: 82 | - 83 | name: Prepare 84 | run: | 85 | platform=${{ matrix.platform }} 86 | echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV 87 | - 88 | name: Checkout 89 | uses: actions/checkout@v4 90 | - 91 | name: Download meta bake definition 92 | uses: actions/download-artifact@v4 93 | with: 94 | name: bake-meta 95 | path: /tmp 96 | - 97 | name: Set up QEMU 98 | uses: docker/setup-qemu-action@v3 99 | - 100 | name: Set up Docker Buildx 101 | uses: docker/setup-buildx-action@v3 102 | with: 103 | buildkitd-flags: --debug 104 | - 105 | name: Login to DockerHub 106 | if: github.event_name != 'pull_request' 107 | uses: docker/login-action@v3 108 | with: 109 | username: ${{ secrets.DOCKER_USERNAME }} 110 | password: ${{ secrets.DOCKER_PASSWORD }} 111 | - 112 | name: Login to GHCR 113 | if: github.event_name != 'pull_request' 114 | uses: docker/login-action@v3 115 | with: 116 | registry: ghcr.io 117 | username: ${{ github.repository_owner }} 118 | password: ${{ secrets.GITHUB_TOKEN }} 119 | - 120 | name: Build 121 | id: bake 122 | uses: docker/bake-action@v5 123 | with: 124 | files: | 125 | ./docker-bake.hcl 126 | /tmp/bake-meta.json 127 | targets: image 128 | set: | 129 | *.tags= 130 | *.platform=${{ matrix.platform }} 131 | *.cache-from=type=gha,scope=build-${{ env.PLATFORM_PAIR }} 132 | *.cache-to=type=gha,scope=build-${{ env.PLATFORM_PAIR }},mode=max 133 | *.output=type=image,"name=${{ env.DOCKERHUB_SLUG }},${{ env.GHCR_SLUG }}",push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }} 134 | - 135 | name: Export digest 136 | run: | 137 | mkdir -p /tmp/digests 138 | digest="${{ fromJSON(steps.bake.outputs.metadata).image['containerimage.digest'] }}" 139 | touch "/tmp/digests/${digest#sha256:}" 140 | - 141 | name: Upload digest 142 | uses: actions/upload-artifact@v4 143 | with: 144 | name: digests-${{ env.PLATFORM_PAIR }} 145 | path: /tmp/digests/* 146 | if-no-files-found: error 147 | retention-days: 1 148 | 149 | merge: 150 | runs-on: ubuntu-latest 151 | if: github.event_name != 'pull_request' 152 | needs: 153 | - build 154 | steps: 155 | - 156 | name: Download meta bake definition 157 | uses: actions/download-artifact@v4 158 | with: 159 | name: bake-meta 160 | path: /tmp 161 | - 162 | name: Download digests 163 | uses: actions/download-artifact@v4 164 | with: 165 | path: /tmp/digests 166 | pattern: digests-* 167 | merge-multiple: true 168 | - 169 | name: Set up Docker Buildx 170 | uses: docker/setup-buildx-action@v3 171 | - 172 | name: Login to DockerHub 173 | uses: docker/login-action@v3 174 | with: 175 | username: ${{ secrets.DOCKER_USERNAME }} 176 | password: ${{ secrets.DOCKER_PASSWORD }} 177 | - 178 | name: Login to GHCR 179 | uses: docker/login-action@v3 180 | with: 181 | registry: ghcr.io 182 | username: ${{ github.repository_owner }} 183 | password: ${{ secrets.GITHUB_TOKEN }} 184 | - 185 | name: Create manifest list and push 186 | working-directory: /tmp/digests 187 | run: | 188 | docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.DOCKERHUB_SLUG }}")) | "-t " + .) | join(" ")' /tmp/bake-meta.json) \ 189 | $(printf '${{ env.DOCKERHUB_SLUG }}@sha256:%s ' *) 190 | docker buildx imagetools create $(jq -cr '.target."docker-metadata-action".tags | map(select(startswith("${{ env.GHCR_SLUG }}")) | "-t " + .) | join(" ")' /tmp/bake-meta.json) \ 191 | $(printf '${{ env.GHCR_SLUG }}@sha256:%s ' *) 192 | - 193 | name: Inspect image 194 | run: | 195 | tag=$(jq -r '.target."docker-metadata-action".args.DOCKER_META_VERSION' /tmp/bake-meta.json) 196 | docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${tag} 197 | docker buildx imagetools inspect ${{ env.GHCR_SLUG }}:${tag} 198 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: labels 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - 'master' 11 | paths: 12 | - '.github/labels.yml' 13 | - '.github/workflows/labels.yml' 14 | pull_request: 15 | paths: 16 | - '.github/labels.yml' 17 | - '.github/workflows/labels.yml' 18 | 19 | jobs: 20 | labeler: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - 24 | name: Checkout 25 | uses: actions/checkout@v4 26 | - 27 | name: Run Labeler 28 | uses: crazy-max/ghaction-github-labeler@v5 29 | with: 30 | dry-run: ${{ github.event_name == 'pull_request' }} 31 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - 'master' 11 | paths-ignore: 12 | - '**.md' 13 | pull_request: 14 | paths-ignore: 15 | - '**.md' 16 | 17 | env: 18 | BUILD_TAG: healthchecks:test 19 | CONTAINER_NAME: healthchecks 20 | 21 | jobs: 22 | test: 23 | runs-on: ubuntu-latest 24 | steps: 25 | - 26 | name: Checkout 27 | uses: actions/checkout@v4 28 | - 29 | name: Set up QEMU 30 | uses: docker/setup-qemu-action@v3 31 | - 32 | name: Set up Docker Buildx 33 | uses: docker/setup-buildx-action@v3 34 | - 35 | name: Build 36 | uses: docker/bake-action@v5 37 | with: 38 | targets: image-local 39 | env: 40 | DEFAULT_TAG: ${{ env.BUILD_TAG }} 41 | - 42 | name: Start 43 | run: | 44 | docker compose up -d 45 | working-directory: test 46 | env: 47 | HEALTHCHECKS_IMAGE: ${{ env.BUILD_TAG }} 48 | HEALTHCHECKS_CONTAINER: ${{ env.CONTAINER_NAME }} 49 | - 50 | name: Check container logs 51 | uses: crazy-max/.github/.github/actions/container-logs-check@main 52 | with: 53 | container_name: ${{ env.CONTAINER_NAME }} 54 | log_check: "GET /api/v1/status/" 55 | timeout: 120 56 | - 57 | name: Logs 58 | if: always() 59 | run: | 60 | docker compose logs 61 | working-directory: test 62 | env: 63 | HEALTHCHECKS_IMAGE: ${{ env.BUILD_TAG }} 64 | HEALTHCHECKS_CONTAINER: ${{ env.CONTAINER_NAME }} 65 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 3.1-r0 (2023/12/30) 4 | 5 | * Healthchecks 3.1 6 | * Alpine Linux 3.18 7 | * Python 3.12 8 | 9 | ## 2.1-r0 (2022/06/05) 10 | 11 | * Healthchecks 2.1 12 | * alpine-s6 3.15-2.2.0.3 13 | 14 | ## 1.22.0-r0 (2021/08/15) 15 | 16 | * Healthchecks 1.22.0 17 | * alpine-s6 3.14-2.2.0.3 18 | 19 | ## 1.21.0-r0 (2021/07/04) 20 | 21 | * Healthchecks 1.21.0 22 | 23 | ## 1.20.0-r0 (2021/05/06) 24 | 25 | * Healthchecks 1.20.0 26 | * alpine-s6 3.13-2.2.0.3 27 | 28 | ## 1.19.0-r3 (2021/03/18) 29 | 30 | * Upstream Alpine update 31 | 32 | ## 1.19.0-r2 (2021/03/04) 33 | 34 | * Renamed `yasu` (more info https://github.com/crazy-max/yasu#yet-another) 35 | 36 | ## 1.19.0-r1 (2021/03/03) 37 | 38 | * Switch to `gosu` 39 | * Disable Rust (pyca/cryptography#5771) 40 | * Alpine Linux 3.13 with s6-overlay 41 | 42 | ## 1.19.0-r0 (2021/02/06) 43 | 44 | * Healthchecks 1.19.0 45 | * Switch to buildx bake 46 | * Do not fail on permission issue 47 | 48 | ## 1.18.0-RC1 (2020/12/10) 49 | 50 | * Healthchecks 1.18.0 51 | 52 | ## 1.17.0-RC1 (2020/10/14) 53 | 54 | * Healthchecks 1.17.0 55 | 56 | ## 1.16.0-RC1 (2020/10/12) 57 | 58 | * Initial version based on Healthchecks 1.16.0 59 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | ARG HEALTHCHECKS_VERSION=3.7 4 | ARG ALPINE_VERSION=3.20 5 | ARG S6_VERSION=2.2.0.3 6 | 7 | # https://github.com/healthchecks/healthchecks/blob/v3.7/docker/Dockerfile#L1 8 | ARG PYTHON_VERSION=3.12 9 | 10 | FROM crazymax/yasu:latest AS yasu 11 | FROM crazymax/alpine-s6-dist:${ALPINE_VERSION}-${S6_VERSION} AS s6 12 | 13 | FROM --platform=${BUILDPLATFORM} alpine:${ALPINE_VERSION} AS src 14 | RUN apk add --update git 15 | WORKDIR /src 16 | RUN git init . && git remote add origin "https://github.com/healthchecks/healthchecks" 17 | ARG HEALTHCHECKS_VERSION 18 | RUN git fetch origin "v${HEALTHCHECKS_VERSION}" && git checkout -q FETCH_HEAD 19 | 20 | FROM python:${PYTHON_VERSION}-alpine${ALPINE_VERSION} 21 | COPY --from=s6 / / 22 | COPY --from=yasu / / 23 | COPY --from=src /src /opt/healthchecks 24 | 25 | WORKDIR /opt/healthchecks 26 | RUN apk --update --no-cache add \ 27 | bash \ 28 | bearssl \ 29 | curl \ 30 | jansson \ 31 | libcap \ 32 | libffi \ 33 | libpq \ 34 | libxml2 \ 35 | mailcap \ 36 | mariadb-client \ 37 | musl \ 38 | openssl \ 39 | pcre2 \ 40 | postgresql-client \ 41 | shadow \ 42 | tzdata \ 43 | zlib \ 44 | && apk --update --no-cache add -t build-dependencies \ 45 | build-base \ 46 | cairo \ 47 | cairo-dev \ 48 | cargo \ 49 | curl-dev \ 50 | gcc \ 51 | git \ 52 | jansson-dev \ 53 | libcap-dev \ 54 | libffi-dev \ 55 | libpq-dev \ 56 | libxml2-dev \ 57 | linux-headers \ 58 | mariadb-dev \ 59 | musl-dev \ 60 | openssl-dev \ 61 | pcre2-dev \ 62 | postgresql-dev \ 63 | python3-dev \ 64 | zlib-dev \ 65 | && python -m pip install --upgrade pip \ 66 | && pip install apprise minio mysqlclient uwsgi \ 67 | && PYTHONUNBUFFERED=1 pip install --upgrade --no-cache-dir -r requirements.txt \ 68 | && touch hc/local_settings.py \ 69 | && apk del build-dependencies \ 70 | && rm -rf /opt/healthchecks/.git\ 71 | /root/.cache \ 72 | /root/.cargo \ 73 | /tmp/* 74 | 75 | COPY rootfs / 76 | 77 | ENV TZ="UTC" \ 78 | PUID="1000" \ 79 | PGID="1000" 80 | 81 | RUN addgroup -g ${PGID} healthchecks \ 82 | && adduser -D -H -u ${PUID} -G healthchecks -s /bin/sh healthchecks 83 | 84 | EXPOSE 8000 2500 85 | VOLUME [ "/data" ] 86 | 87 | ENTRYPOINT [ "/init" ] 88 | 89 | HEALTHCHECK --interval=10s --timeout=5s --start-period=20s \ 90 | CMD curl --fail http://127.0.0.1:8000/api/v1/status/ || exit 1 91 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2024 CrazyMax 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 11 | 12 | 13 | ## ⚠️ Abandoned project 14 | 15 | This project is not maintained anymore and is abandoned. Feel free to fork and 16 | make your own changes, or you can switch to the [official image](https://hub.docker.com/r/healthchecks/healthchecks). 17 | 18 | ## About 19 | 20 | Docker image for [Healthchecks](https://github.com/healthchecks/healthchecks), 21 | a cron monitoring tool. 22 | 23 | > [!TIP] 24 | > Want to be notified of new releases? Check out 🔔 [Diun (Docker Image Update Notifier)](https://github.com/crazy-max/diun) 25 | > project! 26 | 27 | ___ 28 | 29 | * [Features](#features) 30 | * [Build locally](#build-locally) 31 | * [Image](#image) 32 | * [Environment variables](#environment-variables) 33 | * [Ports](#ports) 34 | * [Usage](#usage) 35 | * [Docker Compose](#docker-compose) 36 | * [Command line](#command-line) 37 | * [Upgrade](#upgrade) 38 | * [Contributing](#contributing) 39 | * [License](#license) 40 | 41 | ## Features 42 | 43 | * Run as non-root user 44 | * Multi-platform image 45 | * [Traefik](https://github.com/containous/traefik-library-image) as reverse proxy and creation/renewal of Let's Encrypt certificates (see [this template](examples/traefik)) 46 | 47 | ## Build locally 48 | 49 | ```shell 50 | git clone https://github.com/crazy-max/docker-healthchecks.git 51 | cd docker-healthchecks 52 | 53 | # Build image and output to docker (default) 54 | docker buildx bake 55 | 56 | # Build multi-platform image 57 | docker buildx bake image-all 58 | ``` 59 | 60 | ## Image 61 | 62 | | Registry | Image | 63 | |--------------------------------------------------------------------------------------------------|---------------------------------| 64 | | [Docker Hub](https://hub.docker.com/r/crazymax/healthchecks/) | `crazymax/healthchecks` | 65 | | [GitHub Container Registry](https://github.com/users/crazy-max/packages/container/package/healthchecks) | `ghcr.io/crazy-max/healthchecks` | 66 | 67 | Following platforms for this image are available: 68 | 69 | ``` 70 | $ docker buildx imagetools inspect crazymax/healthchecks --format "{{json .Manifest}}" | \ 71 | jq -r '.manifests[] | select(.platform.os != null and .platform.os != "unknown") | .platform | "\(.os)/\(.architecture)\(if .variant then "/" + .variant else "" end)"' 72 | 73 | linux/amd64 74 | linux/arm/v7 75 | linux/arm64 76 | ``` 77 | 78 | ## Environment variables 79 | 80 | * `TZ`: The timezone assigned to the container (default `UTC`) 81 | * `PUID`: Process UID (default `1000`) 82 | * `PGID`: Process GID (default `1000`) 83 | * `SUPERUSER_EMAIL`: Superuser email to access [admin panel](https://github.com/healthchecks/healthchecks#accessing-administration-panel) 84 | * `SUPERUSER_PASSWORD`: Superuser password 85 | * `USE_OFFICIAL_LOGO`: Replace generic logo with official branding (default `false`) 86 | 87 | To configure the application, you just add the environment variables as shown in the 88 | [Configuration page](https://github.com/healthchecks/healthchecks#configuration) of Healthchecks Project. 89 | 90 | > 💡 `SUPERUSER_PASSWORD_FILE` can be used to fill in the value from a file, especially for Docker's secrets feature. 91 | 92 | ## Volumes 93 | 94 | * `/data`: Contains SQLite database and static images folder 95 | 96 | > :warning: Note that the volumes should be owned by the user/group with the specified `PUID` and `PGID`. If you don't 97 | > give the volume correct permissions, the container may not start. 98 | 99 | ## Ports 100 | 101 | * `2500`: [Healthchecks SMTP](https://github.com/healthchecks/healthchecks#receiving-emails) listener service 102 | * `8000`: HTTP port 103 | 104 | ## Usage 105 | 106 | ### Docker Compose 107 | 108 | Docker compose is the recommended way to run this image. You can use the following 109 | [docker compose template](examples/compose/compose.yml), then run the container: 110 | 111 | ```bash 112 | docker compose up -d 113 | docker compose logs -f 114 | ``` 115 | 116 | ### Command line 117 | 118 | You can also use the following minimal command: 119 | 120 | ```bash 121 | $ docker run -d -p 8000:8000 --name healthchecks \ 122 | -e "TZ=Europe/Paris" \ 123 | -e "SECRET_KEY=5up3rS3kr1t" \ 124 | -e "DB=sqlite" \ 125 | -e "DB_NAME=/data/hc.sqlite" \ 126 | -e "ALLOWED_HOSTS=*" \ 127 | -v $(pwd)/data:/data \ 128 | crazymax/healthchecks:latest 129 | ``` 130 | 131 | ## Upgrade 132 | 133 | Recreate the container whenever I push an update: 134 | 135 | ```bash 136 | docker compose pull 137 | docker compose up -d 138 | ``` 139 | 140 | ## Contributing 141 | 142 | Want to contribute? Awesome! The most basic way to show your support is to star 143 | the project, or to raise issues. You can also support this project by [**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) 144 | or by making a [PayPal donation](https://www.paypal.me/crazyws) to ensure this 145 | journey continues indefinitely! 146 | 147 | Thanks again for your support, it is much appreciated! :pray: 148 | 149 | ## License 150 | 151 | MIT. See `LICENSE` for more details. 152 | -------------------------------------------------------------------------------- /docker-bake.hcl: -------------------------------------------------------------------------------- 1 | variable "DEFAULT_TAG" { 2 | default = "healthchecks:local" 3 | } 4 | 5 | // Special target: https://github.com/docker/metadata-action#bake-definition 6 | target "docker-metadata-action" { 7 | tags = ["${DEFAULT_TAG}"] 8 | } 9 | 10 | // Default target if none specified 11 | group "default" { 12 | targets = ["image-local"] 13 | } 14 | 15 | target "image" { 16 | inherits = ["docker-metadata-action"] 17 | } 18 | 19 | target "image-local" { 20 | inherits = ["image"] 21 | output = ["type=docker"] 22 | } 23 | 24 | target "image-all" { 25 | inherits = ["image"] 26 | platforms = [ 27 | "linux/amd64", 28 | "linux/arm/v7", 29 | "linux/arm64" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /examples/compose/.env: -------------------------------------------------------------------------------- 1 | TZ=Europe/Paris 2 | -------------------------------------------------------------------------------- /examples/compose/compose.yml: -------------------------------------------------------------------------------- 1 | name: healthchecks 2 | 3 | services: 4 | msmtpd: 5 | image: crazymax/msmtpd:latest 6 | container_name: msmtpd 7 | env_file: 8 | - "./msmtpd.env" 9 | environment: 10 | - "TZ" 11 | restart: always 12 | 13 | healthchecks: 14 | image: crazymax/healthchecks:latest 15 | container_name: healthchecks 16 | ports: 17 | - target: 8000 18 | published: 8000 19 | protocol: tcp 20 | volumes: 21 | - "healthchecks:/data" 22 | env_file: 23 | - "./healthchecks.env" 24 | environment: 25 | - "TZ" 26 | - "DB=sqlite" 27 | - "DB_NAME=/data/hc.sqlite" 28 | restart: always 29 | 30 | volumes: 31 | healthchecks: 32 | -------------------------------------------------------------------------------- /examples/compose/healthchecks.env: -------------------------------------------------------------------------------- 1 | PUID=1000 2 | PGID=1000 3 | 4 | SECRET_KEY=5up3rS3kr1t 5 | SITE_ROOT=http://healthchecks.example.com:8000 6 | SITE_NAME=Healthchecks 7 | ALLOWED_HOSTS=* 8 | 9 | DEFAULT_FROM_EMAIL=healthchecks@example.com 10 | EMAIL_HOST=msmtpd 11 | EMAIL_PORT=2500 12 | 13 | SUPERUSER_EMAIL=healthchecks@example.com 14 | SUPERUSER_PASSWORD=pwd 15 | -------------------------------------------------------------------------------- /examples/compose/msmtpd.env: -------------------------------------------------------------------------------- 1 | # https://github.com/crazy-max/docker-msmtpd 2 | SMTP_HOST=smtp.gmail.com 3 | SMTP_PORT=587 4 | SMTP_TLS=on 5 | SMTP_STARTTLS=on 6 | SMTP_TLS_CHECKCERT=on 7 | SMTP_AUTH=on 8 | SMTP_USER=foo 9 | SMTP_PASSWORD=bar 10 | SMTP_FROM=foo@gmail.com 11 | -------------------------------------------------------------------------------- /examples/mysql/.env: -------------------------------------------------------------------------------- 1 | TZ=Europe/Paris 2 | 3 | MYSQL_DATABASE=hc 4 | MYSQL_USER=hc 5 | MYSQL_PASSWORD=hc 6 | -------------------------------------------------------------------------------- /examples/mysql/compose.yml: -------------------------------------------------------------------------------- 1 | name: healthchecks 2 | 3 | services: 4 | db: 5 | image: mariadb:10 6 | container_name: healthchecks_db 7 | volumes: 8 | - "healthchecks-db:/var/lib/mysql" 9 | environment: 10 | - "MARIADB_RANDOM_ROOT_PASSWORD=yes" 11 | - "MYSQL_DATABASE" 12 | - "MYSQL_USER" 13 | - "MYSQL_PASSWORD" 14 | restart: always 15 | 16 | msmtpd: 17 | image: crazymax/msmtpd:latest 18 | container_name: healthchecks_msmtpd 19 | env_file: 20 | - "./msmtpd.env" 21 | environment: 22 | - "TZ" 23 | restart: always 24 | 25 | healthchecks: 26 | image: crazymax/healthchecks:latest 27 | container_name: healthchecks 28 | ports: 29 | - target: 8000 30 | published: 8000 31 | protocol: tcp 32 | volumes: 33 | - "healthchecks:/data" 34 | env_file: 35 | - "./healthchecks.env" 36 | environment: 37 | - "TZ" 38 | - "DB=mysql" 39 | - "DB_HOST=db" 40 | - "DB_NAME=${MYSQL_DATABASE}" 41 | - "DB_USER=${MYSQL_USER}" 42 | - "DB_PASSWORD=${MYSQL_PASSWORD}" 43 | restart: always 44 | 45 | volumes: 46 | healthchecks: 47 | healthchecks-db: 48 | -------------------------------------------------------------------------------- /examples/mysql/healthchecks.env: -------------------------------------------------------------------------------- 1 | PUID=1000 2 | PGID=1000 3 | 4 | SECRET_KEY=5up3rS3kr1t 5 | SITE_ROOT=http://healthchecks.example.com:8000 6 | SITE_NAME=Healthchecks 7 | ALLOWED_HOSTS=* 8 | 9 | DEFAULT_FROM_EMAIL=healthchecks@example.com 10 | EMAIL_HOST=msmtpd 11 | EMAIL_PORT=2500 12 | 13 | SUPERUSER_EMAIL=healthchecks@example.com 14 | SUPERUSER_PASSWORD=pwd 15 | -------------------------------------------------------------------------------- /examples/mysql/msmtpd.env: -------------------------------------------------------------------------------- 1 | # https://github.com/crazy-max/docker-msmtpd 2 | SMTP_HOST=smtp.gmail.com 3 | SMTP_PORT=587 4 | SMTP_TLS=on 5 | SMTP_STARTTLS=on 6 | SMTP_TLS_CHECKCERT=on 7 | SMTP_AUTH=on 8 | SMTP_USER=foo 9 | SMTP_PASSWORD=bar 10 | SMTP_FROM=foo@gmail.com 11 | -------------------------------------------------------------------------------- /examples/traefik/.env: -------------------------------------------------------------------------------- 1 | TZ=Europe/Paris 2 | -------------------------------------------------------------------------------- /examples/traefik/README.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | ```bash 4 | touch acme.json 5 | chmod 600 acme.json 6 | docker compose up -d 7 | docker compose logs -f 8 | ``` 9 | -------------------------------------------------------------------------------- /examples/traefik/compose.yml: -------------------------------------------------------------------------------- 1 | name: healthchecks 2 | 3 | services: 4 | traefik: 5 | image: traefik:2.5 6 | container_name: traefik 7 | command: 8 | - "--global.checknewversion=false" 9 | - "--global.sendanonymoususage=false" 10 | - "--log=true" 11 | - "--log.level=INFO" 12 | - "--entrypoints.http=true" 13 | - "--entrypoints.http.address=:80" 14 | - "--entrypoints.http.http.redirections.entrypoint.to=https" 15 | - "--entrypoints.http.http.redirections.entrypoint.scheme=https" 16 | - "--entrypoints.https=true" 17 | - "--entrypoints.https.address=:443" 18 | - "--certificatesresolvers.letsencrypt" 19 | - "--certificatesresolvers.letsencrypt.acme.storage=acme.json" 20 | - "--certificatesresolvers.letsencrypt.acme.email=webmaster@example.com" 21 | - "--certificatesresolvers.letsencrypt.acme.httpchallenge" 22 | - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http" 23 | - "--providers.docker" 24 | - "--providers.docker.watch=true" 25 | - "--providers.docker.exposedbydefault=false" 26 | ports: 27 | - target: 80 28 | published: 80 29 | protocol: tcp 30 | - target: 443 31 | published: 443 32 | protocol: tcp 33 | volumes: 34 | - "./acme.json:/acme.json" 35 | - "/var/run/docker.sock:/var/run/docker.sock" 36 | environment: 37 | - "TZ" 38 | restart: always 39 | 40 | msmtpd: 41 | image: crazymax/msmtpd:latest 42 | container_name: msmtpd 43 | env_file: 44 | - "./msmtpd.env" 45 | environment: 46 | - "TZ" 47 | restart: always 48 | 49 | healthchecks: 50 | image: crazymax/healthchecks:latest 51 | container_name: healthchecks 52 | volumes: 53 | - "healthchecks:/data" 54 | labels: 55 | - "traefik.enable=true" 56 | - "traefik.http.routers.healthchecks.entrypoints=https" 57 | - "traefik.http.routers.healthchecks.rule=Host(`healthchecks.example.com`)" 58 | - "traefik.http.routers.healthchecks.tls=true" 59 | - "traefik.http.routers.healthchecks.tls.certresolver=letsencrypt" 60 | - "traefik.http.routers.healthchecks.tls.domains[0].main=healthchecks.example.com" 61 | - "traefik.http.services.healthchecks.loadbalancer.server.port=8000" 62 | env_file: 63 | - "./healthchecks.env" 64 | environment: 65 | - "TZ" 66 | - "DB=sqlite" 67 | - "DB_NAME=/data/hc.sqlite" 68 | restart: always 69 | 70 | volumes: 71 | healthchecks: 72 | -------------------------------------------------------------------------------- /examples/traefik/healthchecks.env: -------------------------------------------------------------------------------- 1 | PUID=1000 2 | PGID=1000 3 | 4 | SECRET_KEY=5up3rS3kr1t 5 | SITE_ROOT=https://healthchecks.example.com 6 | SITE_NAME=Healthchecks 7 | ALLOWED_HOSTS=healthchecks.example.com 8 | 9 | DEFAULT_FROM_EMAIL=healthchecks@example.com 10 | EMAIL_HOST=msmtpd 11 | EMAIL_PORT=2500 12 | 13 | SUPERUSER_EMAIL=healthchecks@example.com 14 | SUPERUSER_PASSWORD=pwd 15 | -------------------------------------------------------------------------------- /examples/traefik/msmtpd.env: -------------------------------------------------------------------------------- 1 | # https://github.com/crazy-max/docker-msmtpd 2 | SMTP_HOST=smtp.gmail.com 3 | SMTP_PORT=587 4 | SMTP_TLS=on 5 | SMTP_STARTTLS=on 6 | SMTP_TLS_CHECKCERT=on 7 | SMTP_AUTH=on 8 | SMTP_USER=foo 9 | SMTP_PASSWORD=bar 10 | SMTP_FROM=foo@gmail.com 11 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/00-fix-logs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | 3 | # Fix access rights to stdout and stderr 4 | chown ${PUID}:${PGID} /proc/self/fd/1 /proc/self/fd/2 || true 5 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/01-fix-uidgid.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | 3 | if [ -n "${PGID}" ] && [ "${PGID}" != "$(id -g healthchecks)" ]; then 4 | echo "Switching to PGID ${PGID}..." 5 | sed -i -e "s/^healthchecks:\([^:]*\):[0-9]*/healthchecks:\1:${PGID}/" /etc/group 6 | sed -i -e "s/^healthchecks:\([^:]*\):\([0-9]*\):[0-9]*/healthchecks:\1:\2:${PGID}/" /etc/passwd 7 | fi 8 | if [ -n "${PUID}" ] && [ "${PUID}" != "$(id -u healthchecks)" ]; then 9 | echo "Switching to PUID ${PUID}..." 10 | sed -i -e "s/^healthchecks:\([^:]*\):[0-9]*:\([0-9]*\)/healthchecks:\1:${PUID}:\2/" /etc/passwd 11 | fi 12 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/02-fix-perms.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | 3 | echo "Fixing perms..." 4 | mkdir -p /data/img 5 | chown -R healthchecks. \ 6 | /data \ 7 | /opt/healthchecks \ 8 | /tpl 9 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/03-config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | # From https://github.com/docker-library/mariadb/blob/master/docker-entrypoint.sh#L21-L41 4 | # usage: file_env VAR [DEFAULT] 5 | # ie: file_env 'XYZ_DB_PASSWORD' 'example' 6 | # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of 7 | # "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) 8 | file_env() { 9 | local var="$1" 10 | local fileVar="${var}_FILE" 11 | local def="${2:-}" 12 | if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then 13 | echo >&2 "error: both $var and $fileVar are set (but are exclusive)" 14 | exit 1 15 | fi 16 | local val="$def" 17 | if [ "${!var:-}" ]; then 18 | val="${!var}" 19 | elif [ "${!fileVar:-}" ]; then 20 | val="$(< "${!fileVar}")" 21 | fi 22 | export "$var"="$val" 23 | unset "$fileVar" 24 | } 25 | 26 | TZ=${TZ:-UTC} 27 | USE_OFFICIAL_LOGO=${USE_OFFICIAL_LOGO:-false} 28 | DB_TIMEOUT=${DB_TIMEOUT:-60} 29 | 30 | # Timezone 31 | echo "Setting timezone to ${TZ}..." 32 | ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime 33 | echo ${TZ} > /etc/timezone 34 | 35 | # Settings 36 | echo "Setting Healthchecks configuration..." 37 | sed -i "s|DEBUG = .*|DEBUG = False|g" /opt/healthchecks/hc/settings.py 38 | sed -i "s|TIME_ZONE = .*|TIME_ZONE = \"${TZ}\"|g" /opt/healthchecks/hc/settings.py 39 | 40 | # DB 41 | echo "Checking database..." 42 | if [ -z "$DB" ]; then 43 | >&2 echo "ERROR: DB must be defined" 44 | exit 1 45 | fi 46 | if [ "$DB" = "mysql" ]; then 47 | echo "Use MySQL database" 48 | if [ -z "${DB_HOST}" ]; then 49 | >&2 echo "ERROR: DB_HOST must be defined" 50 | exit 1 51 | fi 52 | if [ -z "${DB_NAME}" ]; then 53 | >&2 echo "ERROR: DB_NAME must be defined" 54 | exit 1 55 | fi 56 | if [ -z "${DB_USER}" ]; then 57 | >&2 echo "ERROR: DB_USER must be defined" 58 | exit 1 59 | fi 60 | 61 | DB_CMD="mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_USER} "-p${DB_PASSWORD}"" 62 | #echo "DB_CMD=$DB_CMD" 63 | 64 | echo "Waiting ${DB_TIMEOUT}s for MySQL database to be ready..." 65 | counter=1 66 | while ! ${DB_CMD} -e "show databases;" > /dev/null 2>&1; do 67 | sleep 1 68 | counter=$((counter + 1)) 69 | if [ ${counter} -gt "${DB_TIMEOUT}" ]; then 70 | >&2 echo "ERROR: Failed to connect to MySQL database on $DB_HOST" 71 | exit 1 72 | fi; 73 | done 74 | echo "MySQL database ready!" 75 | elif [ "$DB" = "postgres" ]; then 76 | echo "Use PostgreSQL database" 77 | if [ -z "${DB_HOST}" ]; then 78 | >&2 echo "ERROR: DB_HOST must be defined" 79 | exit 1 80 | fi 81 | if [ -z "${DB_NAME}" ]; then 82 | >&2 echo "ERROR: DB_NAME must be defined" 83 | exit 1 84 | fi 85 | if [ -z "${DB_USER}" ]; then 86 | >&2 echo "ERROR: DB_USER must be defined" 87 | exit 1 88 | fi 89 | 90 | DB_CMD="psql --host=${DB_HOST} --port=${DB_PORT} --username=${DB_USER} -lqt" 91 | #echo "DB_CMD=$DB_CMD" 92 | 93 | echo "Waiting ${DB_TIMEOUT}s for database to be ready..." 94 | counter=1 95 | while ${DB_CMD} | cut -d \| -f 1 | grep -qw "${DB_NAME}" > /dev/null 2>&1; [ $? -ne 0 ]; do 96 | sleep 1 97 | counter=$((counter + 1)) 98 | if [ ${counter} -gt "${DB_TIMEOUT}" ]; then 99 | >&2 echo "ERROR: Failed to connect to PostgreSQL database on $DB_HOST" 100 | exit 1 101 | fi; 102 | done 103 | echo "PostgreSQL database ready!" 104 | elif [ "$DB" = "sqlite" ]; then 105 | echo "Use SQLite database" 106 | if [ -z "${DB_NAME}" ]; then 107 | >&2 echo "ERROR: DB_NAME must be defined" 108 | exit 1 109 | fi 110 | if [ ! -f "/opt/healthchecks/hc.sqlite" ]; then 111 | yasu healthchecks:healthchecks ln -sf /data/hc.sqlite /opt/healthchecks/hc.sqlite 112 | fi 113 | else 114 | >&2 echo "ERROR: Unknown database type: $DB" 115 | exit 1 116 | fi 117 | 118 | # Migrate database 119 | echo "Migrating database..." 120 | yasu healthchecks:healthchecks python /opt/healthchecks/manage.py migrate --noinput 121 | 122 | # Create superuser 123 | file_env 'SUPERUSER_PASSWORD' 124 | if [ -n "$SUPERUSER_EMAIL" ] && [ -n "$SUPERUSER_PASSWORD" ]; then 125 | cat << EOF | yasu healthchecks:healthchecks python /opt/healthchecks/manage.py shell 126 | from django.contrib.auth.models import User; 127 | username = 'su'; 128 | password = '$SUPERUSER_PASSWORD'; 129 | email = '$SUPERUSER_EMAIL'; 130 | if User.objects.filter(username=username).count()==0: 131 | User.objects.create_superuser(username, email, password); 132 | print('Superuser created successfully!'); 133 | else: 134 | print('Superuser already exists.'); 135 | EOF 136 | fi 137 | 138 | if [ "${USE_OFFICIAL_LOGO}" = "true" ]; then 139 | echo "Using official branding logo..." 140 | yasu healthchecks:healthchecks cp -f /tpl/img/* /opt/healthchecks/static/img/ 141 | fi 142 | 143 | if [ "$(ls -A /data/img)" ]; then 144 | echo "Copying /data/img to /opt/healthchecks/static/img..." 145 | yasu healthchecks:healthchecks cp -rf /data/img/* /opt/healthchecks/static/img/ 146 | fi 147 | -------------------------------------------------------------------------------- /rootfs/etc/cont-init.d/04-svc-main.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | 3 | mkdir -p /etc/services.d/healthchecks 4 | cat > /etc/services.d/healthchecks/run <