Move to Alpine linux
Based on https://github.com/sanjeevan/baseimage Image size reduced from 232MB to 90MB Also make the change monitors more like services that restart if they crash
This commit is contained in:
42
60_create_monitors.sh
Executable file
42
60_create_monitors.sh
Executable file
@@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function ts {
|
||||||
|
echo [`date '+%Y-%m-%d %H:%M:%S'`] MASTER:
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "$(ts) Starting master controller"
|
||||||
|
|
||||||
|
if [ -f /config/sample.conf ]; then
|
||||||
|
echo "$(ts) /config/sample.conf exists. Rename it to <monitor name>.conf, check the settings, then rerun the container. Exiting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
readarray -t CONFIG_FILES < <(ls /config/*.conf)
|
||||||
|
|
||||||
|
# If there is no config file copy the default one
|
||||||
|
if [[ "$CONFIG_FILES" == "" ]]
|
||||||
|
then
|
||||||
|
echo "$(ts) Creating sample config file. Rename it to <monitor name>.conf, check the settings, then rerun the container. Exiting."
|
||||||
|
cp /files/sample.conf /config/sample.conf
|
||||||
|
chmod a+w /config/sample.conf
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for CONFIG_FILE in "${CONFIG_FILES[@]}"
|
||||||
|
do
|
||||||
|
FILENAME=$(basename "$CONFIG_FILE")
|
||||||
|
|
||||||
|
echo "$(ts) Creating monitor for $FILENAME"
|
||||||
|
|
||||||
|
FILEBASE="${FILENAME%.*}"
|
||||||
|
|
||||||
|
mkdir -p /etc/service/$FILEBASE
|
||||||
|
|
||||||
|
cat > /etc/service/$FILEBASE/run <<EOF
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
/files/monitor.py "$CONFIG_FILE"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod a+x /etc/service/$FILEBASE/run
|
||||||
|
done
|
||||||
65
Dockerfile
65
Dockerfile
@@ -1,43 +1,40 @@
|
|||||||
FROM phusion/baseimage:0.9.19
|
FROM alpine:3.7
|
||||||
|
|
||||||
MAINTAINER David Coppit <david@coppit.org>
|
MAINTAINER David Coppit <david@coppit.org>
|
||||||
|
|
||||||
|
ENV TERM=xterm-256color
|
||||||
# Use baseimage-docker's init system
|
|
||||||
CMD ["/sbin/my_init"]
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND noninteractive
|
|
||||||
ADD dpkg-excludes /etc/dpkg/dpkg.cfg.d/excludes
|
|
||||||
|
|
||||||
RUN true && \
|
RUN true && \
|
||||||
|
\
|
||||||
|
echo "http://dl-cdn.alpinelinux.org/alpine/v3.7/community" >> /etc/apk/repositories && \
|
||||||
|
apk --update upgrade && \
|
||||||
|
\
|
||||||
|
# Basics, including runit
|
||||||
|
apk add bash curl htop runit && \
|
||||||
|
\
|
||||||
|
# Needed by our code
|
||||||
|
apk add --no-cache python3 icu-libs shadow && \
|
||||||
|
pip3 install watchdog && \
|
||||||
|
wget https://raw.githubusercontent.com/phusion/baseimage-docker/9f998e1a09bdcb228af03595092dbc462f1062d0/image/bin/setuser -O /sbin/setuser && \
|
||||||
|
chmod +x /sbin/setuser && \
|
||||||
|
\
|
||||||
|
rm -rf /var/cache/apk/* && \
|
||||||
|
\
|
||||||
|
# RunIt stuff
|
||||||
|
adduser -h /home/user-service -s /bin/sh -D user-service -u 2000 && \
|
||||||
|
chown user-service:user-service /home/user-service && \
|
||||||
|
mkdir -p /etc/run_once /etc/service
|
||||||
|
|
||||||
set -x && \
|
# Boilerplate startup code
|
||||||
|
COPY ./boot.sh /sbin/boot.sh
|
||||||
# Create dir to keep things tidy. Make sure it's readable by $UID
|
RUN chmod +x /sbin/boot.sh
|
||||||
mkdir /files && \
|
CMD [ "/sbin/boot.sh" ]
|
||||||
chmod a+rwX /files && \
|
|
||||||
|
|
||||||
# Speed up APT
|
|
||||||
echo "force-unsafe-io" > /etc/dpkg/dpkg.cfg.d/02apt-speedup && \
|
|
||||||
echo "Acquire::http {No-Cache=True;};" > /etc/apt/apt.conf.d/no-cache && \
|
|
||||||
|
|
||||||
apt-get update && \
|
|
||||||
apt-get install -qy python3-watchdog wget && \
|
|
||||||
|
|
||||||
# clean up
|
|
||||||
apt-get clean && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
|
|
||||||
/usr/share/man /usr/share/groff /usr/share/info \
|
|
||||||
/usr/share/lintian /usr/share/linda /var/cache/man && \
|
|
||||||
(( find /usr/share/doc -depth -type f ! -name copyright|xargs rm || true )) && \
|
|
||||||
(( find /usr/share/doc -empty|xargs rmdir || true ))
|
|
||||||
|
|
||||||
VOLUME ["/config", \
|
VOLUME ["/config", \
|
||||||
"/dir1", "/dir2", "/dir3", "/dir4", "/dir5", "/dir6", "/dir7", "/dir8", "/dir9", "/dir10", \
|
"/dir1", "/dir2", "/dir3", "/dir4", "/dir5", "/dir6", "/dir7", "/dir8", "/dir9", "/dir10", \
|
||||||
"/dir11", "/dir12", "/dir13", "/dir14", "/dir15", "/dir16", "/dir17", "/dir18", "/dir19", "/dir20"]
|
"/dir11", "/dir12", "/dir13", "/dir14", "/dir15", "/dir16", "/dir17", "/dir18", "/dir19", "/dir20"]
|
||||||
|
|
||||||
# Set the locale, to help Python and the user's applications deal with files that have non-ASCII characters
|
# Set the locale, to help Python and the user's applications deal with files that have non-ASCII characters
|
||||||
RUN locale-gen en_US.UTF-8
|
|
||||||
ENV LANG en_US.UTF-8
|
ENV LANG en_US.UTF-8
|
||||||
ENV LANGUAGE en_US:en
|
ENV LANGUAGE en_US:en
|
||||||
ENV LC_ALL en_US.UTF-8
|
ENV LC_ALL en_US.UTF-8
|
||||||
@@ -45,11 +42,11 @@ ENV LC_ALL en_US.UTF-8
|
|||||||
ENV UMAP ""
|
ENV UMAP ""
|
||||||
ENV GMAP ""
|
ENV GMAP ""
|
||||||
|
|
||||||
# Add local files
|
|
||||||
COPY sample.conf monitor.py runas.sh /files/
|
COPY sample.conf monitor.py runas.sh /files/
|
||||||
|
# Make sure it's readable by $UID
|
||||||
|
RUN chmod a+rwX /files
|
||||||
|
|
||||||
ADD 50_remap_ids.sh /etc/my_init.d/
|
# run-parts ignores files with "." in them
|
||||||
|
ADD 50_remap_ids.sh /etc/run_once/50_remap_ids
|
||||||
RUN mkdir /etc/service/monitor
|
ADD 60_create_monitors.sh /etc/run_once/60_create_monitors
|
||||||
ADD monitor.sh /etc/service/monitor/run
|
RUN chmod +x /etc/run_once/*
|
||||||
RUN chmod +x /etc/service/monitor/run
|
|
||||||
|
|||||||
56
boot.sh
Executable file
56
boot.sh
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Based on https://github.com/sanjeevan/baseimage
|
||||||
|
|
||||||
|
shutdown() {
|
||||||
|
echo
|
||||||
|
echo "Shutting down container..."
|
||||||
|
|
||||||
|
# first shutdown any service started by runit
|
||||||
|
for _srv in $(ls -1 /etc/service); do
|
||||||
|
sv force-stop $_srv
|
||||||
|
done
|
||||||
|
|
||||||
|
# shutdown runsvdir command
|
||||||
|
kill -HUP $RUNSVDIR
|
||||||
|
wait $RUNSVDIR
|
||||||
|
|
||||||
|
# give processes time to stop
|
||||||
|
sleep 0.5
|
||||||
|
|
||||||
|
# kill any other processes still running in the container
|
||||||
|
for _pid in $(ps -eo pid | grep -v PID | tr -d ' ' | grep -v '^1$' | head -n -6); do
|
||||||
|
timeout -t 5 /bin/sh -c "kill $_pid && wait $_pid || kill -9 $_pid"
|
||||||
|
done
|
||||||
|
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
# catch shutdown signals
|
||||||
|
trap shutdown SIGTERM SIGHUP SIGQUIT SIGINT
|
||||||
|
|
||||||
|
# store environment variables
|
||||||
|
export > /etc/envvars
|
||||||
|
|
||||||
|
PATH=/bin:/sbin:/usr/bin
|
||||||
|
|
||||||
|
# run all scripts in the run_once folder
|
||||||
|
if ! /bin/run-parts /etc/run_once
|
||||||
|
then
|
||||||
|
echo "Run-once scripts failed. Stopping container"
|
||||||
|
shutdown
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec env - PATH=$PATH runsvdir -P /etc/service &
|
||||||
|
|
||||||
|
RUNSVDIR=$!
|
||||||
|
echo "Started runsvdir, PID is $RUNSVDIR. Waiting for processes to start...."
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
for _srv in $(ls -1 /etc/service); do
|
||||||
|
sv status $_srv
|
||||||
|
done
|
||||||
|
|
||||||
|
wait $RUNSVDIR
|
||||||
|
|
||||||
|
shutdown
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
path-exclude /usr/share/doc/*
|
|
||||||
# we need to keep copyright files for legal reasons
|
|
||||||
path-include /usr/share/doc/*/copyright
|
|
||||||
path-exclude /usr/share/man/*
|
|
||||||
path-exclude /usr/share/groff/*
|
|
||||||
path-exclude /usr/share/info/*
|
|
||||||
# lintian stuff is small, but really unnecessary
|
|
||||||
path-exclude /usr/share/lintian/*
|
|
||||||
path-exclude /usr/share/linda/*
|
|
||||||
# Drop locales except English
|
|
||||||
path-exclude=/usr/share/locale/*
|
|
||||||
path-include=/usr/share/locale/en/*
|
|
||||||
path-include=/usr/share/locale/locale.alias
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
57
monitor.sh
57
monitor.sh
@@ -1,57 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
function ts {
|
|
||||||
echo [`date '+%Y-%m-%d %H:%M:%S'`] MASTER:
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "$(ts) Starting master controller"
|
|
||||||
|
|
||||||
if [ -f /config/sample.conf ]; then
|
|
||||||
echo "$(ts) /config/sample.conf exists. Rename it, check the settings, then rerun the container. Exiting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
readarray -t CONFIG_FILES < <(ls /config/*.conf)
|
|
||||||
|
|
||||||
# If there is no config file copy the default one
|
|
||||||
if [[ "$CONFIG_FILES" == "" ]]
|
|
||||||
then
|
|
||||||
echo "$(ts) Creating sample config file. Rename it, check the settings, then rerun the container. Exiting."
|
|
||||||
cp /files/sample.conf /config/sample.conf
|
|
||||||
chmod a+w /config/sample.conf
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
PIDS=()
|
|
||||||
|
|
||||||
for CONFIG_FILE in "${CONFIG_FILES[@]}"
|
|
||||||
do
|
|
||||||
echo "$(ts) Launching monitor for $CONFIG_FILE"
|
|
||||||
/files/monitor.py $CONFIG_FILE &
|
|
||||||
PIDS+=($!)
|
|
||||||
done
|
|
||||||
|
|
||||||
# Sleep for a second to allow the monitors to check their config files
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
while true
|
|
||||||
do
|
|
||||||
for ((i = 0; i < ${#PIDS[@]}; i++))
|
|
||||||
do
|
|
||||||
if ps -p ${PIDS[$i]} > /dev/null
|
|
||||||
then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$(ts) Monitor for ${CONFIG_FILES[$i]} has died (PID ${PIDS[$i]}). Killing other monitors and exiting."
|
|
||||||
|
|
||||||
for PID in "${PIDS[@]}"
|
|
||||||
do
|
|
||||||
kill -9 $PID >/dev/null 2>&1
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 2
|
|
||||||
done
|
|
||||||
|
|
||||||
sleep 60
|
|
||||||
done
|
|
||||||
Reference in New Issue
Block a user