From 89f2c28046d75cad90ec9988ccc81276755891a0 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 29 Feb 2024 21:56:55 +0000 Subject: [PATCH] Adding support for alpine based image --- Dockerfile.alpine | 51 ++++++++++++++++++++++++++ dockerfiles/pre-setup.sh | 26 +++++++++++++ dockerfiles/setup.sh | 69 +++++++++++++++++++++++++++++++++++ install/pialert.conf.template | 17 +++++++++ 4 files changed, 163 insertions(+) create mode 100644 Dockerfile.alpine create mode 100755 dockerfiles/pre-setup.sh create mode 100755 dockerfiles/setup.sh create mode 100644 install/pialert.conf.template diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 00000000..8cd21153 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,51 @@ +FROM alpine:3.19 as builder + +ARG INSTALL_DIR=/home/pi +ENV PYTHONUNBUFFERED 1 + +RUN apk add --no-cache bash python3 \ + && python -m venv /opt/venv + +# Enable venv +ENV PATH="/opt/venv/bin:$PATH" + +COPY . ${INSTALL_DIR}/pialert/ + +RUN pip install requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet \ + && bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \ + && bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \ + && bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'pialert-cli' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;" + +# second stage +FROM alpine:3.19 as runner + +ARG INSTALL_DIR=/home/pi + +COPY --from=builder /opt/venv /opt/venv + +# Enable venv +ENV PATH="/opt/venv/bin:$PATH" + +# default port and listen address +ENV PORT=20211 LISTEN_ADDR=0.0.0.0 + +# needed for s6-overlay +ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 + +RUN apk update --no-cache \ + && apk add --no-cache bash zip gettext-envsubst sudo mtr usbutils s6-overlay \ + && apk add --no-cache curl arp-scan iproute2 iproute2-ss nmap traceroute net-tools net-snmp-tools bind-tools awake ca-certificates \ + && apk add --no-cache sqlite php82 php82-fpm php82-cgi php82-curl php82-sqlite3 php82-session \ + && apk add --no-cache python3 nginx \ + && ln -s /usr/bin/awake /usr/bin/wakeonlan \ + && bash -c "install -d -m 750 -o nginx -g www-data ${INSTALL_DIR} ${INSTALL_DIR}/pialert" \ + && rm -f /etc/nginx/http.d/default.conf + +COPY --from=builder --chown=nginx:www-data ${INSTALL_DIR}/pialert/ ${INSTALL_DIR}/pialert/ + +RUN /home/pi/pialert/dockerfiles/pre-setup.sh + +HEALTHCHECK --interval=30s --timeout=5s --start-period=0s --retries=2 \ + CMD curl -sf -o /dev/null ${LISTEN_ADDR}:${PORT}/api/app_state.json + +ENTRYPOINT ["/init"] diff --git a/dockerfiles/pre-setup.sh b/dockerfiles/pre-setup.sh new file mode 100755 index 00000000..87b5bea5 --- /dev/null +++ b/dockerfiles/pre-setup.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# php-fpm setup +install -d -o nginx -g www-data /run/php/ +sed -i "/^;pid/c\pid = /run/php/php8.2-fpm.pid" /etc/php82/php-fpm.conf +sed -i "/^listen/c\listen = /run/php/php8.2-fpm.sock" /etc/php82/php-fpm.d/www.conf +sed -i "/^;listen.owner/c\listen.owner = nginx" /etc/php82/php-fpm.d/www.conf +sed -i "/^;listen.group/c\listen.group = www-data" /etc/php82/php-fpm.d/www.conf +sed -i "/^user/c\user = nginx" /etc/php82/php-fpm.d/www.conf +sed -i "/^group/c\group = www-data" /etc/php82/php-fpm.d/www.conf + +# s6 overlay setup +mkdir -p /etc/s6-overlay/s6-rc.d/{SetupOneshot,php-fpm/dependencies.d,nginx/dependencies.d} +mkdir -p /etc/s6-overlay/s6-rc.d/{SetupOneshot,php-fpm/dependencies.d,nginx/dependencies.d,pialert/dependencies.d} +echo "oneshot" > /etc/s6-overlay/s6-rc.d/SetupOneshot/type +echo "longrun" > /etc/s6-overlay/s6-rc.d/php-fpm/type +echo "longrun" > /etc/s6-overlay/s6-rc.d/nginx/type +echo "longrun" > /etc/s6-overlay/s6-rc.d/pialert/type +echo -e "/home/pi/pialert/dockerfiles/setup.sh" > /etc/s6-overlay/s6-rc.d/SetupOneshot/up +echo -e "#!/bin/execlineb -P\n/usr/sbin/php-fpm82 -F" > /etc/s6-overlay/s6-rc.d/php-fpm/run +echo -e '#!/bin/execlineb -P\nnginx -g "daemon off;"' > /etc/s6-overlay/s6-rc.d/nginx/run +echo -e '#!/bin/execlineb -P\n\nwith-contenv\nimportas -i PORT PORT\nif { echo "[INSTALL] 🚀 Starting app - navigate to your :${PORT}" }\npython /home/pi/pialert/pialert' > /etc/s6-overlay/s6-rc.d/pialert/run +touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx} /etc/s6-overlay/s6-rc.d/{php-fpm,nginx}/dependencies.d/SetupOneshot +touch /etc/s6-overlay/s6-rc.d/user/contents.d/{SetupOneshot,php-fpm,nginx,pialert} /etc/s6-overlay/s6-rc.d/{php-fpm,nginx,pialert}/dependencies.d/SetupOneshot +touch /etc/s6-overlay/s6-rc.d/nginx/dependencies.d/php-fpm +touch /etc/s6-overlay/s6-rc.d/pialert/dependencies.d/nginx diff --git a/dockerfiles/setup.sh b/dockerfiles/setup.sh new file mode 100755 index 00000000..b51ac5f2 --- /dev/null +++ b/dockerfiles/setup.sh @@ -0,0 +1,69 @@ +#!/usr/bin/with-contenv bash + +echo "---------------------------------------------------------" +echo "[INSTALL] Run setup.sh" +echo "---------------------------------------------------------" + +export INSTALL_DIR=/home/pi # Specify the installation directory here + +# DO NOT CHANGE ANYTHING BELOW THIS LINE! +NGINX_CONFIG_FILE=/etc/nginx/http.d/pialert.conf +OUI_FILE="/usr/share/arp-scan/ieee-oui.txt" # Define the path to ieee-oui.txt and ieee-iab.txt +FILEDB="${INSTALL_DIR}/pialert/db/pialert.db" +# DO NOT CHANGE ANYTHING ABOVE THIS LINE! + +# Check if script is run as root +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root. Please use 'sudo'." + exit 1 +fi + +echo "[INSTALL] Copy starter pialert.db and pialert.conf if they don't exist" + +# Copy starter pialert.db and pialert.conf if they don't exist +cp -na "${INSTALL_DIR}/pialert/back/pialert.conf" "${INSTALL_DIR}/pialert/config/pialert.conf" +cp -na "${INSTALL_DIR}/pialert/back/pialert.db" "${FILEDB}" + +# if custom variables not set we do not need to do anything +if [ -n "${TZ}" ]; then + FILECONF="${INSTALL_DIR}/pialert/config/pialert.conf" + echo "[INSTALL] Setup timezone" + sed -i "\#^TIMEZONE=#c\TIMEZONE='${TZ}'" "${FILECONF}" +fi + +echo "[INSTALL] Setup NGINX" +echo "Setting webserver to address ($LISTEN_ADDR) and port ($PORT)" +envsubst '$INSTALL_DIR $LISTEN_ADDR $PORT' < "${INSTALL_DIR}/pialert/install/pialert.conf.template" > "${NGINX_CONFIG_FILE}" + +# Run the hardware vendors update at least once +echo "[INSTALL] Run the hardware vendors update" + +# Check if ieee-oui.txt or ieee-iab.txt exist +if [ -f "${OUI_FILE}" ]; then + echo "The file ieee-oui.txt exists. Skipping update_vendors.sh..." +else + echo "The file ieee-oui.txt does not exist. Running update_vendors..." + + # Run the update_vendors.sh script + if [ -f "${INSTALL_DIR}/pialert/back/update_vendors.sh" ]; then + "${INSTALL_DIR}/pialert/back/update_vendors.sh" + else + echo "update_vendors.sh script not found in ${INSTALL_DIR}." + fi +fi + +# Create an empty log files +# Create the execution_queue.log and pialert_front.log files if they don't exist +touch "${INSTALL_DIR}"/pialert/front/log/{execution_queue.log,pialert_front.log,pialert.php_errors.log,stderr.log,stdout.log} + +echo "[INSTALL] Fixing permissions after copied starter config & DB" +chown -R nginx:www-data "${INSTALL_DIR}"/pialert/{config,front/log,db} +chmod 750 "${INSTALL_DIR}"/pialert/{config,front/log,db} +chmod 640 "${INSTALL_DIR}"/pialert/{config,front/log,db}/* + +# Check if buildtimestamp.txt doesn't exist +if [ ! -f "${INSTALL_DIR}/pialert/front/buildtimestamp.txt" ]; then + # Create buildtimestamp.txt + date +%s > "${INSTALL_DIR}/pialert/front/buildtimestamp.txt" + chown nginx:www-data "${INSTALL_DIR}/pialert/front/buildtimestamp.txt" +fi diff --git a/install/pialert.conf.template b/install/pialert.conf.template new file mode 100644 index 00000000..6e71e12b --- /dev/null +++ b/install/pialert.conf.template @@ -0,0 +1,17 @@ +server { + listen ${LISTEN_ADDR}:${PORT} default_server; + root ${INSTALL_DIR}/pialert/front; + index index.php; + add_header X-Forwarded-Prefix "/pialert" always; + proxy_set_header X-Forwarded-Prefix "/pialert"; + + location ~* \.php$ { + fastcgi_pass unix:/run/php/php8.2-fpm.sock; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_connect_timeout 75; + fastcgi_send_timeout 600; + fastcgi_read_timeout 600; + } +}