1
0
Fork 0
mirror of https://github.com/librenms/docker.git synced 2026-01-23 02:14:48 +00:00

Run as non-root user (#6)

Switch to s6-overlay as process supervisor
Prevent exposing Nginx and PHP version
Bind to unprivileged port (8000)
Remove php-fpm access log (already mirrored by nginx)
This commit is contained in:
CrazyMax 2019-11-19 14:09:34 +01:00
parent fbb387d0da
commit 3a92d62e86
No known key found for this signature in database
GPG key ID: 3248E46B6BB8C7F7
27 changed files with 377 additions and 332 deletions

11
.gitignore vendored
View file

@ -1,9 +1,4 @@
# Jetbrains
/.idea
/*.iml
# Visual Studio Code
/.vscode
# App
/.dev
/.idea
/.vscode
/*.iml

View file

@ -1,5 +1,22 @@
# Changelog
## 1.57-RC2 (2019/11/19)
* :warning: Run as non-root user (#6)
* Switch to [s6-overlay](https://github.com/just-containers/s6-overlay/) as process supervisor
* Prevent exposing Nginx and PHP version
* :warning: Bind to unprivileged port (8000)
* Remove php-fpm access log (already mirrored by nginx)
> :warning: **UPGRADE NOTES**
> As the Docker container now runs as a non-root user, you have to first stop the container and change permissions to `data` volume:
> ```
> docker-compose stop
> chown -R ${PUID}:${PGID} data/
> docker-compose pull
> docker-compose up -d
> ```
## 1.57-RC1 (2019/10/30)
* LibreNMS 1.57

View file

@ -70,7 +70,7 @@ RUN apk --update --no-cache add \
rrdtool \
runit \
shadow \
supervisor \
su-exec \
syslog-ng \
ttf-dejavu \
tzdata \
@ -80,6 +80,8 @@ RUN apk --update --no-cache add \
&& pip2 install python-memcached \
&& pip3 install --upgrade pip \
&& pip3 install python-memcached \
&& wget -q "https://github.com/just-containers/s6-overlay/releases/latest/download/s6-overlay-amd64.tar.gz" -qO "/tmp/s6-overlay-amd64.tar.gz" \
&& tar xzf /tmp/s6-overlay-amd64.tar.gz -C / \
&& sed -i -e "s/;date\.timezone.*/date\.timezone = UTC/" /etc/php7/php.ini \
&& rm -rf /var/cache/apk/* /var/www/* /tmp/* \
&& setcap cap_net_raw+ep /usr/bin/nmap \
@ -87,39 +89,34 @@ RUN apk --update --no-cache add \
ENV LIBRENMS_VERSION="1.57" \
LIBRENMS_PATH="/opt/librenms" \
DATA_PATH="/data" \
CRONTAB_PATH="/var/spool/cron/crontabs"
PUID="1000" \
PGID="1000" \
S6_BEHAVIOUR_IF_STAGE2_FAILS="2"
RUN mkdir -p /opt \
&& addgroup -g 1000 librenms \
&& adduser -u 1000 -G librenms -h ${LIBRENMS_PATH} -s /bin/sh -D librenms \
&& passwd -l librenms \
&& usermod -a -G librenms nginx \
&& curl -sSL https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer \
&& git clone --branch ${LIBRENMS_VERSION} https://github.com/librenms/librenms.git ${LIBRENMS_PATH} \
&& chown -R librenms. ${LIBRENMS_PATH} \
&& su - librenms -c "composer install --no-dev --no-interaction --no-ansi --working-dir=${LIBRENMS_PATH}" \
&& composer install --no-dev --no-interaction --no-ansi --working-dir=${LIBRENMS_PATH} \
&& curl -sSLk -q https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro -o /usr/bin/distro \
&& chmod +x /usr/bin/distro \
&& mkdir -p /data ${LIBRENMS_PATH}/config.d /var/log/supervisord \
&& mkdir -p ${LIBRENMS_PATH}/config.d \
&& cp ${LIBRENMS_PATH}/config.php.default ${LIBRENMS_PATH}/config.php \
&& cp ${LIBRENMS_PATH}/snmpd.conf.example /etc/snmp/snmpd.conf \
&& sed -i "1s|.*|#!/usr/bin/env python3|" ${LIBRENMS_PATH}/snmp-scan.py \
&& echo "foreach (glob(\"${DATA_PATH}/config/*.php\") as \$filename) include \$filename;" >> ${LIBRENMS_PATH}/config.php \
&& echo "foreach (glob(\"/data/config/*.php\") as \$filename) include \$filename;" >> ${LIBRENMS_PATH}/config.php \
&& echo "foreach (glob(\"${LIBRENMS_PATH}/config.d/*.php\") as \$filename) include \$filename;" >> ${LIBRENMS_PATH}/config.php \
&& chown -R librenms. ${DATA_PATH} ${LIBRENMS_PATH} \
&& chown -R nginx. /var/lib/nginx /var/log/nginx /var/log/php7 /var/tmp/nginx \
&& pip3 install -r ${LIBRENMS_PATH}/requirements.txt \
&& chown -R nobody.nogroup ${LIBRENMS_PATH} \
&& rm -rf /tmp/*
COPY entrypoint.sh /entrypoint.sh
COPY assets /
RUN chmod a+x /entrypoint.sh /usr/local/bin/*
RUN addgroup -g ${PGID} librenms \
&& adduser -D -h ${LIBRENMS_PATH} -u ${PUID} -G librenms -s /bin/sh -D librenms \
&& mkdir -p /data /var/run/nginx /var/run/php-fpm
EXPOSE 80 514 514/udp
EXPOSE 8000 514 514/udp
WORKDIR ${LIBRENMS_PATH}
VOLUME [ "${DATA_PATH}" ]
VOLUME [ "/data" ]
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/usr/bin/supervisord", "-c", "/etc/supervisord.conf" ]
ENTRYPOINT [ "/init" ]

View file

@ -20,11 +20,13 @@ It's a fork of [CrazyMax's LibreNMS Docker image repository](https://github.com/
## Features
* Run as non-root user
* Cron tasks as a ["sidecar" container](doc/notes/crons.md)
* Syslog-ng support through a ["sidecar" container](doc/notes/syslog-ng.md)
* Ability to configure [distributed polling](https://docs.librenms.org/#Extensions/Distributed-Poller/#distributed-poller)
* Ability to add custom Monitoring plugins (Nagios)
* OPCache enabled to store precompiled script bytecode in shared memory
* [s6-overlay](https://github.com/just-containers/s6-overlay/) as process supervisor
* [Traefik](https://github.com/containous/traefik-library-image) as reverse proxy and creation/renewal of Let's Encrypt certificates (see [this template](examples/traefik))
* [Memcached](https://github.com/docker-library/memcached) image ready to use for better scalability
* [RRDcached](https://github.com/crazy-max/docker-rrdcached) image ready to use for better scalability

View file

@ -0,0 +1,4 @@
#!/usr/bin/with-contenv sh
# Fix access rights to stdout and stderr
chown ${PUID}:${PGID} /proc/self/fd/1 /proc/self/fd/2

View file

@ -0,0 +1,11 @@
#!/usr/bin/with-contenv sh
if [ -n "${PGID}" ] && [ "${PGID}" != "$(id -g librenms)" ]; then
echo "Switching to PGID ${PGID}..."
sed -i -e "s/^librenms:\([^:]*\):[0-9]*/librenms:\1:${PGID}/" /etc/group
sed -i -e "s/^librenms:\([^:]*\):\([0-9]*\):[0-9]*/librenms:\1:\2:${PGID}/" /etc/passwd
fi
if [ -n "${PUID}" ] && [ "${PUID}" != "$(id -u librenms)" ]; then
echo "Switching to PUID ${PUID}..."
sed -i -e "s/^librenms:\([^:]*\):[0-9]*:\([0-9]*\)/librenms:\1:${PUID}:\2/" /etc/passwd
fi

View file

@ -0,0 +1,14 @@
#!/usr/bin/with-contenv sh
echo "Fixing perms..."
chown librenms. \
/data \
"${LIBRENMS_PATH}"
chown -R librenms. \
/tpls \
/var/lib/nginx \
/var/log/nginx \
/var/log/php7 \
/var/run/nginx \
/var/run/php-fpm \
/var/tmp/nginx

View file

@ -1,47 +1,4 @@
#!/bin/bash
function runas_librenms() {
su - librenms -s /bin/sh -c "$1"
}
TZ=${TZ:-UTC}
PUID=${PUID:-1000}
PGID=${PGID:-1000}
MEMORY_LIMIT=${MEMORY_LIMIT:-256M}
UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE:-16M}
OPCACHE_MEM_SIZE=${OPCACHE_MEM_SIZE:-128}
REAL_IP_FROM=${REAL_IP_FROM:-"0.0.0.0/32"}
REAL_IP_HEADER=${REAL_IP_HEADER:-"X-Forwarded-For"}
LOG_IP_VAR=${LOG_IP_VAR:-remote_addr}
LIBRENMS_POLLER_THREADS=${LIBRENMS_POLLER_THREADS:-16}
LIBRENMS_POLLER_INTERVAL=${LIBRENMS_POLLER_INTERVAL:-5}
LIBRENMS_DISTRIBUTED_POLLER_ENABLE=${LIBRENMS_DISTRIBUTED_POLLER_ENABLE:-false}
LIBRENMS_DISTRIBUTED_POLLER_NAME=${LIBRENMS_DISTRIBUTED_POLLER_NAME:-$(hostname -f)}
LIBRENMS_DISTRIBUTED_POLLER_GROUP=${LIBRENMS_DISTRIBUTED_POLLER_GROUP:-'0'}
LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST:-${MEMCACHED_HOST}}
LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT:-${MEMCACHED_PORT}}
SIDECAR_CRON=${SIDECAR_CRON:-0}
LIBRENMS_CRON_DISCOVERY_ENABLE=${LIBRENMS_CRON_DISCOVERY_ENABLE:-true}
LIBRENMS_CRON_DAILY_ENABLE=${LIBRENMS_CRON_DAILY_ENABLE:-true}
LIBRENMS_CRON_ALERTS_ENABLE=${LIBRENMS_CRON_ALERTS_ENABLE:-true}
LIBRENMS_CRON_BILLING_ENABLE=${LIBRENMS_CRON_BILLING_ENABLE:-true}
LIBRENMS_CRON_BILLING_CALCULATE_ENABLE=${LIBRENMS_CRON_BILLING_CALCULATE_ENABLE:-true}
LIBRENMS_CRON_CHECK_SERVICES_ENABLE=${LIBRENMS_CRON_CHECK_SERVICES_ENABLE:-true}
LIBRENMS_CRON_POLLER_ENABLE=${LIBRENMS_CRON_POLLER_ENABLE:-true}
SIDECAR_SYSLOGNG=${SIDECAR_SYSLOGNG:-0}
DB_PORT=${DB_PORT:-3306}
DB_NAME=${DB_NAME:-librenms}
DB_USER=${DB_USER:-librenms}
DB_TIMEOUT=${DB_TIMEOUT:-30}
MEMCACHED_PORT=${MEMCACHED_PORT:-11211}
RRDCACHED_PORT=${RRDCACHED_PORT:-42217}
#!/usr/bin/with-contenv bash
# From https://github.com/docker-library/mariadb/blob/master/docker-entrypoint.sh#L21-L41
# usage: file_env VAR [DEFAULT]
@ -66,21 +23,29 @@ file_env() {
unset "$fileVar"
}
# Timezone
echo "Setting timezone to ${TZ}..."
ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime
echo ${TZ} > /etc/timezone
sed -i -e "s|date\.timezone.*|date\.timezone = ${TZ}|" /etc/php7/php.ini \
MEMORY_LIMIT=${MEMORY_LIMIT:-256M}
UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE:-16M}
OPCACHE_MEM_SIZE=${OPCACHE_MEM_SIZE:-128}
REAL_IP_FROM=${REAL_IP_FROM:-"0.0.0.0/32"}
REAL_IP_HEADER=${REAL_IP_HEADER:-"X-Forwarded-For"}
LOG_IP_VAR=${LOG_IP_VAR:-remote_addr}
# Change librenms UID / GID
echo "Checking if librenms UID / GID has changed..."
if [ -n "${PGID}" ] && [ "${PGID}" != "`id -g librenms`" ]; then
sed -i -e "s/^librenms:\([^:]*\):[0-9]*/librenms:\1:${PGID}/" /etc/group
sed -i -e "s/^librenms:\([^:]*\):\([0-9]*\):[0-9]*/librenms:\1:\2:${PGID}/" /etc/passwd
fi
if [ -n "${PUID}" ] && [ "${PUID}" != "`id -u librenms`" ]; then
sed -i -e "s/^librenms:\([^:]*\):[0-9]*:\([0-9]*\)/librenms:\1:${PUID}:\2/" /etc/passwd
fi
LIBRENMS_DISTRIBUTED_POLLER_ENABLE=${LIBRENMS_DISTRIBUTED_POLLER_ENABLE:-false}
LIBRENMS_DISTRIBUTED_POLLER_NAME=${LIBRENMS_DISTRIBUTED_POLLER_NAME:-$(hostname -f)}
LIBRENMS_DISTRIBUTED_POLLER_GROUP=${LIBRENMS_DISTRIBUTED_POLLER_GROUP:-'0'}
LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST:-${MEMCACHED_HOST}}
LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT=${LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT:-${MEMCACHED_PORT}}
DB_PORT=${DB_PORT:-3306}
DB_NAME=${DB_NAME:-librenms}
DB_USER=${DB_USER:-librenms}
DB_TIMEOUT=${DB_TIMEOUT:-30}
MEMCACHED_PORT=${MEMCACHED_PORT:-11211}
RRDCACHED_PORT=${RRDCACHED_PORT:-42217}
SIDECAR_CRON=${SIDECAR_CRON:-0}
SIDECAR_SYSLOGNG=${SIDECAR_SYSLOGNG:-0}
# PHP
echo "Setting PHP-FPM configuration..."
@ -110,10 +75,8 @@ sed -i -e "s/RANDOMSTRINGGOESHERE/${LIBRENMS_SNMP_COMMUNITY}/" /etc/snmp/snmpd.c
# Init files and folders
echo "Initializing LibreNMS files / folders..."
mkdir -p ${DATA_PATH}/config \
${DATA_PATH}/logs \
${DATA_PATH}/monitoring-plugins \
${DATA_PATH}/rrd
mkdir -p /data/config /data/logs /data/monitoring-plugins /data/rrd
rm -rf ${LIBRENMS_PATH}/logs
rm -f ${LIBRENMS_PATH}/config.d/*
echo "Setting LibreNMS configuration..."
@ -122,9 +85,10 @@ echo "Setting LibreNMS configuration..."
cat > ${LIBRENMS_PATH}/config.d/directories.php <<EOL
<?php
\$config['install_dir'] = '${LIBRENMS_PATH}';
\$config['log_dir'] = '${DATA_PATH}/logs';
\$config['rrd_dir'] = '${DATA_PATH}/rrd';
\$config['log_dir'] = '/data/logs';
\$config['rrd_dir'] = '/data/rrd';
EOL
ln -sf /data/logs ${LIBRENMS_PATH}/logs
# Config : Database
if [ -z "$DB_HOST" ]; then
@ -144,8 +108,6 @@ cat > ${LIBRENMS_PATH}/config.d/database.php <<EOL
\$config['db_pass'] = '${DB_PASSWORD}';
\$config['db_name'] = '${DB_NAME}';
EOL
dbcmd="mysql -h ${DB_HOST} -P ${DB_PORT} -u "${DB_USER}" "-p${DB_PASSWORD}""
unset DB_PASSWORD
# Config : User
cat > ${LIBRENMS_PATH}/config.d/user.php <<EOL
@ -213,23 +175,14 @@ EOL
fi
# Fix perms
echo "Fixing permissions..."
chown librenms. ${DATA_PATH}/config \
${DATA_PATH}/logs \
${DATA_PATH}/monitoring-plugins \
${DATA_PATH}/rrd
chown -R librenms. ${LIBRENMS_PATH}/config.d \
${LIBRENMS_PATH}/bootstrap \
${LIBRENMS_PATH}/storage
chmod ug+rw ${DATA_PATH}/logs \
${DATA_PATH}/rrd \
${LIBRENMS_PATH}/bootstrap/cache \
${LIBRENMS_PATH}/storage \
${LIBRENMS_PATH}/storage/framework/*
echo "Fixing perms..."
chown librenms. /data/config /data/monitoring-plugins /data/rrd
chown -R librenms. /data/logs ${LIBRENMS_PATH}/config.d ${LIBRENMS_PATH}/bootstrap ${LIBRENMS_PATH}/logs ${LIBRENMS_PATH}/storage
chmod ug+rw /data/logs /data/rrd ${LIBRENMS_PATH}/bootstrap/cache ${LIBRENMS_PATH}/storage ${LIBRENMS_PATH}/storage/framework/*
# Check additional Monitoring plugins
echo "Checking additional Monitoring plugins..."
mon_plugins=$(ls -l ${DATA_PATH}/monitoring-plugins | egrep '^-' | awk '{print $9}')
mon_plugins=$(ls -l /data/monitoring-plugins | egrep '^-' | awk '{print $9}')
for mon_plugin in ${mon_plugins}; do
if [ -f "/usr/lib/monitoring-plugins/${mon_plugin}" ]; then
echo " WARNING: Official Monitoring plugin ${mon_plugin} cannot be overriden. Skipping..."
@ -239,104 +192,10 @@ for mon_plugin in ${mon_plugins}; do
echo " WARNING: Monitoring plugin filename ${mon_plugin} invalid. It must start with 'check_'. Skipping..."
continue
fi
if [[ ! -x "${DATA_PATH}/monitoring-plugins/${mon_plugin}" ]]; then
if [[ ! -x "/data/monitoring-plugins/${mon_plugin}" ]]; then
echo " WARNING: Monitoring plugin file ${mon_plugin} has to be executable. Skipping..."
continue
fi
echo " Adding ${mon_plugin} Monitoring plugin"
ln -sf ${DATA_PATH}/monitoring-plugins/${mon_plugin} /usr/lib/monitoring-plugins/${mon_plugin}
ln -sf /data/monitoring-plugins/${mon_plugin} /usr/lib/monitoring-plugins/${mon_plugin}
done
# Sidecar cron container
if [ "$SIDECAR_CRON" = "1" ]; then
echo ">>"
echo ">> Sidecar cron container detected"
echo ">>"
# Init
rm /etc/supervisord/nginx.conf /etc/supervisord/php.conf /etc/supervisord/snmpd.conf /etc/supervisord/syslog-ng.conf
if [ -z "$CRONTAB_PATH" ]; then
>&2 echo "ERROR: CRONTAB_PATH must be defined"
exit 1
fi
rm -rf ${CRONTAB_PATH}
mkdir -m 0644 -p ${CRONTAB_PATH}
touch ${CRONTAB_PATH}/librenms
# Add crontab
cat ${LIBRENMS_PATH}/librenms.nonroot.cron > ${CRONTAB_PATH}/librenms
sed -i -e "s/ librenms //" ${CRONTAB_PATH}/librenms
if [ $LIBRENMS_CRON_DISCOVERY_ENABLE != true ]; then
sed -i "/discovery.php/d" ${CRONTAB_PATH}/librenms
fi
if [ $LIBRENMS_CRON_DAILY_ENABLE != true ]; then
sed -i "/daily.sh/d" ${CRONTAB_PATH}/librenms
fi
if [ $LIBRENMS_CRON_ALERTS_ENABLE != true ]; then
sed -i "/alerts.php/d" ${CRONTAB_PATH}/librenms
fi
if [ $LIBRENMS_CRON_BILLING_ENABLE != true ]; then
sed -i "/poll-billing.php/d" ${CRONTAB_PATH}/librenms
fi
if [ $LIBRENMS_CRON_BILLING_CALCULATE_ENABLE != true ]; then
sed -i "/billing-calculate.php/d" ${CRONTAB_PATH}/librenms
fi
if [ $LIBRENMS_CRON_CHECK_SERVICES_ENABLE != true ]; then
sed -i "/check-services.php/d" ${CRONTAB_PATH}/librenms
fi
sed -i "/poller-wrapper.py/d" ${CRONTAB_PATH}/librenms
if [ $LIBRENMS_CRON_POLLER_ENABLE = true ]; then
cat >> ${CRONTAB_PATH}/librenms <<EOL
*/${LIBRENMS_POLLER_INTERVAL} * * * * /opt/librenms/cronic /opt/librenms/poller-wrapper.py ${LIBRENMS_POLLER_THREADS}
EOL
fi
# Fix crontab perms
echo "Fixing crontab permissions..."
chmod -R 0644 ${CRONTAB_PATH}
elif [ "$SIDECAR_SYSLOGNG" = "1" ]; then
echo ">>"
echo ">> Sidecar syslog-ng container detected"
echo ">>"
# Init
rm /etc/supervisord/cron.conf /etc/supervisord/nginx.conf /etc/supervisord/php.conf /etc/supervisord/snmpd.conf
mkdir -p ${DATA_PATH}/syslog-ng /run/syslog-ng
chown librenms. ${DATA_PATH}/syslog-ng
chown -R librenms. /run/syslog-ng
else
# Init
rm /etc/supervisord/cron.conf /etc/supervisord/syslog-ng.conf
echo "Waiting ${DB_TIMEOUT}s for database to be ready..."
counter=1
while ! ${dbcmd} -e "show databases;" > /dev/null 2>&1; do
sleep 1
counter=$((counter + 1))
if [ ${counter} -gt ${DB_TIMEOUT} ]; then
>&2 echo "ERROR: Failed to connect to database on $DB_HOST"
exit 1
fi;
done
echo "Database ready!"
counttables=$(echo 'SHOW TABLES' | ${dbcmd} "$DB_NAME" | wc -l)
echo "Updating database schema..."
runas_librenms "php build-base.php"
if [ "${counttables}" -eq "0" ]; then
echo "Creating admin user..."
runas_librenms "php adduser.php librenms librenms 10 librenms@librenms.docker"
fi
fi
exec "$@"

View file

@ -0,0 +1,92 @@
#!/usr/bin/with-contenv bash
# From https://github.com/docker-library/mariadb/blob/master/docker-entrypoint.sh#L21-L41
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
DB_PORT=${DB_PORT:-3306}
DB_NAME=${DB_NAME:-librenms}
DB_USER=${DB_USER:-librenms}
DB_TIMEOUT=${DB_TIMEOUT:-60}
SIDECAR_CRON=${SIDECAR_CRON:-0}
SIDECAR_SYSLOGNG=${SIDECAR_SYSLOGNG:-0}
if [ "$SIDECAR_CRON" = "1" ] || [ "$SIDECAR_SYSLOGNG" = "1" ]; then
exit 0
fi
file_env 'DB_PASSWORD'
if [ -z "$DB_PASSWORD" ]; then
>&2 echo "ERROR: Either DB_PASSWORD or DB_PASSWORD_FILE must be defined"
exit 1
fi
dbcmd="mysql -h ${DB_HOST} -P ${DB_PORT} -u "${DB_USER}" "-p${DB_PASSWORD}""
unset DB_PASSWORD
echo "Waiting ${DB_TIMEOUT}s for database to be ready..."
counter=1
while ! ${dbcmd} -e "show databases;" > /dev/null 2>&1; do
sleep 1
counter=$((counter + 1))
if [ ${counter} -gt ${DB_TIMEOUT} ]; then
>&2 echo "ERROR: Failed to connect to database on $DB_HOST"
exit 1
fi;
done
echo "Database ready!"
counttables=$(echo 'SHOW TABLES' | ${dbcmd} "$DB_NAME" | wc -l)
echo "Updating database schema..."
su-exec librenms:librenms php build-base.php
if [ "${counttables}" -eq "0" ]; then
echo "Creating admin user..."
su-exec librenms:librenms php adduser.php librenms librenms 10 librenms@librenms.docker
fi
mkdir -p /etc/services.d/nginx
cat > /etc/services.d/nginx/run <<EOL
#!/usr/bin/execlineb -P
with-contenv
s6-setuidgid ${PUID}:${PGID}
nginx -g "daemon off;"
EOL
chmod +x /etc/services.d/nginx/run
mkdir -p /etc/services.d/php-fpm
cat > /etc/services.d/php-fpm/run <<EOL
#!/usr/bin/execlineb -P
with-contenv
s6-setuidgid ${PUID}:${PGID}
php-fpm7 -F
EOL
chmod +x /etc/services.d/php-fpm/run
mkdir -p /etc/services.d/snmpd
cat > /etc/services.d/snmpd/run <<EOL
#!/usr/bin/execlineb -P
with-contenv
/usr/sbin/snmpd -f -c /etc/snmp/snmpd.conf
EOL
chmod +x /etc/services.d/snmpd/run

View file

@ -0,0 +1,97 @@
#!/usr/bin/with-contenv sh
CRONTAB_PATH="/var/spool/cron/crontabs"
SIDECAR_CRON=${SIDECAR_CRON:-0}
LIBRENMS_POLLER_THREADS=${LIBRENMS_POLLER_THREADS:-16}
LIBRENMS_POLLER_INTERVAL=${LIBRENMS_POLLER_INTERVAL:-5}
LIBRENMS_CRON_DISCOVERY_ENABLE=${LIBRENMS_CRON_DISCOVERY_ENABLE:-true}
LIBRENMS_CRON_DAILY_ENABLE=${LIBRENMS_CRON_DAILY_ENABLE:-true}
LIBRENMS_CRON_ALERTS_ENABLE=${LIBRENMS_CRON_ALERTS_ENABLE:-true}
LIBRENMS_CRON_BILLING_ENABLE=${LIBRENMS_CRON_BILLING_ENABLE:-true}
LIBRENMS_CRON_BILLING_CALCULATE_ENABLE=${LIBRENMS_CRON_BILLING_CALCULATE_ENABLE:-true}
LIBRENMS_CRON_CHECK_SERVICES_ENABLE=${LIBRENMS_CRON_CHECK_SERVICES_ENABLE:-true}
LIBRENMS_CRON_POLLER_ENABLE=${LIBRENMS_CRON_POLLER_ENABLE:-true}
# Continue only if sidecar cron container
if [ "$SIDECAR_CRON" != "1" ]; then
exit 0
fi
echo ">>"
echo ">> Sidecar cron container detected"
echo ">>"
rm -rf ${CRONTAB_PATH}
mkdir -m 0644 -p ${CRONTAB_PATH}
touch ${CRONTAB_PATH}/librenms
# Add crontab
cat "${LIBRENMS_PATH}/librenms.nonroot.cron" > ${CRONTAB_PATH}/librenms
sed -i -e "s/ librenms //" ${CRONTAB_PATH}/librenms
if [ "$LIBRENMS_CRON_DISCOVERY_ENABLE" != "true" ]; then
echo "Disable discovery cron"
sed -i "/discovery.php/d" ${CRONTAB_PATH}/librenms
else
echo "Enable discovery cron"
fi
if [ "$LIBRENMS_CRON_DAILY_ENABLE" != "true" ]; then
echo "Disable daily script cron"
sed -i "/daily.sh/d" ${CRONTAB_PATH}/librenms
else
echo "Enable daily script cron"
fi
if [ "$LIBRENMS_CRON_ALERTS_ENABLE" != "true" ]; then
echo "Disable alerts generation cron"
sed -i "/alerts.php/d" ${CRONTAB_PATH}/librenms
else
echo "Enable alerts generation cron"
fi
if [ "$LIBRENMS_CRON_BILLING_ENABLE" != "true" ]; then
echo "Disable billing polling cron"
sed -i "/poll-billing.php/d" ${CRONTAB_PATH}/librenms
else
echo "Enable billing polling cron"
fi
if [ "$LIBRENMS_CRON_BILLING_CALCULATE_ENABLE" != "true" ]; then
echo "Disable billing cron"
sed -i "/billing-calculate.php/d" ${CRONTAB_PATH}/librenms
else
echo "Enable billing cron"
fi
if [ "$LIBRENMS_CRON_CHECK_SERVICES_ENABLE" != "true" ]; then
echo "Disable service checks cron"
sed -i "/check-services.php/d" ${CRONTAB_PATH}/librenms
else
echo "Enable service checks cron"
fi
sed -i "/poller-wrapper.py/d" ${CRONTAB_PATH}/librenms
if [ "$LIBRENMS_CRON_POLLER_ENABLE" = "true" ]; then
echo "Enable polling cron"
cat >> ${CRONTAB_PATH}/librenms <<EOL
*/${LIBRENMS_POLLER_INTERVAL} * * * * /opt/librenms/cronic /opt/librenms/poller-wrapper.py ${LIBRENMS_POLLER_THREADS}
EOL
else
echo "Disable polling cron"
fi
# Fix perms
echo "Fixing crontabs permissions..."
chmod -R 0644 ${CRONTAB_PATH}
# Create service
mkdir -p /etc/services.d/cron
cat > /etc/services.d/cron/run <<EOL
#!/usr/bin/execlineb -P
with-contenv
exec busybox crond -f -L /dev/stdout
EOL
chmod +x /etc/services.d/cron/run

View file

@ -0,0 +1,25 @@
#!/usr/bin/with-contenv sh
SIDECAR_SYSLOGNG=${SIDECAR_SYSLOGNG:-0}
# Continue only if sidecar syslogng container
if [ "$SIDECAR_SYSLOGNG" != "1" ]; then
exit 0
fi
echo ">>"
echo ">> Sidecar syslog-ng container detected"
echo ">>"
mkdir -p /data/syslog-ng /run/syslog-ng
chown librenms. /data/syslog-ng
chown -R librenms. /run/syslog-ng
# Create service
mkdir -p /etc/services.d/syslogng
cat > /etc/services.d/syslogng/run <<EOL
#!/usr/bin/execlineb -P
with-contenv
/usr/sbin/syslog-ng -F
EOL
chmod +x /etc/services.d/syslogng/run

View file

@ -1,21 +0,0 @@
[supervisord]
nodaemon = true
user = root
logfile = /var/log/supervisord/supervisord.log
pidfile = /var/run/supervisord.pid
childlogdir = /var/log/supervisord/
logfile_maxbytes = 50MB
logfile_backups = 10
loglevel = info
[supervisorctl]
serverurl = unix:///var/run/supervisor.sock
[unix_http_server]
file = /var/run/supervisor.sock
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[include]
files = /etc/supervisord/*.conf

View file

@ -1,6 +0,0 @@
[program:cron]
command = /usr/local/bin/cron
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0

View file

@ -1,8 +0,0 @@
[program:nginx]
command = /usr/sbin/nginx
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
autorestart = false
startentries = 0

View file

@ -1,8 +0,0 @@
[program:php]
command = /usr/sbin/php-fpm7
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
autorestart = false
startentries = 0

View file

@ -1,7 +0,0 @@
[program:snmpd]
command = /usr/sbin/snmpd -f -c /etc/snmp/snmpd.conf
startentries = 0
stdout_logfile = /proc/1/fd/1
stdout_logfile_maxbytes = 0
stderr_logfile = /proc/1/fd/2
stderr_logfile_maxbytes = 0

View file

@ -1,6 +0,0 @@
[program:syslog-ng]
command = /usr/sbin/syslog-ng -F
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0

View file

@ -1,4 +1,4 @@
@version:3.13
@version:3.19
options {
chain_hostnames(off);

View file

@ -1,8 +1,6 @@
daemon off;
user nginx;
pid /run/nginx.pid;
pid /var/run/nginx/nginx.pid;
worker_processes auto;
error_log /proc/1/fd/2 info;
error_log /proc/self/fd/2 info;
worker_rlimit_nofile 8192;
events {
@ -37,7 +35,7 @@ http {
log_format main '$@LOG_IP_VAR@ - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /proc/1/fd/1 main;
access_log /proc/self/fd/1 main;
## Hide the Nginx version number
server_tokens off;
@ -61,8 +59,8 @@ http {
gzip_static on;
server {
listen 80;
listen [::]:80;
listen 8000;
listen [::]:8000;
root /opt/librenms/html;
index index.php;
@ -80,10 +78,11 @@ http {
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SERVER_SOFTWARE "";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php-fpm7.sock;
fastcgi_pass unix:/var/run/php-fpm/php-fpm7.sock;
fastcgi_buffers 256 4k;
fastcgi_intercept_errors on;
fastcgi_read_timeout 14400;

View file

@ -1,14 +1,11 @@
[global]
pid = /var/run/php-fpm/php-fpm7.pid
daemonize = no
error_log = /proc/self/fd/2
[www]
user = librenms
group = librenms
listen = /run/php-fpm7.sock
listen.owner = librenms
listen.group = librenms
listen = /var/run/php-fpm/php-fpm7.sock
access.log = /dev/null
pm = dynamic
pm.max_children = 15
@ -17,12 +14,9 @@ pm.min_spare_servers = 1
pm.max_spare_servers = 6
request_terminate_timeout = 0
; if we send this to /proc/self/fd/1, it never appears
access.log = /proc/self/fd/2
php_admin_value[post_max_size] = @UPLOAD_MAX_SIZE@
php_admin_value[upload_max_filesize] = @UPLOAD_MAX_SIZE@
php_admin_value[max_execution_time] = 10800
php_admin_value[max_input_time] = 3600
php_admin_value[expose_php] = Off
php_admin_value[memory_limit] = @MEMORY_LIMIT@
php_admin_value[memory_limit] = @MEMORY_LIMIT@

View file

@ -1,5 +0,0 @@
#!/bin/sh
set -e
exec busybox crond -f -L /dev/stdout

View file

@ -2,58 +2,58 @@
### General
* `TZ` : The timezone assigned to the container (default `UTC`)
* `PUID` : LibreNMS user id (default `1000`)
* `TZ`: The timezone assigned to the container (default `UTC`)
* `PUID`: LibreNMS user id (default `1000`)
* `PGID`: LibreNMS group id (default `1000`)
* `MEMORY_LIMIT` : PHP memory limit (default `256M`)
* `UPLOAD_MAX_SIZE` : Upload max size (default `16M`)
* `OPCACHE_MEM_SIZE` : PHP OpCache memory consumption (default `128`)
* `REAL_IP_FROM` : Trusted addresses that are known to send correct replacement addresses (default `0.0.0.0/32`)
* `REAL_IP_HEADER` : Request header field whose value will be used to replace the client address (default `X-Forwarded-For`)
* `LOG_IP_VAR` : Use another variable to retrieve the remote IP address for access [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format) on Nginx. (default `remote_addr`)
* `MEMORY_LIMIT`: PHP memory limit (default `256M`)
* `UPLOAD_MAX_SIZE`: Upload max size (default `16M`)
* `OPCACHE_MEM_SIZE`: PHP OpCache memory consumption (default `128`)
* `REAL_IP_FROM`: Trusted addresses that are known to send correct replacement addresses (default `0.0.0.0/32`)
* `REAL_IP_HEADER`: Request header field whose value will be used to replace the client address (default `X-Forwarded-For`)
* `LOG_IP_VAR`: Use another variable to retrieve the remote IP address for access [log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html#log_format) on Nginx. (default `remote_addr`)
### (Distributed) Poller
* `LIBRENMS_POLLER_THREADS` : Threads that `poller-wrapper.py` runs (default `16`)
* `LIBRENMS_POLLER_INTERVAL` : Interval in minutes at which `poller-wrapper.py` runs (defaults to `5`) [docs](https://docs.librenms.org/#Support/1-Minute-Polling/)
* `LIBRENMS_DISTRIBUTED_POLLER_ENABLE` : Enable distributed poller functionality
* `LIBRENMS_DISTRIBUTED_POLLER_NAME` : Optional name of poller (defaults to hostname)
* `LIBRENMS_DISTRIBUTED_POLLER_GROUP` : By default, all hosts are shared and have the poller_group = 0. To pin a device to a poller, set it to a value greater than 0 and set the same value here. One can also specify a comma separated string of poller groups. The poller will then poll devices from any of the groups listed. [docs](https://docs.librenms.org/#Extensions/Distributed-Poller/#distributed-poller)
* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST` : Memcached server for poller synchronization (Defaults to `$MEMCACHED_HOST`)
* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT` : Port of memcached server (Defaults to `$MEMCACHED_PORT`)
* `LIBRENMS_POLLER_THREADS`: Threads that `poller-wrapper.py` runs (default `16`)
* `LIBRENMS_POLLER_INTERVAL`: Interval in minutes at which `poller-wrapper.py` runs (defaults to `5`) [docs](https://docs.librenms.org/#Support/1-Minute-Polling/)
* `LIBRENMS_DISTRIBUTED_POLLER_ENABLE`: Enable distributed poller functionality
* `LIBRENMS_DISTRIBUTED_POLLER_NAME`: Optional name of poller (defaults to hostname)
* `LIBRENMS_DISTRIBUTED_POLLER_GROUP`: By default, all hosts are shared and have the poller_group = 0. To pin a device to a poller, set it to a value greater than 0 and set the same value here. One can also specify a comma separated string of poller groups. The poller will then poll devices from any of the groups listed. [docs](https://docs.librenms.org/#Extensions/Distributed-Poller/#distributed-poller)
* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_HOST`: Memcached server for poller synchronization (Defaults to `$MEMCACHED_HOST`)
* `LIBRENMS_DISTRIBUTED_POLLER_MEMCACHED_PORT`: Port of memcached server (Defaults to `$MEMCACHED_PORT`)
### Cron
> :warning: Only used if you enabled and run a [sidecar cron container](../notes/crons.md)
* `SIDECAR_CRON` : Set to `1` to enable sidecar cron mode for this container (default `0`)
* `LIBRENMS_CRON_DISCOVERY_ENABLE` : Enable LibreNMS discovery for this container cronjobs (default `true`)
* `LIBRENMS_CRON_DAILY_ENABLE` : Enable LibreNMS daily script for this container cronjobs (default `true`)
* `LIBRENMS_CRON_ALERTS_ENABLE` : Enable LibreNMS alerts generation for this container cronjobs (default `true`)
* `LIBRENMS_CRON_BILLING_ENABLE` : Enable LibreNMS billing polling for this container cronjobs (default `true`)
* `LIBRENMS_CRON_BILLING_CALCULATE_ENABLE` : Enable LibreNMS billing for this container cronjobs (default `true`)
* `LIBRENMS_CRON_CHECK_SERVICES_ENABLE` : Enable LibreNMS service checks for this container cronjobs (default `true`)
* `LIBRENMS_CRON_POLLER_ENABLE` : Enable LibreNMS polling for this container cronjobs (default `true`)
* `SIDECAR_CRON`: Set to `1` to enable sidecar cron mode for this container (default `0`)
* `LIBRENMS_CRON_DISCOVERY_ENABLE`: Enable LibreNMS discovery for this container cronjobs (default `true`)
* `LIBRENMS_CRON_DAILY_ENABLE`: Enable LibreNMS daily script for this container cronjobs (default `true`)
* `LIBRENMS_CRON_ALERTS_ENABLE`: Enable LibreNMS alerts generation for this container cronjobs (default `true`)
* `LIBRENMS_CRON_BILLING_ENABLE`: Enable LibreNMS billing polling for this container cronjobs (default `true`)
* `LIBRENMS_CRON_BILLING_CALCULATE_ENABLE`: Enable LibreNMS billing for this container cronjobs (default `true`)
* `LIBRENMS_CRON_CHECK_SERVICES_ENABLE`: Enable LibreNMS service checks for this container cronjobs (default `true`)
* `LIBRENMS_CRON_POLLER_ENABLE`: Enable LibreNMS polling for this container cronjobs (default `true`)
### Syslog-ng
> :warning: Only used if you enabled and run a [sidecar syslog-ng container](../notes/syslog-ng.md)
* `SIDECAR_SYSLOGNG` : Set to `1` to enable sidecar syslog-ng mode for this container (default `0`)
* `SIDECAR_SYSLOGNG`: Set to `1` to enable sidecar syslog-ng mode for this container (default `0`)
### Database
* `DB_HOST` : MySQL database hostname / IP address
* `DB_PORT` : MySQL database port (default `3306`)
* `DB_NAME` : MySQL database name (default `librenms`)
* `DB_USER` : MySQL user (default `librenms`)
* `DB_PASSWORD` : MySQL password (default `librenms`)
* `DB_TIMEOUT` : Time in seconds after which we stop trying to reach the MySQL server (useful for clusters, default `30`)
* `DB_HOST`: MySQL database hostname / IP address
* `DB_PORT`: MySQL database port (default `3306`)
* `DB_NAME`: MySQL database name (default `librenms`)
* `DB_USER`: MySQL user (default `librenms`)
* `DB_PASSWORD`: MySQL password (default `librenms`)
* `DB_TIMEOUT`: Time in seconds after which we stop trying to reach the MySQL server (useful for clusters, default `60`)
### Misc
* `LIBRENMS_SNMP_COMMUNITY` : This container's SNMP v2c community string (default `librenmsdocker`)
* `MEMCACHED_HOST` : Hostname / IP address of a Memcached server
* `MEMCACHED_PORT` : Port of the Memcached server (default `11211`)
* `RRDCACHED_HOST` : Hostname / IP address of a RRDcached server
* `RRDCACHED_PORT` : Port of the RRDcached server (default `42217`)
* `LIBRENMS_SNMP_COMMUNITY`: This container's SNMP v2c community string (default `librenmsdocker`)
* `MEMCACHED_HOST`: Hostname / IP address of a Memcached server
* `MEMCACHED_PORT`: Port of the Memcached server (default `11211`)
* `RRDCACHED_HOST`: Hostname / IP address of a RRDcached server
* `RRDCACHED_PORT`: Port of the RRDcached server (default `42217`)

View file

@ -1,4 +1,4 @@
### Ports
* `80` : HTTP port
* `514 514/udp` : Syslog ports (only used if you enabled and run a [sidecar syslog-ng container](../notes/syslog-ng.md))
* `8000`: HTTP port
* `514 514/udp`: Syslog ports (only used if you enabled and run a [sidecar syslog-ng container](../notes/syslog-ng.md))

View file

@ -1,5 +1,5 @@
## Volumes
* `/data` : Contains configuration, rrd database, logs, additional Monitoring plugins, additional syslog-ng config files
* `/data`: Contains configuration, rrd database, logs, additional Monitoring plugins, additional syslog-ng config files
> :warning: Note that the volume should be owned by the user/group with the specified `PUID` and `PGID`. If you dont give the volume correct permissions, the container may not start.
> :warning: Note that the volume should be owned by the user/group with the specified `PUID` and `PGID`. If you don't give the volume correct permissions, the container may not start.

View file

@ -14,7 +14,7 @@ docker-compose logs -f
You can also use the following minimal command :
```bash
docker run -d -p 80:80 --name librenms \
docker run -d -p 8000:8000 --name librenms \
-v $(pwd)/data:/data \
-e "DB_HOST=db" \
librenms/librenms:latest

View file

@ -61,8 +61,8 @@ services:
domainname: example.com
hostname: librenms
ports:
- target: 80
published: 80
- target: 8000
published: 8000
protocol: tcp
depends_on:
- db
@ -79,7 +79,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
env_file:
- "./librenms.env"
restart: always
@ -101,7 +101,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
- "SIDECAR_CRON=1"
env_file:
- "./librenms.env"
@ -131,7 +131,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
- "SIDECAR_SYSLOGNG=1"
env_file:
- "./librenms.env"

View file

@ -101,7 +101,7 @@ services:
labels:
- "traefik.enable=true"
- "traefik.backend=librenms"
- "traefik.port=80"
- "traefik.port=8000"
- "traefik.frontend.rule=Host:librenms.example.com"
environment:
- "TZ=${TZ}"
@ -111,7 +111,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
env_file:
- "./librenms.env"
restart: always
@ -133,7 +133,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
- "SIDECAR_CRON=1"
env_file:
- "./librenms.env"
@ -163,7 +163,7 @@ services:
- "DB_NAME=${MYSQL_DATABASE}"
- "DB_USER=${MYSQL_USER}"
- "DB_PASSWORD=${MYSQL_PASSWORD}"
- "DB_TIMEOUT=30"
- "DB_TIMEOUT=60"
- "SIDECAR_SYSLOGNG=1"
env_file:
- "./librenms.env"