Merge pull request #10505 from Icinga/docker-v2

Rework docker images build
This commit is contained in:
Julian Brost 2025-09-15 12:52:29 +02:00 committed by GitHub
commit 2063d2bdbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 583 additions and 36 deletions

32
.github/workflows/container-image.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: Container Image
on:
push:
branches:
- master
pull_request: {}
release:
types:
- published
concurrency:
group: container-image-${{ github.event_name == 'push' && github.sha || github.ref }}
cancel-in-progress: true
jobs:
container-image:
# Required by the base Container Image Action [^1].
# [^1]: https://github.com/Icinga/github-actions/blob/main/.github/workflows/container-image.yml#L54-L58
permissions:
contents: read
packages: write
attestations: write
id-token: write
name: Container Image
uses: icinga/github-actions/.github/workflows/container-image.yml@main
with:
documentation_url: https://icinga.com/docs/icinga2
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}

View File

@ -1,36 +0,0 @@
name: Docker image
on:
pull_request: {}
push:
branches:
- master
release:
types:
- published
concurrency:
group: docker-${{ github.event_name == 'push' && github.sha || github.ref }}
cancel-in-progress: true
jobs:
docker-release:
if: github.event_name == 'release'
concurrency: docker-release
runs-on: ubuntu-latest
steps:
- name: Docker image
uses: Icinga/docker-icinga2@master
with:
dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}'
docker:
if: github.event_name != 'release'
runs-on: ubuntu-latest
steps:
- name: Docker image
uses: Icinga/docker-icinga2@master
with:
dockerhub-token: '${{ secrets.DOCKER_HUB_PERSONAL_TOKEN }}'

225
Containerfile Normal file
View File

@ -0,0 +1,225 @@
# Icinga 2 Docker image | (c) 2025 Icinga GmbH | GPLv2+
FROM debian:trixie-slim AS build-base
# Install all the necessary build dependencies for building Icinga 2 and the plugins.
#
# This stage includes the build dependencies for the plugins as well, so that they can share the same base
# image, since Docker builds common stages only once [^1] even if they are used in multiple build stages.
# This eliminates the need to have a separate base image for the plugins, that basically has kind of the
# same dependencies as the Icinga 2 build stage (ok, not exactly the same, but some of them are shared).
#
# [^1]: https://docs.docker.com/build/building/best-practices/#create-reusable-stages
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y --no-install-recommends --no-install-suggests \
autoconf \
automake \
bison \
ccache \
cmake \
flex \
g++ \
git \
libboost1.83-dev \
libboost-context1.83-dev \
libboost-coroutine1.83-dev \
libboost-date-time1.83-dev \
libboost-filesystem1.83-dev \
libboost-iostreams1.83-dev \
libboost-program-options1.83-dev \
libboost-regex1.83-dev \
libboost-system1.83-dev \
libboost-thread1.83-dev \
libboost-test1.83-dev \
libedit-dev \
libmariadb-dev \
libpq-dev \
libssl-dev \
libsystemd-dev \
make && \
rm -rf /var/lib/apt/lists/*
# Set the default working directory for subsequent commands of the next stages.
WORKDIR /icinga2-build
FROM build-base AS build-plugins
# Install all the plugins that are not included in the monitoring-plugins package.
ADD https://github.com/lausser/check_mssql_health.git#747af4c3c261790341da164b58d84db9c7fa5480 /check_mssql_health
ADD https://github.com/lausser/check_nwc_health.git#a5295475c9bbd6df9fe7432347f7c5aba16b49df /check_nwc_health
ADD https://github.com/bucardo/check_postgres.git#58de936fdfe4073413340cbd9061aa69099f1680 /check_postgres
ADD https://github.com/matteocorti/check_ssl_cert.git#341b5813108fb2367ada81e866da989ea4fb29e7 /check_ssl_cert
WORKDIR /check_mssql_health
RUN mkdir bin && \
autoconf && \
autoreconf && \
./configure "--build=$(uname -m)-unknown-linux-gnu" --libexecdir=/usr/lib/nagios/plugins && \
make && \
make install DESTDIR="$(pwd)/bin"
WORKDIR /check_nwc_health
RUN mkdir bin && \
autoreconf && \
./configure "--build=$(uname -m)-unknown-linux-gnu" --libexecdir=/usr/lib/nagios/plugins && \
make && \
make install DESTDIR="$(pwd)/bin"
WORKDIR /check_postgres
RUN mkdir bin && \
perl Makefile.PL INSTALLSITESCRIPT=/usr/lib/nagios/plugins && \
make && \
make install DESTDIR="$(pwd)/bin" && \
# This is necessary because of this build error: cannot copy to non-directory: /var/lib/docker/.../merged/usr/local/man
rm -rf bin/usr/local/man
FROM build-base AS build-icinga2
# To access the automated build arguments in the Dockerfile originated from the Docker BuildKit [^1],
# we need to declare them here as build arguments. This is necessary because we want to use unique IDs
# for the mount cache below for each platform to avoid conflicts between multi arch builds. Otherwise,
# the build targets will invalidate the cache one another, leading to strange build errors.
#
# [^1]: https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope
ARG TARGETPLATFORM
# Icinga 2 build arguments.
#
# These arguments are used to configure the build of Icinga 2 and can be overridden
# by the user when building the image. All of them have a default value suitable for our official image.
ARG CMAKE_BUILD_TYPE=RelWithDebInfo
ARG ICINGA2_UNITY_BUILD=ON
ARG ICINGA2_BUILD_TESTING=ON
# The number of jobs to run in parallel when building Icinga 2.
# By default, it is set to the number of available CPU cores on the build machine.
ARG MAKE_JOBS=auto
# Create the directory where the final Icinga 2 files will be installed.
#
# This directory will be used as the destination for the `make install` command below and will be
# copied to the final image. Other than that, this directory will not be used for anything else.
RUN mkdir /icinga2-install
# Mount the source code as a bind mount instead of copying it, so that we can use the cache effectively.
# Additionally, add the ccache and CMake build directories as cache mounts to speed up rebuilds.
RUN --mount=type=bind,source=.,target=/icinga2,readonly \
--mount=type=cache,id=ccache-${TARGETPLATFORM},target=/root/.ccache \
--mount=type=cache,id=icinga2-build-${TARGETPLATFORM},target=/icinga2-build \
PATH="/usr/lib/ccache:$PATH" \
cmake -S /icinga2 -B /icinga2-build \
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
# Podman supports forwarding notifications from containers to systemd, so build Icinga 2 with systemd support.
-DUSE_SYSTEMD=ON \
-DBUILD_TESTING=${ICINGA2_BUILD_TESTING} \
-DICINGA2_UNITY_BUILD=${ICINGA2_UNITY_BUILD} \
# The command group name below is required for the prepare-dirs script to work, as it expects
# the command group name, which by default is `icingacmd` to exist on the system. Since we
# don't create the `icingacmd` command group in this image, we need to override it with icinga.
-DICINGA2_COMMAND_GROUP=icinga \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_SYSCONFDIR=/data/etc \
-DCMAKE_INSTALL_LOCALSTATEDIR=/data/var \
-DICINGA2_SYSCONFIGFILE=/etc/sysconfig/icinga2 \
-DICINGA2_RUNDIR=/run \
-DICINGA2_WITH_COMPAT=OFF \
-DICINGA2_WITH_LIVESTATUS=OFF && \
make -j$([ "$MAKE_JOBS" = auto ] && nproc || echo "$MAKE_JOBS") && \
CTEST_OUTPUT_ON_FAILURE=1 make test && \
make install DESTDIR=/icinga2-install
RUN rm -rf /icinga2-install/etc/icinga2/features-enabled/mainlog.conf \
/icinga2-install/usr/share/doc/icinga2/markdown && \
strip -g /icinga2-install/usr/lib/*/icinga2/sbin/icinga2 && \
strip -g /icinga2-install/usr/lib/nagios/plugins/check_nscp_api
# Prepare the final image with the necessary configuration files and runtime dependencies.
FROM debian:trixie-slim AS icinga2
# The real UID of the Icinga user to be used in the final image.
ARG ICINGA_USER_ID=5665
# Install the necessary runtime dependencies for the Icinga 2 binary and the monitoring-plugins.
RUN apt-get update && \
apt-get upgrade -y && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --no-install-suggests \
bc \
ca-certificates \
curl \
dumb-init \
file \
libboost-context1.83.0 \
libboost-coroutine1.83.0 \
libboost-date-time1.83.0 \
libboost-filesystem1.83.0 \
libboost-iostreams1.83.0 \
libboost-program-options1.83.0 \
libboost-regex1.83.0 \
libboost-system1.83.0 \
libboost-thread1.83.0 \
libcap2-bin \
libedit2 \
libldap-common \
libmariadb3 \
libmoosex-role-timer-perl \
libpq5 \
libssl3 \
libsystemd0 \
mailutils \
monitoring-plugins \
msmtp \
msmtp-mta \
openssh-client \
openssl && \
# Official Debian images automatically run `apt-get clean` after every install, so we don't need to do it here.
rm -rf /var/lib/apt/lists/*
# Create the icinga user and group with a specific UID as recommended by Docker best practices.
# The user has a home directory at /var/lib/icinga2, and if configured, that directory will also
# be used to store the ".msmtprc" file created by the entrypoint script.
RUN adduser \
--system \
--group \
--home /var/lib/icinga2 \
--disabled-login \
--no-create-home \
--uid ${ICINGA_USER_ID} icinga
COPY --from=build-plugins /check_mssql_health/bin/ /
COPY --from=build-plugins /check_nwc_health/bin/ /
COPY --from=build-plugins /check_postgres/bin/ /
COPY --from=build-plugins /check_ssl_cert/check_ssl_cert /usr/lib/nagios/plugins/check_ssl_cert
COPY --from=build-icinga2 /icinga2-install/ /
# Create a corresponding symlink in the root filesystem for all Icinga 2 directories in /data.
# This is necessary because we want to maintain the compatibility with containers built with the
# legacy Dockerfile, which expects the Icinga 2 directories to be in the root directory.
RUN for dir in /etc/icinga2 /var/cache/icinga2 /var/lib/icinga2 /var/log/icinga2 /var/spool/icinga2; do \
ln -vs "/data$dir" "$dir"; \
done
# The below prepare-dirs script will not fix any permissions issues for the actuall /var/lib/icinga2 or
# /etc/icinga2 directories, so we need to set the correct ownership for the /data directory recursively.
RUN chown -R icinga:icinga /data
# Run the prepare-dirs script to create non-existing directories and set the correct permissions for them.
# It's invoked in the same way as in the systemd unit file in a Debian package, so this will ensure that
# all the necessary directories are created with the correct permissions and ownership.
RUN /usr/lib/icinga2/prepare-dirs /etc/sysconfig/icinga2
# Well, since the /data directory is intended to be used as a volume, we should also declare it as such.
# This will allow users to mount their own directories or even specific files to the /data directory
# without any issues. We've already filled the /data directory with the necessary configuration files,
# so users can simply mount their own files or directories if they want to override the default ones and
# they will be able to do so without any issues.
VOLUME ["/data"]
COPY --chmod=0755 tools/container/entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/bin/dumb-init", "-c", "--", "/usr/local/bin/entrypoint.sh"]
EXPOSE 5665
USER icinga
CMD ["icinga2", "daemon"]

View File

@ -0,0 +1,184 @@
# Installing Icinga 2 in Containers
To be able to run Icinga 2 in a containerized environment, you'll need to set up a few things.
This guide will help you get started with running Icinga 2 in a container using our official images.
## Prerequisites
- A container runtime such as [Docker](https://www.docker.com) or [Podman](https://podman.io) installed on your system.
- Basic knowledge of how to use Docker or Podman commands.
- A basic understanding of Icinga 2 and its configuration.
## Getting Started
First, create a dedicated docker network for Icinga 2 to ensure that all containers can communicate with each other:
```
docker network create icinga
```
Next, start an Icinga 2 master container using the official Icinga 2 image. By default, all Icinga 2 containers will
listen on port `5665` from within the docker network, but you can expose this port on a different port on your host
system if needed. The following command will start an Icinga 2 master container with the necessary configurations:
```
docker run --detach \
--network icinga \
--name icinga-master \
--hostname icinga-master \
--publish 5665:5665 \
--volume icinga-master:/data \
--env ICINGA_MASTER=1 \
icinga/icinga2
```
This command will run the Icinga 2 master container in detached mode, exposing port 5665 for communication and mounting
the `/data` directory to a persistent volume named `icinga-master`. You can adjust the volume name and other parameters
as needed. You can also set additional environment variables to configure the Icinga 2 instance,
see [Environment Variables](#environment-variables) for a list of available options.
Alternatively, if you're used to using the `icinga2 node wizard` command to set up Icinga 2 nodes, you can still run
the `icinga2 node wizard` command to set up the containers interactively.
```
docker run --rm -it \
--network icinga \
--hostname icinga-master \
--volume icinga-master:/data \
icinga/icinga2 icinga2 node wizard
```
This command will run the Icinga 2 master container in interactive mode, allowing you to answer the prompts from the
`icinga2 node wizard` command.
Another option is to mount all the necessary configuration files from your host system into the container.
This way, you can use your existing Icinga 2 configuration files without needing any additional setup steps.
By default, the container will be populated with the default Icinga 2 configuration files, but you can override
them by creating bind mounts from your host system to the respective directories in the container. For example, to
replace the default `api-users.conf` file with your own one, you can start the Icinga 2 master container with the
following command:
```
docker run --detach \
--network icinga \
--name icinga-master \
--hostname icinga-master \
--publish 5665:5665 \
--volume icinga-master:/data \
--mount=type=bind,source=/absolute/path/to/your/api-users.conf,target=/data/etc/icinga2/conf.d/api-users.conf \
--env ICINGA_MASTER=1 \
icinga/icinga2
```
> **Note**
>
> If you [mount an empty](https://docs.docker.com/engine/storage/bind-mounts/#mount-into-a-non-empty-directory-on-the-container)
> directory from your host into the container's `/data` directory using `--volume /path/to/empty-directory:/data`,
> all files in `/data` inside the container will be obscured. The container may not start correctly because its
> important files are no longer visible. This happens because Docker replaces the container's `/data` directory with
> your empty host directory. To avoid this, either use `--mount` to bind only specific files or subdirectories, or
> use `--volume` with a named volume (like `icinga-master:/data`) so the container's default files are preserved and
> only your specified files are replaced.
## Adding Icinga 2 Agents
To add Icinga 2 agents to your setup, you can run additional containers for each agent. In order your agents be able
to successfully connect to the master, they need to have a copy of the master's `ca.crt` file created during the master
setup. You can first copy this file from the master container to your host system using the following command:
```
docker cp icinga-master:/var/lib/icinga2/certs/ca.crt icinga-ca.crt
```
If you didn't use `icinga-master` as the name of your master container, replace it with the actual name you used.
For easier setup, you may want to also obtain a `ticket` from the master container, which will allow the agent to
authenticate itself without needing you to manually sign a certificate signing request (CSR).
You can create a ticket for the agent by running the following command on your host system:
```
docker exec icinga-master icinga2 pki ticket --cn icinga-agent > icinga-agent.ticket
```
Again, replace `icinga-master` with the actual name of your master container if necessary. Additionally, you may want
to adjust the `--cn` parameter to match the hostname of your agent containers. For non-ticket based setups, the required
steps are described in the [On-Demand CSR Signing](https://icinga.com/docs/icinga-2/latest/doc/06-distributed-monitoring/#on-demand-csr-signing)
section of the Icinga 2 documentation. So, we won't cover that here.
Now, you can start an Icinga 2 agent container using the following command:
```
docker run --detach \
--network icinga \
--name icinga-agent \
--hostname icinga-agent \
--volume icinga-agent:/data \
--env ICINGA_ZONE=icinga-agent \
--env ICINGA_ENDPOINT=icinga-master,icinga-master,5665 \
--env ICINGA_CACERT="$(< icinga-ca.crt)" \
--env ICINGA_TICKET="$(< icinga-agent.ticket)" \
icinga/icinga2
```
This command will run the Icinga 2 agent container in detached mode, mounting the `/data` directory to a persistent
volume named `icinga-agent`. As with the master container, you can adjust the volume name and other parameters as
needed. The environment variables will be processed by the container's entrypoint script and perform a `icinga2 node setup`
on your behalf, configuring the agent to connect to the master.
You can repeat this step for each additional agent you want to add, ensuring that each agent has a unique hostname and
zone name.
## Icinga 2 API
By default, if the `icinga2 node setup` command is run when starting the container, the Icinga 2 API will be enabled,
and it will use a default API user named `root` with a randomly generated password. If you want to use your own API
users and passwords, you can bind mount your api-users file from your host system into the
`/data/etc/icinga2/conf.d/api-users.conf` in the container as described in the [Getting Started](#getting-started)
section.
## Notifications
By default, Icinga 2 does not send notifications when running in a containerized environment. However, it is possible
to enable mail notifications by configuring [msmtp](https://wiki.archlinux.org/title/Msmtp) client in the container.
The binary is already included in the official Icinga 2 container image, so it just needs to be configured. In order
to do this, you can either mount the `/etc/msmtprc` file from your host system into the container or provide the
necessary configuration for the `~icinga/.msmtprc` file via the `MSMTPRC` environment variable.
## Environment Variables
Most of the environment variables are used as parameters for the `icinga2 node setup` command. If you set any of these
variables, and the `node setup` has not been run yet, the entrypoint script will automatically run the command for you.
The following environment variables are available:
| Variable | Node setup CLI |
|----------------------------------------------------------|---------------------------------------------------------------|
| `ICINGA_ACCEPT_COMMANDS=1` | `--accept-commands` |
| `ICINGA_ACCEPT_CONFIG=1` | `--accept-config` |
| `ICINGA_DISABLE_CONFD=1` | `--disable-confd` |
| `ICINGA_MASTER=1` | `--master` |
| `ICINGA_CN=icinga-master` | `--cn icinga-master` |
| `ICINGA_ENDPOINT=icinga-master,2001:db8::192.0.2.9,5665` | `--endpoint icinga-master,2001:db8::192.0.2.9,5665` |
| `ICINGA_GLOBAL_ZONES=global-config,global-commands` | `--global_zones global-config --global_zones global-commands` |
| `ICINGA_LISTEN=::,5665` | `--listen ::,5665` |
| `ICINGA_PARENT_HOST=2001:db8::192.0.2.9,5665` | `--parent_host 2001:db8::192.0.2.9,5665` |
| `ICINGA_PARENT_ZONE=master` | `--parent_zone master` |
| `ICINGA_TICKET=0123456789abcdef0123456789abcdef01234567` | `--ticket 0123456789abcdef0123456789abcdef01234567` |
| `ICINGA_ZONE=master` | `--zone master` |
Special variables:
* `ICINGA_TRUSTEDCERT`'s value is written to a temporary file in the container, which is then used
as the `--trustedcert` parameter for the `icinga2 node setup` command.
* `ICINGA_CACERT`'s value is directly written to the `/var/lib/icinga2/certs/ca.crt` file in the container.
## Build Your Own Image
If you want to build your own Icinga 2 container image, you can clone the Icinga 2 repository and build the image
using the provided `Containerfile`.
```
git clone https://github.com/Icinga/icinga2.git
cd icinga2
docker build --tag icinga/icinga2:test --file Containerfile .
```

142
tools/container/entrypoint.sh Executable file
View File

@ -0,0 +1,142 @@
#!/bin/bash
set -eo pipefail
# Function to display messages with different severity levels
# Usage: icinga2_log <severity> <message>
icinga2_log() {
local severity="$1"
local message="$2"
local color=""
local reset=""
# Check if we are running in a terminal that supports colors,
# otherwise fallback to plain text output.
if [ -t 2 ]; then
reset="\033[0m"
# Set color codes based on severity
case "$severity" in
"information")
color="\033[32m" # Green
;;
"warning")
color="\033[1;33m" # Yellow bold
;;
"critical")
color="\033[1;31m" # Red bold
;;
esac
fi
# Print the message with the appropriate color and reset code to stderr
echo -e "[$(date +'%Y-%m-%d %H:%M:%S %z')] ${color}${severity}${reset}/DockerEntrypoint: ${message}" >&2
}
# The entrypoint script expects at least one command to run.
if [ $# -eq 0 ]; then
icinga2_log "critical" "Icinga 2 Docker entrypoint script requires at least one command to run."
exit 1
fi
icinga2_log "information" "Icinga 2 Docker entrypoint script started."
ca="/var/lib/icinga2/certs/ca.crt"
if [ ! -e "$ca" ]; then
nodeSetup=("node" "setup")
runNodeSetup=false
# The following loop looks for environment variables that start with ICINGA_ and applies some transformations
# to the keys before processing them in one way or another. Their values are never modified or printed in
# unintended ways. The key transformations have the following rules and are applied in the order they are listed:
#
# - Since it only processes environment variables that start with ICINGA_, it'll first strip that prefix.
# It then passes the key through awk to convert it to lowercase e.g. ICINGA_CN becomes cn.
# - For each key, that hits one of the cases below, it will be processed a bit differently. In the first match,
# the environment variable is expected to be a boolean (1 or 0) and it only becomes part of the node setup
# command if and only if its value is 1. In that case, underscores in the key are replaced with dashes and
# passed as-is to the node setup command (e.g., ICINGA_ACCEPT_COMMANDS=1 becomes --accept-commands).
# - The second case matches exclusively on the "global_zones" key. The value of this environment variable
# is expected to be one or comma-separated list of zones. If the value is not empty, it will be split by
# commas and each zone will be passed as a separate argument to the node setup command
# (e.g., ICINGA_GLOBAL_ZONES=icinga,example becomes --global_zones icinga --global_zones example).
# - For the third match, the key is expected to be a key-value pair that should be passed to the node setup
# command. In this case, key and value pairs are passed as-is to the node setup command (e.g.,
# ICINGA_CN=icinga.example.com becomes --cn icinga.example.com).
# - For the fourth match, the trusted certificate is expected to be a PEM-encoded certificate that should be
# written to a temporary file and passed to the node setup command.
# - Lastly, the CA certificate is likewise expected to be a PEM-encoded certificate that should be written to
# the expected location at /var/lib/icinga2/certs/ca.crt.
#
# When encountering an environment variable prefixed with ICINGA_ that we don't know how to handle, we log it
# as an informational message and continue processing the next environment variable but it doesn't cause the
# script to fail.
for k in "${!ICINGA_@}"; do
# Strip the ICINGA_ prefix and convert the key to lowercase.
key=$(echo "${k#ICINGA_}" | awk '{print tolower($0)}')
# Get the value of the environment variable.
value="${!k}"
case "$key" in
"accept_commands" | "accept_config" | "disable_confd" | "master")
runNodeSetup=true
if [ "$value" = "1" ]; then
nodeSetup+=("--${key//_/-}")
fi
;;
"global_zones")
runNodeSetup=true
# Split the value by commas and pass each part as a separate argument.
IFS=',' read -ra zones <<< "$value"
for zone in "${zones[@]}"; do
nodeSetup+=("--global_zones" "$zone")
done
;;
"cn" | "endpoint" | "listen" | "parent_host" | "parent_zone" | "zone" | "ticket")
runNodeSetup=true
nodeSetup+=("--$key" "$value")
;;
"trustedcert")
icinga2_log "information" "Writing trusted certificate to temporary file."
runNodeSetup=true
trustedCertFile=$(mktemp /tmp/trusted.cert.XXXXXXXX)
printf "%s" "$value" > "$trustedCertFile"
nodeSetup+=("--$key" "$trustedCertFile")
chmod 0644 "$trustedCertFile"
;;
"cacert")
icinga2_log "information" "Writing CA certificate to $ca."
runNodeSetup=true
printf "%s" "$value" > "$ca"
chmod 0644 "$ca"
;;
*)
# We don't know how to handle this environment variable, so log it and move on.
icinga2_log "warning" "Ignoring unknown environment variable $k"
;;
esac
done
if [ "$runNodeSetup" = true ]; then
icinga2_log "information" "Running Icinga 2 node setup command..."
icinga2 "${nodeSetup[@]}"
# If the node setup command wasn't successful, we shouldn't reach this point due to set -e.
icinga2_log "information" "Node setup completed successfully."
else
icinga2_log "information" "No node setup required based on environment variables."
fi
fi
msmtprc_path="/var/lib/icinga2/.msmtprc"
# This script should initialize the container's msmtp configuration but never overwrite an existing configuration file.
# If the file already exists, it should not be modified, even if the MSMTPRC environment variable is set.
if [ ! -e "$msmtprc_path" ] && [ -n "${MSMTPRC}" ]; then
icinga2_log "information" "Configuring msmtp with the provided MSMTPRC environment variable."
printf "%s" "$MSMTPRC" > "$msmtprc_path"
chmod 0644 "$msmtprc_path"
fi
icinga2_log "information" "Starting Icinga 2 daemon."
exec "$@"