Upstream repo

We use the official Zabbix Docker GitHub repo for Docker Compose deployment, we add a few local changes.

Create dir

mkdir -p '/opt/git/github.com/zabbix/zabbix-docker/branches/latest'

Pull repo

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' clone 'https://github.com/zabbix/zabbix-docker' .

Docker Compose

Base setup

When everything's ready start Zabbix with Docker Compose, otherwise head down to Initial setup or Upgrade an existing repo first.

Define variables assuming the official Zabbix Docker repo lives at /opt/git/github.com/zabbix/zabbix-docker/branches/latest:

export UPSTREAM_REPO_DIR='/opt/git/github.com/zabbix/zabbix-docker/branches/latest'
export UPSTREAM_REPO_TAG='6.4.15'
export UPSTREAM_COMPOSE_FILE="${UPSTREAM_REPO_DIR%/}"'/docker-compose_v3_alpine_pgsql_latest.yaml'
export UPSTREAM_COMPOSE_DB_FILE="${UPSTREAM_REPO_DIR%/}"'/compose_databases.yaml'
export UPSTREAM_ENV_FILE="${UPSTREAM_REPO_DIR%/}"'/.env'
export COMPOSE_CTX='bi_colombo'
export COMPOSE_PROJECT_NAME='zabbixserver-'"${COMPOSE_CTX}"
export COMPOSE_ENV_FILE=<add accordingly>

Context

On your deployment machine create the necessary Docker context to connect to and control the Docker daemon on whatever target host you'll be using, for example:

docker context create fully.qualified.domain.name --docker 'host=ssh://root@fully.qualified.domain.name'

Pull

Pull newest image versions. Do this locally on your deployment machine, not on the actual app machine. Chances are the app machine cannot even pull directly from your container registry anyways:

docker compose --project-name "${COMPOSE_PROJECT_NAME}" --file "${UPSTREAM_COMPOSE_FILE}" --env-file "${UPSTREAM_ENV_FILE}" --env-file "${COMPOSE_ENV_FILE}" pull

Copy to target

Copy images to target Docker host, that is assuming you deploy to a machine that itself has no network route to reach Docker Hub. Copying in its simplest form involves a local docker save and a remote docker load. Consider the helper mini-project quico.space/Quico/copy-docker where copy-docker.sh allows the following workflow:

source "${UPSTREAM_ENV_FILE}" "${COMPOSE_ENV_FILE}" 2>/dev/null
while IFS= read -r image; do
    copy-docker "$(eval echo "${image}")" containers-1.ops.loft.seneve.de
done < <(grep -Pih -- '^[^#]*image:' "${UPSTREAM_COMPOSE_FILE}" "${UPSTREAM_COMPOSE_DB_FILE}" | awk '{print $2}')

This first greps a list of images and their tags from Zabbix' official Docker Compose files:

# grep -Pi -- '^[^#]*image:' "${UPSTREAM_COMPOSE_FILE}" | awk '{print $2}'
"${ZABBIX_SERVER_PGSQL_IMAGE}:${ZABBIX_ALPINE_IMAGE_TAG}${ZABBIX_IMAGE_TAG_POSTFIX}"
"${ZABBIX_WEB_NGINX_PGSQL_IMAGE}:${ZABBIX_ALPINE_IMAGE_TAG}${ZABBIX_IMAGE_TAG_POSTFIX}"
"${POSTGRESQL_IMAGE}:${POSTGRESQL_IMAGE_TAG}"
busybox

It then expands each variable via eval echo "${image}" like so:

zabbix/zabbix-server-pgsql:alpine-6.4-latest
zabbix/zabbix-web-nginx-pgsql:alpine-6.4-latest
postgres:15-alpine
busybox

... and pushes each resulting image string to your remote host where the image is needed. Note that busybox implies busybox:latest by convention.

Start

Run Zabbix like so

docker --context 'fully.qualified.domain.name' compose --project-name "${COMPOSE_PROJECT_NAME}" --file "${UPSTREAM_COMPOSE_FILE}" --env-file "${UPSTREAM_ENV_FILE}" --env-file "${COMPOSE_ENV_FILE}" up --detach

Additional files

  • common-settings.yml

    This file will be auto-created as part of the patch. Use it as an example in case patching fails

  • env/fqdn_context.env.example

    An example env file with all currently used variables after docker-compose_v3_alpine_pgsql_latest.yaml is patched

  • Directory tree underneath build-context

    build-context/
    └── docker-data
        ├── postgres
        │   └── config
        │       ├── cert
        │       │   ├── ZBX_PGSQL_TLS_CA_CERT_FILE
        │       │   ├── ZBX_PGSQL_TLS_CERT_FILE
        │       │   └── ZBX_PGSQL_TLS_KEY_FILE
        │       └── docker-entrypoint-initdb.d
        │           └── init-user-db.sh
        ├── zabbixserver
        │   └── config
        │       └── cert
        │           ├── ZBX_SERVER_TLS_CA_CERT_FILE
        │           ├── ZBX_SERVER_TLS_CERT_FILE
        │           └── ZBX_SERVER_TLS_KEY_FILE
        └── zabbixwebnginx
            └── config
                └── cert
                    ├── dhparam.pem
                    ├── ZBX_WEBNGINX_TLS_CERT_FULLCHAIN_FILE
                    └── ZBX_WEBNGINX_TLS_KEY_FILE
    

    Example data you're going to want to physically place on your deployment machine. SSL certs and keys are blank files each of which has the exact same name used in env file fqdn_context.env.example.

    In postgres/config/docker-entrypoint-initdb.d a PostgreSQL initialization script - when this container is run on a completely empty data directory - will create an additional read-only user ZBX_DB_USERNAME_RO with password ZBX_DB_USERNAME_PW. The example's intended to grant a Grafana daemon direct PostgreSQL database read access.

Upgrade an existing repo

Check Initial setup below for first time steps. On consecutive upgrades proceed as follows.

Revert unpushed local changes

Return repo state to exactly the upstream repo's original branch state throwing away the commits you added.

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' reset --hard origin

Switch to trunk branch, get newest commits from upstream

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' checkout trunk
git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' pull

Pick and checkout new tag

pushd '/opt/git/github.com/zabbix/zabbix-docker/branches/latest'
while IFS= read -r; do commitDate=$(grep -Pio '^.+?(?=[[:space:]])' <<< "${REPLY}"); commitDate=$(date --date='@'"${commitDate}" +%F-%H%M%S); tagRef="$(cut -d $'\t' -f2 <<< "${REPLY}")"; tagName="$(grep -Pio '(?<=refs/tags/)[^\r\n\f]+' <<<"${tagRef}")"; commitHash="$(git rev-list -n 1 "${tagRef}")"; echo "${commitDate} ${commitHash} ${tagName}"; done < <(git for-each-ref --sort=v:refname --format='%(*creatordate:raw)%00%(creatordate:raw)%00%(refname)' refs/tags | awk -F"\0" 'BEGIN {ORS=""} $1 == "" {print $2} $1 != "" {print $1} {print "\t"$3"\n"}')

# Output goes like:
...
2023-03-07-191829 9f2e726e554b23595489eb66c8e11e5d114b573f 6.4.0
2023-04-03-105513 9f16f6d773a2a46f1595c86077899d1e040db283 6.4.1
2023-04-25-133446 0fa87156974e799e04bf99e5300bad6830d754ab 6.4.2
2023-05-30-151931 d7b0eab80723a2c562a13ee866c4cd384af96d3b 6.4.3
2023-06-27-133008 482e21c7803c2878e522aba0325bf04533efa61a 6.4.4
...

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' checkout 'tags/x.y.z'

Lastly apply patch. If patch does not apply cleanly read on in the next section Create new patch to find out how to fix your patch.

Create new patch

Add your changes as commits

Get zabbix-docker repo into a state with which you're happy then

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' format-patch 7665739620ba6d99090838d502ab76d2f5a47e96^..a17380598ca66153ddc2a42eb618d906d4f582e6 --stdout > '/opt/containers/zabbixserver/zabbix-docker.patch'

Where the first commit hash is our first commit and the other commit hash is our last commit. Note the caret (^) right after the first commit hash.

Investigation

You may have to try and find out how a known good base commit differs from a newer one in case the newer one does no longer cleanly accept the patch.

Get commit hashes from both affected tags, e.g.

pushd '/opt/git/github.com/zabbix/zabbix-docker/branches/latest'
while IFS= read -r; do commitDate=$(grep -Pio '^.+?(?=[[:space:]])' <<< "${REPLY}"); commitDate=$(date --date='@'"${commitDate}" +%F-%H%M%S); tagRef="$(cut -d $'\t' -f2 <<< "${REPLY}")"; tagName="$(grep -Pio '(?<=refs/tags/)[^\r\n\f]+' <<<"${tagRef}")"; commitHash="$(git rev-list -n 1 "${tagRef}")"; echo "${commitDate} ${commitHash} ${tagName}"; done < <(git for-each-ref --sort=v:refname --format='%(*creatordate:raw)%00%(creatordate:raw)%00%(refname)' refs/tags | awk -F"\0" 'BEGIN {ORS=""} $1 == "" {print $2} $1 != "" {print $1} {print "\t"$3"\n"}')

# Output goes like:
...
2024-02-01-100454 4d62e7af5cf884763c5e66a5e376a77972fb632f 6.4.11
2024-02-26-142242 a4e950ac473a82c2982ed2ebb5b82e4b2204e78a 6.4.12
2024-03-25-175845 6b85028331f30dcd3440888d846babd12eb01ae2 6.4.13
2024-04-22-124800 7cb4ec29d4c34f006f2c92403022fb32eb778276 6.4.14
2024-05-21-131508 170db44b637acdb37d3c0f7b71d623c5488446e4 6.4.15
...

Diff them

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' diff a4e950ac473a82c2982ed2ebb5b82e4b2204e78a 170db44b637acdb37d3c0f7b71d623c5488446e4 .env env_vars docker-compose_v3_alpine_pgsql_latest.yaml compose_zabbix_components.yaml compose_databases.yaml

Output will be empty in case no difference exists in any of the files between both commit hashes.

Commit your updated patch file into this repo. With a new working patch in hand head back up to Upgrade an existing repo.

Initial setup

Prep

Get desired tag e.g. from version-sorted tags list

pushd '/opt/git/github.com/zabbix/zabbix-docker/branches/latest'
while IFS= read -r; do commitDate=$(grep -Pio '^.+?(?=[[:space:]])' <<< "${REPLY}"); commitDate=$(date --date='@'"${commitDate}" +%F-%H%M%S); tagRef="$(cut -d $'\t' -f2 <<< "${REPLY}")"; tagName="$(grep -Pio '(?<=refs/tags/)[^\r\n\f]+' <<<"${tagRef}")"; commitHash="$(git rev-list -n 1 "${tagRef}")"; echo "${commitDate} ${commitHash} ${tagName}"; done < <(git for-each-ref --sort=v:refname --format='%(*creatordate:raw)%00%(creatordate:raw)%00%(refname)' refs/tags | awk -F"\0" 'BEGIN {ORS=""} $1 == "" {print $2} $1 != "" {print $1} {print "\t"$3"\n"}')

# Output goes like:
...
2024-02-01-100454 4d62e7af5cf884763c5e66a5e376a77972fb632f 6.4.11
2024-02-26-142242 a4e950ac473a82c2982ed2ebb5b82e4b2204e78a 6.4.12
2024-03-25-175845 6b85028331f30dcd3440888d846babd12eb01ae2 6.4.13
2024-04-22-124800 7cb4ec29d4c34f006f2c92403022fb32eb778276 6.4.14
2024-05-21-131508 170db44b637acdb37d3c0f7b71d623c5488446e4 6.4.15
...

Switch to desired tag

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' checkout 'tags/6.4.15'

Apply patch

Identify yourself to the local zabbix-docker repo. Obviously substitute your own name. An e-mail address is optional here. You don't want to contribute upstream, you just want to locally apply a patch file.

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' config user.name "hygienic-books"
git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' config user.email ""

Apply zabbix-docker.patch to Docker Compose file. We use Zabbix' docker-compose_v3_alpine_pgsql_latest.yaml Compose file. Assuming this repo lives at /opt/containers/zabbixserver:

git -C '/opt/git/github.com/zabbix/zabbix-docker/branches/latest' am '/opt/containers/zabbixserver/zabbix-docker.patch'

# Output will be:
Applying: refactor(compose): Remove unneeded components
Applying: refactor(zabbix-server): Set bind mounts
Applying: feat(stack): Extend env vars
Applying: refactor(compose): Remove secrets and unneeded volume
Applying: refactor(zabbix-web-nginx): Exposed ports
...

And now back up to Docker Compose.

Description
Zabbix monitoring in Docker
Readme 86 KiB
Languages
Shell 100%