icinga2/Containerfile
2025-09-10 15:15:00 +02:00

226 lines
9.7 KiB
Docker

# 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"]