diff --git a/.env.scripts b/.env.scripts index 3d5ac37..5ce9da7 100644 --- a/.env.scripts +++ b/.env.scripts @@ -1,4 +1,4 @@ -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - ##@Version : 202509161146-git # @@Author : CasjaysDev # @@Contact : CasjaysDev @@ -7,54 +7,77 @@ # @@Created : Tue Sep 16 11:46:10 AM EDT 2025 # @@File : .env.scripts # @@Description : Variables for gen-dockerfile and buildx scripts -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# @@Changelog : newScript +# @@TODO : Refactor code +# @@Other : N/A +# @@Resource : N/A +# @@Terminal App : yes +# @@sudo/root : yes +# @@Template : templates/dockerfiles/dotenv.template +# - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329 +# - - - - - - - - - - - - - - - - - - - - - - - - - # entrypoint Settings DOCKER_ENTYPOINT_PORTS_WEB="${DOCKER_ENTYPOINT_PORTS_WEB}" DOCKER_ENTYPOINT_PORTS_SRV="${DOCKER_ENTYPOINT_PORTS_SRV}" DOCKER_ENTYPOINT_HEALTH_APPS="$DOCKER_ENTYPOINT_HEALTH_APPS" DOCKER_ENTYPOINT_HEALTH_ENDPOINTS="$DOCKER_ENTYPOINT_HEALTH_ENDPOINTS" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - # Dockerfile info ENV_DOCKERFILE="Dockerfile" -ENV_IMAGE_NAME="ampache" +# ENV_REGISTRY_REPO: Registry repository/image name +ENV_REGISTRY_REPO="ampache" ENV_USE_TEMPLATE="alpine" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - # Maintainer info -ENV_ORG_NAME="casjaysdevdocker" +ENV_REGISTRY_ORG="casjaysdevdocker" ENV_VENDOR="CasjaysDev" ENV_AUTHOR="CasjaysDev" ENV_MAINTAINER="CasjaysDev " -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# REPO info +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Repository URLs (Full URLs) +# ENV_GIT_REPO_URL: Complete Git repository URL for source code ENV_GIT_REPO_URL="https://github.com/casjaysdevdocker/ampache" -ENV_REGISTRY_URL="docker.io" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Push image info -ENV_IMAGE_PUSH="casjaysdevdocker/ampache" +# ENV_REGISTRY_URL: Registry provider base URL (for example https://docker.io) +ENV_REGISTRY_URL="https://docker.io" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Push Configuration +# ENV_REGISTRY_PUSH: Complete push destination derived from registry/org/repo +ENV_REGISTRY_PUSH="casjaysdevdocker/ampache" +# ENV_IMAGE_TAG: Default tag for the image ENV_IMAGE_TAG="latest" +# ENV_ADD_TAGS: Additional tags, comma-separated (USE_DATE = auto date tag) ENV_ADD_TAGS="USE_DATE" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Additional push destinations (if needed) ENV_ADD_IMAGE_PUSH="" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Pull image info +# - - - - - - - - - - - - - - - - - - - - - - - - - +# Pull Configuration +# ENV_PULL_URL: Source image to pull from (base image) ENV_PULL_URL="casjaysdev/alpine" +# ENV_DISTRO_TAG: Tag for the pull source image ENV_DISTRO_TAG="${IMAGE_VERSION}" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - # Env SERVICE_PORT="80" EXPOSE_PORTS="" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - +# IF using a lanuage such as go, php, rust, ruby, etc set the version here. +LANG_VERSION="" +# - - - - - - - - - - - - - - - - - - - - - - - - - # Versions PHP_VERSION="php84" NODE_VERSION="system" NODE_MANAGER="system" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - # Default directories WWW_ROOT_DIR="/usr/local/share/httpd/default" DEFAULT_FILE_DIR="/usr/local/share/template-files" DEFAULT_DATA_DIR="/usr/local/share/template-files/data" DEFAULT_CONF_DIR="/usr/local/share/template-files/config" DEFAULT_TEMPLATE_DIR="/usr/local/share/template-files/defaults" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ENV_PACKAGES="mariadb-server-utils mariadb-client mariadb pwgen apache2 apache2-ctl apache2-lua apache2-ssl apache2-ldap apache2-icons apache2-http2 apache2-error apache2-proxy apache2-brotli apache2-webdav apache2-mod-wsgi apache-mod-fcgid apache2-proxy-html composer php84-bcmath php84-bz2 php84-calendar php84-cgi php84-common php84-ctype php84-curl php84-dba php84-dev php84-doc php84-dom php84-embed php84-enchant php84-exif php84-ffi php84-fileinfo php84-fpm php84-ftp php84-gd php84-gettext php84-gmp php84-iconv php84-imap php84-intl php84-ldap php84-litespeed php84-mbstring php84-mysqli php84-mysqlnd php84-odbc php84-opcache php84-openssl php84-pcntl php84-pdo php84-pdo_dblib php84-pdo_mysql php84-pdo_odbc php84-pdo_pgsql php84-pdo_sqlite php84-pear php84-pgsql php84-phar php84-phpdbg php84-posix php84-pspell php84-session php84-shmop php84-simplexml php84-snmp php84-soap php84-sockets php84-sodium php84-sqlite3 php84-sysvmsg php84-sysvsem php84-sysvshm php84-tidy php84-tokenizer php84-xml php84-xmlreader php84-xmlwriter php84-xsl php84-zip php84-pecl-memcached php84-pecl-mcrypt php84-pecl-mongodb php84-pecl-redis" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - +ENV_PACKAGES="bash tini curl wget unzip tar gzip tzdata ca-certificates pwgen mariadb mariadb-client mariadb-server-utils apache2 apache2-ctl apache2-utils apache2-ssl apache2-proxy apache2-http2 apache2-brotli apache2-icons apache2-error php84 php84-fpm php84-common php84-ctype php84-pdo php84-pdo_mysql php84-mysqli php84-mysqlnd php84-session php84-intl php84-curl php84-simplexml php84-xml php84-xmlreader php84-xmlwriter php84-dom php84-mbstring php84-iconv php84-tokenizer php84-fileinfo php84-openssl php84-phar php84-gd php84-zip php84-bz2 php84-gmp php84-exif php84-opcache php84-pecl-redis" +# - - - - - - - - - - - - - - - - - - - - - - - - - +# ex: ts=2 sw=2 et filetype=sh +# - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitattributes b/.gitattributes index 4a549a9..07f3b95 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -# Template generated on Thu Sep 4 10:41:50 PM EDT 2025 from https://github.com/alexkaratarakis/gitattributes" +# Template generated on Sat Nov 29 11:57:12 AM EST 2025 from https://github.com/alexkaratarakis/gitattributes" # Common settings that generally should always be used with your language specific settings # Auto detect text files and perform LF normalization * text=auto diff --git a/.gitea/workflows/docker.yaml b/.gitea/workflows/docker.yaml new file mode 100644 index 0000000..8982ab3 --- /dev/null +++ b/.gitea/workflows/docker.yaml @@ -0,0 +1,68 @@ +name: ampache + +on: push + +jobs: + release-ampache: + runs-on: act_runner + container: + image: catthehacker/ubuntu:act-latest + env: + RUNNER_TOOL_CACHE: /toolcache + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Get Meta + id: meta + run: | + repo_version="$(git describe --tags --always)" + repo_version="${repo_version#v}" + docker_org="${GITHUB_REPOSITORY%%/*}" + repo_name="${GITHUB_REPOSITORY#*/}" + repo_name="${repo_name#docker-}" + docker_tag="${DOCKER_TAG:-latest}" + docker_hub="${DOCKER_HUB:-docker.io}" + printf 'DATE_TAG=%s\n' "$(date +'%y%m')" >> "$GITHUB_OUTPUT" + printf 'REPO_VERSION=%s\n' "$repo_version" >> "$GITHUB_OUTPUT" + printf 'DOCKER_ORG=%s\n' "$docker_org" >> "$GITHUB_OUTPUT" + printf 'DOCKER_TAG=%s\n' "$docker_tag" >> "$GITHUB_OUTPUT" + printf 'DOCKER_HUB=%s\n' "$docker_hub" >> "$GITHUB_OUTPUT" + printf 'REPO_NAME=%s\n' "$repo_name" >> "$GITHUB_OUTPUT" + printf '%s\n' "$docker_hub/$docker_org/$repo_name:$docker_tag" + + - name: Set up Docker BuildX + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + password: ${{ secrets.DOCKER_TOKEN }} + username: ${{ secrets.DOCKER_USERNAME }} + registry: ${{ steps.meta.outputs.DOCKER_HUB }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + context: . + file: ./Dockerfile + platforms: | + linux/amd64 + linux/arm64 + push: true + build-args: | + IMAGE_NAME=${{ steps.meta.outputs.REPO_NAME }} + BUILD_DATE=$(date -u +'%Y%m%d%H%M') + BUILD_VERSION=$(date -u +'%Y%m%d%H%M') + GIT_COMMIT=${{ github.sha }} + TIMEZONE=America/New_York + LANGUAGE=en_US.UTF-8 + LICENSE=WTFPL + TZ=America/New_York + tags: | + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DATE_TAG }} + ${{ steps.meta.outputs.DOCKER_HUB }}/${{ steps.meta.outputs.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.DOCKER_TAG }} + diff --git a/.gitignore b/.gitignore index 3b58a10..1bbc636 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ -# gitignore created on 05/22/25 at 21:00 +# gitignore created on 05/05/26 at 14:38 # Disable reminder in prompt ignoredirmessage +# ignore .build_failed files +**/.build_failed* + # OS generated files ### Linux ### *~ @@ -99,17 +102,3 @@ $RECYCLE.BIN/ **/*.rewrite.sh **/*.refactor.sh -# ignore dotenv files -.env - -# Ignore the file: app.env -app.env - -# Ignore the file: compose.default.yaml -compose.default.yaml -# ignore the default dotenv file -default.env - -# Exclude compose.yaml just in case it has sensitive data -compose.yaml - diff --git a/Dockerfile b/Dockerfile index a32b495..578f7e2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # Docker image for ampache using the alpine template ARG IMAGE_NAME="ampache" ARG PHP_SERVER="ampache" -ARG BUILD_DATE="202509161146" +ARG BUILD_DATE="202605091200" ARG LANGUAGE="en_US.UTF-8" ARG TIMEZONE="America/New_York" ARG WWW_ROOT_DIR="/usr/local/share/httpd/default" @@ -54,7 +54,7 @@ ARG PHP_SERVER ARG SHELL_OPTS ARG PATH -ARG PACK_LIST="mariadb-server-utils mariadb-client mariadb pwgen apache2 apache2-ctl apache2-lua apache2-ssl apache2-ldap apache2-icons apache2-http2 apache2-error apache2-proxy apache2-brotli apache2-webdav apache2-mod-wsgi apache-mod-fcgid apache2-proxy-html composer php84-bcmath php84-bz2 php84-calendar php84-cgi php84-common php84-ctype php84-curl php84-dba php84-dev php84-doc php84-dom php84-embed php84-enchant php84-exif php84-ffi php84-fileinfo php84-fpm php84-ftp php84-gd php84-gettext php84-gmp php84-iconv php84-imap php84-intl php84-ldap php84-litespeed php84-mbstring php84-mysqli php84-mysqlnd php84-odbc php84-opcache php84-openssl php84-pcntl php84-pdo php84-pdo_dblib php84-pdo_mysql php84-pdo_odbc php84-pdo_pgsql php84-pdo_sqlite php84-pear php84-pgsql php84-phar php84-phpdbg php84-posix php84-pspell php84-session php84-shmop php84-simplexml php84-snmp php84-soap php84-sockets php84-sodium php84-sqlite3 php84-sysvmsg php84-sysvsem php84-sysvshm php84-tidy php84-tokenizer php84-xml php84-xmlreader php84-xmlwriter php84-xsl php84-zip php84-pecl-memcached php84-pecl-mcrypt php84-pecl-mongodb php84-pecl-redis " +ARG PACK_LIST="bash tini curl wget unzip tar gzip tzdata ca-certificates pwgen mariadb mariadb-client mariadb-server-utils apache2 apache2-ctl apache2-utils apache2-ssl apache2-proxy apache2-http2 apache2-brotli apache2-icons apache2-error php84 php84-fpm php84-common php84-ctype php84-pdo php84-pdo_mysql php84-mysqli php84-mysqlnd php84-session php84-intl php84-curl php84-simplexml php84-xml php84-xmlreader php84-xmlwriter php84-dom php84-mbstring php84-iconv php84-tokenizer php84-fileinfo php84-openssl php84-phar php84-gd php84-zip php84-bz2 php84-gmp php84-exif php84-opcache php84-pecl-redis " ENV ENV=~/.profile ENV SHELL="/bin/sh" @@ -68,7 +68,7 @@ ENV HOSTNAME="casjaysdevdocker-ampache" USER ${USER} WORKDIR /root -COPY ./rootfs/usr/local/bin/. /usr/local/bin/ +COPY ./rootfs/. / RUN set -e; \ echo "Updating the system and ensuring bash is installed"; \ @@ -76,7 +76,13 @@ RUN set -e; \ RUN set -e; \ echo "Setting up prerequisites"; \ - true + apk --no-cache add bash; \ + SH_CMD="$(which sh 2>/dev/null||command -v sh 2>/dev/null)"; \ + BASH_CMD="$(which bash 2>/dev/null||command -v bash 2>/dev/null)"; \ + [ -x "$BASH_CMD" ] && symlink "$BASH_CMD" "/bin/sh" || true; \ + [ -x "$BASH_CMD" ] && symlink "$BASH_CMD" "/usr/bin/sh" || true; \ + [ -x "$BASH_CMD" ] && [ "$SH_CMD" != "/bin/sh" ] && symlink "$BASH_CMD" "$SH_CMD" || true; \ + [ -n "$BASH_CMD" ] && sed -i 's|root:x:.*|root:x:0:0:root:/root:'$BASH_CMD'|g' "/etc/passwd" || true ENV SHELL="/bin/bash" SHELL [ "/bin/bash", "-c" ] @@ -91,7 +97,12 @@ RUN echo "Initializing the system"; \ RUN echo "Creating and editing system files "; \ $SHELL_OPTS; \ - [ -f "/root/.profile" ] || touch "/root/.profile"; \ + rm -Rf "/etc/apk/repositories"; \ + [ "$DISTRO_VERSION" = "latest" ] && DISTRO_VERSION="edge";[ "$DISTRO_VERSION" = "edge" ] || DISTRO_VERSION="v${DISTRO_VERSION}"; \ + echo "http://dl-cdn.alpinelinux.org/alpine/${DISTRO_VERSION}/main" >>"/etc/apk/repositories"; \ + echo "http://dl-cdn.alpinelinux.org/alpine/${DISTRO_VERSION}/community" >>"/etc/apk/repositories"; \ + if [ "${DISTRO_VERSION}" = "edge" ]; then echo "http://dl-cdn.alpinelinux.org/alpine/${DISTRO_VERSION}/testing" >>"/etc/apk/repositories";fi; \ + apk update; apk upgrade --no-cache; \ if [ -f "/root/docker/setup/01-system.sh" ];then echo "Running the system script";/root/docker/setup/01-system.sh||{ echo "Failed to execute /root/docker/setup/01-system.sh" >&2 && exit 10; };echo "Done running the system script";fi; \ echo "" @@ -109,7 +120,6 @@ RUN echo "Initializing packages before copying files to image"; \ if [ -f "/root/docker/setup/02-packages.sh" ];then echo "Running the packages script";/root/docker/setup/02-packages.sh||{ echo "Failed to execute /root/docker/setup/02-packages.sh" >&2 && exit 10; };echo "Done running the packages script";fi; \ echo "" -COPY ./rootfs/. / COPY ./Dockerfile /root/docker/Dockerfile RUN echo "Updating system files "; \ @@ -119,7 +129,7 @@ RUN echo "Updating system files "; \ echo 'hosts: files dns' >"/etc/nsswitch.conf"; \ [ "$PHP_VERSION" = "system" ] && PHP_VERSION="php" || true; \ PHP_BIN="$(command -v ${PHP_VERSION} 2>/dev/null || true)"; \ - PHP_FPM="$(ls /usr/*bin/php*fpm* 2>/dev/null || true)"; \ + set -- /usr/*bin/php*fpm*; [ -e "$1" ] && PHP_FPM="$1" || PHP_FPM=""; \ pip_bin="$(command -v python3 2>/dev/null || command -v python2 2>/dev/null || command -v python 2>/dev/null || true)"; \ py_version="$(command $pip_bin --version | sed 's|[pP]ython ||g' | awk -F '.' '{print $1$2}' | grep '[0-9]' || true)"; \ [ "$py_version" -gt "310" ] && pip_opts="--break-system-packages " || pip_opts=""; \ @@ -176,7 +186,7 @@ RUN echo "Deleting unneeded files"; \ rm -rf /lib/systemd/system/sockets.target.wants/*udev* || true; \ rm -rf /lib/systemd/system/sockets.target.wants/*initctl* || true; \ rm -Rf /usr/share/doc/* /var/tmp/* /var/cache/*/* /root/.cache/* /usr/share/info/* /tmp/* || true; \ - if [ -d "/lib/systemd/system/sysinit.target.wants" ];then cd "/lib/systemd/system/sysinit.target.wants" && rm -f $(ls | grep -v systemd-tmpfiles-setup);fi; \ + if [ -d "/lib/systemd/system/sysinit.target.wants" ];then cd "/lib/systemd/system/sysinit.target.wants" && for want_file in *; do [ "$want_file" = "systemd-tmpfiles-setup" ] || rm -f "$want_file"; done; fi; \ if [ -f "/root/docker/setup/07-cleanup.sh" ];then echo "Running the cleanup script";/root/docker/setup/07-cleanup.sh||{ echo "Failed to execute /root/docker/setup/07-cleanup.sh" >&2 && exit 10; };echo "Done running the cleanup script";fi; \ echo "" @@ -193,6 +203,7 @@ ARG SERVICE_PORT ARG EXPOSE_PORTS ARG BUILD_VERSION ARG IMAGE_VERSION +ARG GIT_COMMIT ARG WWW_ROOT_DIR ARG DEFAULT_FILE_DIR ARG DEFAULT_DATA_DIR @@ -219,10 +230,10 @@ LABEL org.opencontainers.image.authors="${LICENSE}" LABEL org.opencontainers.image.created="${BUILD_DATE}" LABEL org.opencontainers.image.version="${BUILD_VERSION}" LABEL org.opencontainers.image.schema-version="${BUILD_VERSION}" -LABEL org.opencontainers.image.url="docker.io" -LABEL org.opencontainers.image.source="docker.io" +LABEL org.opencontainers.image.url="https://docker.io/casjaysdevdocker/ampache" +LABEL org.opencontainers.image.source="https://docker.io/casjaysdevdocker/ampache" LABEL org.opencontainers.image.vcs-type="Git" -LABEL org.opencontainers.image.revision="${BUILD_VERSION}" +LABEL org.opencontainers.image.revision="${GIT_COMMIT}" LABEL org.opencontainers.image.source="https://github.com/casjaysdevdocker/ampache" LABEL org.opencontainers.image.documentation="https://github.com/casjaysdevdocker/ampache" LABEL com.github.containers.toolbox="false" @@ -252,5 +263,8 @@ VOLUME [ "/config","/data" ] EXPOSE ${SERVICE_PORT} ${ENV_PORTS} -ENTRYPOINT [ "tini","--","/usr/local/bin/entrypoint.sh" ] +STOPSIGNAL SIGRTMIN+3 + +ENTRYPOINT [ "tini", "-p", "SIGTERM","--", "/usr/local/bin/entrypoint.sh" ] HEALTHCHECK --start-period=10m --interval=5m --timeout=15s CMD [ "/usr/local/bin/entrypoint.sh", "healthcheck" ] + diff --git a/LICENSE.md b/LICENSE.md index d9bb25c..27b62a2 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 - Copyright (C) 2025 casjay + Copyright (C) 2026 casjay Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long diff --git a/README.md b/README.md index dcb195f..d34348d 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ dockermgr update ampache ## Install and run container ```shell -dockerHome="/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/volumes" -mkdir -p "/var/lib/srv/$USER/docker/ampache/volumes" +dockerHome="/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/rootfs" +mkdir -p "/var/lib/srv/$USER/docker/ampache/rootfs" git clone "https://github.com/dockermgr/ampache" "$HOME/.local/share/CasjaysDev/dockermgr/ampache" cp -Rfva "$HOME/.local/share/CasjaysDev/dockermgr/ampache/rootfs/." "$dockerHome/" docker run -d \ @@ -47,8 +47,8 @@ services: - TZ=America/New_York - HOSTNAME=ampache volumes: - - "/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/volumes/data:/data:z" - - "/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/volumes/config:/config:z" + - "/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/rootfs/data:/data:z" + - "/var/lib/srv/$USER/docker/casjaysdevdocker/ampache/ampache/latest/rootfs/config:/config:z" ports: - 80:80 restart: always diff --git a/rootfs/root/docker/setup/04-users.sh b/rootfs/root/docker/setup/04-users.sh index 60f3e6e..b6d0251 100755 --- a/rootfs/root/docker/setup/04-users.sh +++ b/rootfs/root/docker/setup/04-users.sh @@ -1,38 +1,26 @@ #!/usr/bin/env bash # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -##@Version : 202502050828-git -# @@Author : CasjaysDev -# @@Contact : CasjaysDev -# @@License : MIT -# @@ReadME : -# @@Copyright : Copyright 2023 CasjaysDev -# @@Created : Mon Aug 28 06:48:42 PM EDT 2023 -# @@File : 04-users.sh -# @@Description : script to run users +# casjaysdevdocker/ampache - 04-users.sh +# Defensive user/group creation. The Alpine apache2 and mariadb packages +# normally create their service users, but we ensure here. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# shellcheck shell=bash -# shellcheck disable=SC2016 -# shellcheck disable=SC2031 -# shellcheck disable=SC2120 -# shellcheck disable=SC2155 -# shellcheck disable=SC2199 -# shellcheck disable=SC2317 -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set bash options set -o pipefail [ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set env variables + exitCode=0 -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Predefined actions +if ! getent group apache >/dev/null 2>&1; then + addgroup -S apache 2>/dev/null || true +fi +if ! getent passwd apache >/dev/null 2>&1; then + adduser -S -G apache -h /var/www -s /sbin/nologin apache 2>/dev/null || true +fi -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Main script +if ! getent group mysql >/dev/null 2>&1; then + addgroup -S mysql 2>/dev/null || true +fi +if ! getent passwd mysql >/dev/null 2>&1; then + adduser -S -G mysql -h /data/db/mariadb -s /sbin/nologin mysql 2>/dev/null || true +fi -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set the exit code -#exitCode=$? -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - exit $exitCode diff --git a/rootfs/root/docker/setup/05-custom.sh b/rootfs/root/docker/setup/05-custom.sh index 7bf95a0..145bd9c 100755 --- a/rootfs/root/docker/setup/05-custom.sh +++ b/rootfs/root/docker/setup/05-custom.sh @@ -1,26 +1,85 @@ #!/usr/bin/env bash # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set bash options +# casjaysdevdocker/ampache - 05-custom.sh +# 1. Wipe distro defaults under /etc/{apache2,php84,my.cnf.d}/* and +# drop in our optimized configs from /tmp/etc/. +# 2. Fetch the upstream Ampache prebuilt zip and unpack it under +# /usr/local/share/ampache. +# 3. Stage runtime dirs that the init.d scripts will need. +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - set -e -o pipefail [ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set env variables + exitCode=0 -export PHP_VERSION=$PHP_VERSION NODE_VERSION=$NODE_VERSION NODE_MANAGER=$NODE_MANAGER WWW_ROOT_DIR="$WWW_ROOT_DIR" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Main script - simplified for now -echo "Skipping template downloads for faster build" -# Create necessary directories -mkdir -p /usr/share/webapps/ampache -mkdir -p /config /data +AMPACHE_VERSION="${AMPACHE_VERSION:-7.9.3}" +AMPACHE_PHP_TAG="${AMPACHE_PHP_TAG:-php8.4}" +AMPACHE_URL="https://github.com/ampache/ampache/releases/download/${AMPACHE_VERSION}/ampache-${AMPACHE_VERSION}_all_${AMPACHE_PHP_TAG}.zip" +AMPACHE_INSTALL_DIR="/usr/local/share/ampache" -# Download Ampache if needed (commented out for now) -# cd /usr/share/webapps -# git clone https://github.com/ampache/ampache.git ampache || true +echo "Wiping distro defaults and installing optimized configs" +for svc in apache2 php84 my.cnf.d; do + src="/tmp/etc/$svc" + dst="/etc/$svc" + [ -d "$src" ] || continue + # Preserve mime.types + magic from the apache2 package; we don't ship our own. + if [ "$svc" = "apache2" ]; then + [ -f "$dst/mime.types" ] && cp -f "$dst/mime.types" "/tmp/${svc}_mime.types.preserve" || true + [ -f "$dst/magic" ] && cp -f "$dst/magic" "/tmp/${svc}_magic.preserve" || true + fi + rm -Rf "$dst"/* + mkdir -p "$dst" + cp -Rf "$src/." "$dst/" + if [ "$svc" = "apache2" ]; then + [ -f "/tmp/${svc}_mime.types.preserve" ] && mv -f "/tmp/${svc}_mime.types.preserve" "$dst/mime.types" + [ -f "/tmp/${svc}_magic.preserve" ] && mv -f "/tmp/${svc}_magic.preserve" "$dst/magic" + fi + # Drop a copy under template-files/config/ so /config/$svc gets seeded on first run. + mkdir -p "/usr/local/share/template-files/config/$svc" + cp -Rf "$dst/." "/usr/local/share/template-files/config/$svc/" +done -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Set the exit code -exitCode=$? -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -exit $exitCode \ No newline at end of file +echo "Fetching Ampache ${AMPACHE_VERSION} (${AMPACHE_PHP_TAG})" +mkdir -p "$AMPACHE_INSTALL_DIR" +cd /tmp +if ! wget -q -O /tmp/ampache.zip "$AMPACHE_URL"; then + echo "Failed to download $AMPACHE_URL" >&2 + exit 10 +fi +unzip -q -o /tmp/ampache.zip -d "$AMPACHE_INSTALL_DIR" +rm -f /tmp/ampache.zip + +# Some upstream zips unpack into a versioned subdir; flatten if needed. +if [ -d "$AMPACHE_INSTALL_DIR/ampache-${AMPACHE_VERSION}" ]; then + shopt -s dotglob + mv "$AMPACHE_INSTALL_DIR/ampache-${AMPACHE_VERSION}"/* "$AMPACHE_INSTALL_DIR/" + rmdir "$AMPACHE_INSTALL_DIR/ampache-${AMPACHE_VERSION}" + shopt -u dotglob +fi + +if [ ! -f "$AMPACHE_INSTALL_DIR/public/index.php" ]; then + echo "Ampache install layout unexpected: $AMPACHE_INSTALL_DIR/public/index.php missing" >&2 + ls -la "$AMPACHE_INSTALL_DIR" | head -20 >&2 + exit 11 +fi + +mkdir -p "$AMPACHE_INSTALL_DIR/config" + +echo "Creating runtime dirs" +mkdir -p /run/apache2 /run/php-fpm /run/mysqld /tmp/php-sessions \ + /var/log/apache2 \ + /usr/local/share/template-files/config/ampache + +# Seed for /config/ampache +cat <<'EOF' >/usr/local/share/template-files/config/ampache/.gitkeep +# Placeholder. Real ampache.cfg.php is generated by install.php on first +# web visit, then mirrored to this directory by 99-ampache.sh post_execute. +EOF + +# Make sure the apache user owns the app tree (composer artifacts ship as +# www-data:www-data by default, but apache uid/gid differ on Alpine). +if id apache >/dev/null 2>&1; then + chown -Rf apache:apache "$AMPACHE_INSTALL_DIR" 2>/dev/null || true +fi + +exit $exitCode diff --git a/rootfs/tmp/etc/ampache/.gitkeep b/rootfs/tmp/etc/ampache/.gitkeep new file mode 100644 index 0000000..6a09d44 --- /dev/null +++ b/rootfs/tmp/etc/ampache/.gitkeep @@ -0,0 +1,3 @@ +# Placeholder. /etc/ampache/ exists so the framework can seed /config/ampache/ +# from /usr/local/share/template-files/config/ampache/ on first run; the real +# ampache.cfg.php is generated by install.php after the first web visit. diff --git a/rootfs/tmp/etc/apache2/conf.d/ampache.conf b/rootfs/tmp/etc/apache2/conf.d/ampache.conf new file mode 100644 index 0000000..000f246 --- /dev/null +++ b/rootfs/tmp/etc/apache2/conf.d/ampache.conf @@ -0,0 +1,33 @@ +# casjaysdevdocker/ampache - Apache vhost for Ampache +# +# DocumentRoot is the upstream-blessed `public/` subfolder of the Ampache +# install (see https://ampache.org/docs/installation). + + + ServerName casjaysdev-ampache + DocumentRoot /usr/local/share/ampache/public + + + Options FollowSymLinks + AllowOverride All + Require all granted + + # Ampache's REST API needs the Authorization header passed through. + SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 + + + # Block .git and other dotfile dirs. + + Require all denied + + + # Hand .php files to php-fpm over its unix socket. + + SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost" + + + DirectoryIndex index.php index.html + + ErrorLog /data/logs/apache2/ampache_error.log + CustomLog /data/logs/apache2/ampache_access.log combined + diff --git a/rootfs/tmp/etc/apache2/conf.d/mpm.conf b/rootfs/tmp/etc/apache2/conf.d/mpm.conf new file mode 100644 index 0000000..d21073f --- /dev/null +++ b/rootfs/tmp/etc/apache2/conf.d/mpm.conf @@ -0,0 +1,10 @@ +# casjaysdevdocker/ampache - MPM event tuning + + StartServers 2 + MinSpareThreads 25 + MaxSpareThreads 75 + ThreadLimit 64 + ThreadsPerChild 25 + MaxRequestWorkers 150 + MaxConnectionsPerChild 0 + diff --git a/rootfs/tmp/etc/apache2/httpd.conf b/rootfs/tmp/etc/apache2/httpd.conf new file mode 100644 index 0000000..d1ef735 --- /dev/null +++ b/rootfs/tmp/etc/apache2/httpd.conf @@ -0,0 +1,83 @@ +# casjaysdevdocker/ampache - Apache httpd 2.4 (Alpine) - main config +# +# Wipe-and-replace via 05-custom.sh; user edits live at /config/apache2/. + +ServerRoot /var/www +PidFile /run/apache2/httpd.pid +Mutex file:/run/apache2 default +Timeout 60 +KeepAlive On +MaxKeepAliveRequests 100 +KeepAliveTimeout 5 + +User apache +Group apache + +ServerAdmin docker-admin@casjaysdev.pro +ServerName casjaysdev-ampache:80 +ServerSignature Off +ServerTokens Prod +UseCanonicalName Off +HostnameLookups Off + +Listen 80 + +# Modules - load only what we need. +LoadModule mpm_event_module modules/mod_mpm_event.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule authn_core_module modules/mod_authn_core.so +LoadModule authn_file_module modules/mod_authn_file.so +LoadModule authz_core_module modules/mod_authz_core.so +LoadModule authz_host_module modules/mod_authz_host.so +LoadModule authz_user_module modules/mod_authz_user.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule filter_module modules/mod_filter.so +LoadModule mime_module modules/mod_mime.so +LoadModule mime_magic_module modules/mod_mime_magic.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule env_module modules/mod_env.so +LoadModule headers_module modules/mod_headers.so +LoadModule expires_module modules/mod_expires.so +LoadModule deflate_module modules/mod_deflate.so +LoadModule brotli_module modules/mod_brotli.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule version_module modules/mod_version.so +LoadModule status_module modules/mod_status.so +LoadModule autoindex_module modules/mod_autoindex.so +LoadModule dir_module modules/mod_dir.so +LoadModule alias_module modules/mod_alias.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule negotiation_module modules/mod_negotiation.so +LoadModule proxy_module modules/mod_proxy.so +LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so +LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +LoadModule ssl_module modules/mod_ssl.so +LoadModule http2_module modules/mod_http2.so + +TypesConfig /etc/apache2/mime.types +MimeMagicFile /etc/apache2/magic +DirectoryIndex index.php index.html + +# Default deny on filesystem root; vhost re-permits its DocumentRoot. + + AllowOverride None + Require all denied + + +# Hide dotfiles. + + Require all denied + + +# Logs land under /data so they survive container recreation. +ErrorLog /data/logs/apache2/error.log +LogLevel warn +LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined +LogFormat "%h %l %u %t \"%r\" %>s %b" common +CustomLog /data/logs/apache2/access.log combined + +# Drop in our service vhost(s) and any user-supplied ones. +IncludeOptional /etc/apache2/conf.d/*.conf +IncludeOptional /config/apache2/vhosts.d/*.conf diff --git a/rootfs/tmp/etc/my.cnf.d/mariadb-server.cnf b/rootfs/tmp/etc/my.cnf.d/mariadb-server.cnf new file mode 100644 index 0000000..b3f36ad --- /dev/null +++ b/rootfs/tmp/etc/my.cnf.d/mariadb-server.cnf @@ -0,0 +1,53 @@ +# casjaysdevdocker/ampache - MariaDB server config +# +# Wipe-and-replace via 05-custom.sh; user edits live at /config/my.cnf.d/. + +[client] +port = 3306 +socket = /run/mysqld/mysqld.sock +default-character-set = utf8mb4 + +[mysql] +no_auto_rehash +default-character-set = utf8mb4 +prompt = '\u@\h [\d]> ' + +[mysqldump] +max_allowed_packet = 64M + +[mysqld_safe] +log-error = /data/logs/mariadb/mariadb.err.log +pid-file = /run/mysqld/mariadb.pid + +[mysqld] +user = mysql +datadir = /data/db/mariadb +socket = /run/mysqld/mysqld.sock +port = 3306 +bind-address = 127.0.0.1 +pid-file = /run/mysqld/mariadb.pid +log-error = /data/logs/mariadb/mariadb.err.log + +character-set-server = utf8mb4 +collation-server = utf8mb4_unicode_ci +default-storage-engine = InnoDB + +max_allowed_packet = 64M +max_connections = 100 +open_files_limit = 16384 +key_buffer_size = 32M +table_open_cache = 256 + +innodb_buffer_pool_size = 256M +innodb_log_file_size = 64M +innodb_flush_log_at_trx_commit = 2 +innodb_file_per_table = 1 + +slow_query_log = 1 +slow_query_log_file = /data/logs/mariadb/mariadb-slow.log +long_query_time = 2 + +skip-name-resolve + +[mariadb] +plugin_load_add = auth_socket diff --git a/rootfs/tmp/etc/php84/php-fpm.conf b/rootfs/tmp/etc/php84/php-fpm.conf new file mode 100644 index 0000000..6daebb2 --- /dev/null +++ b/rootfs/tmp/etc/php84/php-fpm.conf @@ -0,0 +1,12 @@ +; casjaysdevdocker/ampache - PHP-FPM 8.4 global config + +[global] +pid = /run/php-fpm/php-fpm.pid +error_log = /data/logs/php-fpm/error.log +log_level = notice +emergency_restart_threshold = 0 +emergency_restart_interval = 0 +process_control_timeout = 0 +daemonize = no + +include = /etc/php84/php-fpm.d/*.conf diff --git a/rootfs/tmp/etc/php84/php-fpm.d/www.conf b/rootfs/tmp/etc/php84/php-fpm.d/www.conf new file mode 100644 index 0000000..bd3ee2f --- /dev/null +++ b/rootfs/tmp/etc/php84/php-fpm.d/www.conf @@ -0,0 +1,39 @@ +; casjaysdevdocker/ampache - PHP-FPM www pool + +[www] +user = apache +group = apache + +listen = /run/php-fpm/php-fpm.sock +listen.owner = apache +listen.group = apache +listen.mode = 0660 +listen.backlog = 511 + +pm = dynamic +pm.max_children = 20 +pm.start_servers = 4 +pm.min_spare_servers = 2 +pm.max_spare_servers = 8 +pm.max_requests = 500 +pm.process_idle_timeout = 30s +pm.status_path = /status +ping.path = /ping +ping.response = pong + +access.log = /data/logs/php-fpm/access.log +slowlog = /data/logs/php-fpm/slow.log +request_slowlog_timeout = 5s +request_terminate_timeout = 300s + +clear_env = no +catch_workers_output = yes +decorate_workers_output = no + +php_admin_value[error_log] = /data/logs/php-fpm/error.log +php_admin_flag[log_errors] = on +php_admin_value[memory_limit] = 512M +php_admin_value[upload_max_filesize] = 256M +php_admin_value[post_max_size] = 256M +php_admin_value[max_execution_time] = 300 +php_admin_value[session.save_path] = /tmp/php-sessions diff --git a/rootfs/tmp/etc/php84/php.ini b/rootfs/tmp/etc/php84/php.ini new file mode 100644 index 0000000..3a1eb10 --- /dev/null +++ b/rootfs/tmp/etc/php84/php.ini @@ -0,0 +1,80 @@ +; casjaysdevdocker/ampache - PHP 8.4 production tunings for Ampache + +[PHP] +engine = On +short_open_tag = Off +precision = 14 +output_buffering = 4096 +zlib.output_compression = Off +implicit_flush = Off +serialize_precision = -1 +disable_functions = +disable_classes = +zend.enable_gc = On +expose_php = Off +max_execution_time = 300 +max_input_time = 300 +max_input_vars = 5000 +memory_limit = 512M + +error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT +display_errors = Off +display_startup_errors = Off +log_errors = On +log_errors_max_len = 1024 +ignore_repeated_errors = Off +ignore_repeated_source = Off +report_memleaks = On +html_errors = On +error_log = /data/logs/php-fpm/error.log + +variables_order = "GPCS" +request_order = "GP" +register_argc_argv = Off +auto_globals_jit = On + +post_max_size = 256M +upload_max_filesize = 256M +max_file_uploads = 20 + +default_socket_timeout = 60 +allow_url_fopen = On +allow_url_include = Off + +cgi.fix_pathinfo = 0 + +[Date] +date.timezone = REPLACE_TZ + +[Session] +session.save_handler = files +session.save_path = "/tmp/php-sessions" +session.use_strict_mode = 0 +session.use_cookies = 1 +session.use_only_cookies = 1 +session.name = AMPACHE_SESSION +session.auto_start = 0 +session.cookie_lifetime = 0 +session.cookie_path = / +session.cookie_secure = Off +session.cookie_httponly = On +session.cookie_samesite = Lax +session.gc_probability = 1 +session.gc_divisor = 1000 +session.gc_maxlifetime = 86400 + +[opcache] +opcache.enable = 1 +opcache.enable_cli = 0 +opcache.memory_consumption = 256 +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.revalidate_freq = 60 +opcache.fast_shutdown = 1 +opcache.validate_timestamps = 1 + +[curl] +curl.cainfo = /etc/ssl/certs/ca-certificates.crt + +[openssl] +openssl.cafile = /etc/ssl/certs/ca-certificates.crt diff --git a/rootfs/usr/local/bin/entrypoint.sh b/rootfs/usr/local/bin/entrypoint.sh index 651b868..c671962 100755 --- a/rootfs/usr/local/bin/entrypoint.sh +++ b/rootfs/usr/local/bin/entrypoint.sh @@ -1,13 +1,13 @@ #!/usr/bin/env bash # shellcheck shell=bash # - - - - - - - - - - - - - - - - - - - - - - - - - -##@Version : 202511301623-git +##@Version : 202602061352-git # @@Author : Jason Hempstead # @@Contact : jason@casjaysdev.pro # @@License : WTFPL # @@ReadME : entrypoint.sh --help -# @@Copyright : Copyright: (c) 2025 Jason Hempstead, Casjays Developments -# @@Created : Sunday, Nov 30, 2025 16:23 EST +# @@Copyright : Copyright: (c) 2026 Jason Hempstead, Casjays Developments +# @@Created : Tuesday, May 05, 2026 14:38 EDT # @@File : entrypoint.sh # @@Description : Entrypoint file for ampache # @@Changelog : New script @@ -32,7 +32,7 @@ PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" # Set bash options SCRIPT_FILE="$0" CONTAINER_NAME="ampache" -SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +SCRIPT_NAME="${SCRIPT_FILE##*/}" CONTAINER_NAME="${ENV_CONTAINER_NAME:-$CONTAINER_NAME}" # - - - - - - - - - - - - - - - - - - - - - - - - - # remove whitespaces from beginning argument @@ -73,30 +73,38 @@ done unset set_env # - - - - - - - - - - - - - - - - - - - - - - - - - # User to use to launch service - IE: postgres -RUNAS_USER="root" # normally root +# normally root +RUNAS_USER="root" # - - - - - - - - - - - - - - - - - - - - - - - - - # Set user and group from env SERVICE_USER="${PUID:-$SERVICE_USER}" SERVICE_GROUP="${PGID:-$SERVICE_GROUP}" # - - - - - - - - - - - - - - - - - - - - - - - - - # Set user and group ID -SERVICE_UID="${SERVICE_UID:-0}" # set the user id -SERVICE_GID="${SERVICE_GID:-0}" # set the group id +# set the user id +SERVICE_UID="${SERVICE_UID:-0}" +# set the group id +SERVICE_GID="${SERVICE_GID:-0}" # - - - - - - - - - - - - - - - - - - - - - - - - - # User and group in which the service switches to - IE: nginx,apache,mysql,postgres #SERVICE_USER="${SERVICE_USER:-ampache}" # execute command as another user #SERVICE_GROUP="${SERVICE_GROUP:-ampache}" # Set the service group # - - - - - - - - - - - - - - - - - - - - - - - - - # Secondary ports -SERVER_PORTS="" # specifiy other ports +# specifiy other ports +SERVER_PORTS="" # - - - - - - - - - - - - - - - - - - - - - - - - - # Primary server port- will be added to server ports -WEB_SERVER_PORT="" # port : 80,443 +# port : 80,443 +WEB_SERVER_PORT="" # - - - - - - - - - - - - - - - - - - - - - - - - - # Healthcheck variables -HEALTH_ENABLED="yes" # enable healthcheck [yes/no] -SERVICES_LIST="tini" # comma separated list of processes for the healthcheck -HEALTH_ENDPOINTS="" # url endpoints: [http://localhost/health,http://localhost/test] +# enable healthcheck [yes/no] +HEALTH_ENABLED="yes" +# comma separated list of processes for the healthcheck +SERVICES_LIST="tini" +# url endpoints: [http://localhost/health,http://localhost/test] +HEALTH_ENDPOINTS="" # - - - - - - - - - - - - - - - - - - - - - - - - - # Update path var export PATH RUNAS_USER SERVICE_USER SERVICE_GROUP SERVICE_UID SERVICE_GID WWW_ROOT_DIR DATABASE_DIR @@ -162,28 +170,40 @@ export ENTRYPOINT_DATA_INIT_FILE="${ENTRYPOINT_DATA_INIT_FILE:-/data/.docker_has export ENTRYPOINT_CONFIG_INIT_FILE="${ENTRYPOINT_CONFIG_INIT_FILE:-/config/.docker_has_run}" # - - - - - - - - - - - - - - - - - - - - - - - - - if [ -n "$CONTAINER_WEB_SERVER_WWW_REPO" ]; then - www_temp_dir="/tmp/git/$(basename -- "$CONTAINER_WEB_SERVER_WWW_REPO")" - rm -Rf "${WWW_ROOT_DIR:?}"/* "${www_temp_dir:?}"/* - mkdir -p "$WWW_ROOT_DIR" "$www_temp_dir" - git clone -q "$CONTAINER_WEB_SERVER_WWW_REPO" "$www_temp_dir" 2>/dev/null - rm -Rf "$www_temp_dir/.git" "$www_temp_dir"/.git* - rsync -ra "$www_temp_dir/" "$WWW_ROOT_DIR" --delete >/dev/null 2>&1 - rm -Rf "$www_temp_dir" + www_temp_dir="/tmp/git/${CONTAINER_WEB_SERVER_WWW_REPO##*/}" + rm -Rf "${WWW_ROOT_DIR:?}"/* "${www_temp_dir:?}"/* 2>/dev/null || true + mkdir -p "$WWW_ROOT_DIR" "$www_temp_dir" 2>/dev/null || true + git clone -q "$CONTAINER_WEB_SERVER_WWW_REPO" "$www_temp_dir" 2>/dev/null || true + rm -Rf "$www_temp_dir/.git" "$www_temp_dir"/.git* 2>/dev/null || true + rsync -ra "$www_temp_dir/" "$WWW_ROOT_DIR" --delete 2>/dev/null || true + rm -Rf "$www_temp_dir" 2>/dev/null || true fi # - - - - - - - - - - - - - - - - - - - - - - - - - # variables based on env/files -[ -f "/config/enable/ssl" ] && SSL_ENABLED="yes" -[ -f "/config/enable/ssh" ] && SSH_ENABLED="yes" -[ "$WEB_SERVER_PORT" = "443" ] && SSL_ENABLED="yes" -[ "$CONTAINER_WEB_SERVER_PROTOCOL" = "https" ] && SSL_ENABLED="yes" +if [ -f "/config/enable/ssl" ]; then SSL_ENABLED="yes"; fi +if [ -f "/config/enable/ssh" ]; then SSH_ENABLED="yes"; fi +if [ "$WEB_SERVER_PORT" = "443" ]; then SSL_ENABLED="yes"; fi +if [ "$CONTAINER_WEB_SERVER_PROTOCOL" = "https" ]; then SSL_ENABLED="yes"; fi # - - - - - - - - - - - - - - - - - - - - - - - - - # export variables # - - - - - - - - - - - - - - - - - - - - - - - - - # is already Initialized -[ -f "$ENTRYPOINT_DATA_INIT_FILE" ] && DATA_DIR_INITIALIZED="yes" || DATA_DIR_INITIALIZED="no" -[ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ] && CONFIG_DIR_INITIALIZED="yes" || CONFIG_DIR_INITIALIZED="no" -{ [ -f "$ENTRYPOINT_PID_FILE" ] || [ -f "$ENTRYPOINT_INIT_FILE" ]; } && ENTRYPOINT_FIRST_RUN="no" || ENTRYPOINT_FIRST_RUN="yes" +if [ -f "$ENTRYPOINT_DATA_INIT_FILE" ]; then + DATA_DIR_INITIALIZED="yes" +else + DATA_DIR_INITIALIZED="no" +fi +if [ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ]; then + CONFIG_DIR_INITIALIZED="yes" +else + CONFIG_DIR_INITIALIZED="no" +fi +if [ -f "$ENTRYPOINT_PID_FILE" ] || [ -f "$ENTRYPOINT_INIT_FILE" ]; then + ENTRYPOINT_FIRST_RUN="no" +else + ENTRYPOINT_FIRST_RUN="yes" +fi # - - - - - - - - - - - - - - - - - - - - - - - - - # clean ENV_PORTS variables ENV_PORTS="${ENV_PORTS//,/ }" # @@ -207,168 +227,236 @@ ENV_PORTS="$(__format_variables "$SERVER_PORTS" "$WEB_SERVER_PORTS" "$ENV_PORTS" HEALTH_ENDPOINTS="${HEALTH_ENDPOINTS//,/ }" # - - - - - - - - - - - - - - - - - - - - - - - - - # create required directories -mkdir -p "/run" -mkdir -p "/tmp" -mkdir -p "/root" -mkdir -p "/var/run" -mkdir -p "/var/tmp" -mkdir -p "/run/cron" -mkdir -p "/data/logs" -mkdir -p "/run/init.d" -mkdir -p "/config/enable" -mkdir -p "/config/secure" -mkdir -p "/usr/local/etc/docker/exec" +mkdir -p "/run" 2>/dev/null || true +mkdir -p "/tmp" 2>/dev/null || true +mkdir -p "/root" 2>/dev/null || true +mkdir -p "/var/run" 2>/dev/null || true +mkdir -p "/var/tmp" 2>/dev/null || true +mkdir -p "/run/cron" 2>/dev/null || true +mkdir -p "/data/logs" 2>/dev/null || true +mkdir -p "/run/init.d" 2>/dev/null || true +mkdir -p "/config/enable" 2>/dev/null || true +mkdir -p "/config/secure" 2>/dev/null || true +mkdir -p "/usr/local/etc/docker/exec" 2>/dev/null || true # - - - - - - - - - - - - - - - - - - - - - - - - - # create required files -touch "/data/logs/start.log" -touch "/data/logs/entrypoint.log" +touch "/data/logs/start.log" 2>/dev/null || true +touch "/data/logs/entrypoint.log" 2>/dev/null || true # - - - - - - - - - - - - - - - - - - - - - - - - - # fix permissions -chmod -f 777 "/run" -chmod -f 777 "/tmp" -chmod -f 700 "/root" -chmod -f 777 "/var/run" -chmod -f 777 "/var/tmp" -chmod -f 777 "/run/cron" -chmod -f 777 "/data/logs" -chmod -f 777 "/run/init.d" -chmod -f 777 "/config/enable" -chmod -f 777 "/config/secure" -chmod -f 777 "/data/logs/entrypoint.log" -chmod -f 777 "/usr/local/etc/docker/exec" +chmod -f 777 "/run" 2>/dev/null || true +chmod -f 777 "/tmp" 2>/dev/null || true +chmod -f 700 "/root" 2>/dev/null || true +chmod -f 777 "/var/run" 2>/dev/null || true +chmod -f 777 "/var/tmp" 2>/dev/null || true +chmod -f 777 "/run/cron" 2>/dev/null || true +chmod -f 777 "/data/logs" 2>/dev/null || true +chmod -f 777 "/run/init.d" 2>/dev/null || true +chmod -f 777 "/config/enable" 2>/dev/null || true +chmod -f 777 "/config/secure" 2>/dev/null || true +chmod -f 777 "/data/logs/entrypoint.log" 2>/dev/null || true +chmod -f 777 "/usr/local/etc/docker/exec" 2>/dev/null || true # - - - - - - - - - - - - - - - - - - - - - - - - - # lets ensure everyone can write to std* -[ -f "/dev/stdin" ] && chmod -f 777 "/dev/stdin" -[ -f "/dev/stderr" ] && chmod -f 777 "/dev/stderr" -[ -f "/dev/stdout" ] && chmod -f 777 "/dev/stdout" +if [ -f "/dev/stdin" ]; then + chmod -f 777 "/dev/stdin" 2>/dev/null || true +fi +if [ -f "/dev/stderr" ]; then + chmod -f 777 "/dev/stderr" 2>/dev/null || true +fi +if [ -f "/dev/stdout" ]; then + chmod -f 777 "/dev/stdout" 2>/dev/null || true +fi # - - - - - - - - - - - - - - - - - - - - - - - - - -cat </dev/null +cat </dev/null | tee /etc/profile.d/locales.shadow /etc/profile.d/locales.sh >/dev/null 2>&1 || true export LANG="\${LANG:-C.UTF-8}" export LC_ALL="\${LANG:-C.UTF-8}" export TZ="\${TZ:-\${TIMEZONE:-America/New_York}}" EOF # - - - - - - - - - - - - - - - - - - - - - - - - - # Create the backup dir -[ -n "$BACKUP_DIR" ] && { [ -d "$BACKUP_DIR" ] || mkdir -p "$BACKUP_DIR"; } +if [ -n "$BACKUP_DIR" ]; then + if [ ! -d "$BACKUP_DIR" ]; then + mkdir -p "$BACKUP_DIR" 2>/dev/null || true + fi +fi # - - - - - - - - - - - - - - - - - - - - - - - - - if [ -f "$ENTRYPOINT_INIT_FILE" ]; then ENTRYPOINT_MESSAGE="no" ENTRYPOINT_FIRST_RUN="no" fi # - - - - - - - - - - - - - - - - - - - - - - - - - if [ "$ENTRYPOINT_FIRST_RUN" != "no" ]; then - # Show start message if [ "$CONFIG_DIR_INITIALIZED" = "no" ] || [ "$DATA_DIR_INITIALIZED" = "no" ]; then - [ "$ENTRYPOINT_MESSAGE" = "yes" ] && echo "Executing entrypoint script for ampache" + if [ "$ENTRYPOINT_MESSAGE" = "yes" ]; then + echo "Executing entrypoint script for ampache" + fi fi # - - - - - - - - - - - - - - - - - - - - - - - - - # Set reusable variables - { { [ -w "/etc" ] && [ ! -f "/etc/hosts" ]; } || [ -w "/etc/hosts" ]; } && UPDATE_FILE_HOSTS="yes" && touch "/etc/hosts" - { { [ -w "/etc" ] && [ ! -f "/etc/timezone" ]; } || [ -w "/etc/timezone" ]; } && UPDATE_FILE_TZ="yes" && touch "/etc/timezone" - { { [ -w "/etc" ] && [ ! -f "/etc/resolv.conf" ]; } || [ -w "/etc/resolv.conf" ]; } && UPDATE_FILE_RESOLV="yes" && touch "/etc/resolv.conf" + if [ -w "/etc" ] && [ ! -f "/etc/hosts" ]; then + UPDATE_FILE_HOSTS="yes" + touch "/etc/hosts" + elif [ -w "/etc/hosts" ]; then + UPDATE_FILE_HOSTS="yes" + touch "/etc/hosts" + fi + if [ -w "/etc" ] && [ ! -f "/etc/timezone" ]; then + UPDATE_FILE_TZ="yes" + touch "/etc/timezone" + elif [ -w "/etc/timezone" ]; then + UPDATE_FILE_TZ="yes" + touch "/etc/timezone" + fi + if [ -w "/etc" ] && [ ! -f "/etc/resolv.conf" ]; then + UPDATE_FILE_RESOLV="yes" + touch "/etc/resolv.conf" + elif [ -w "/etc/resolv.conf" ]; then + UPDATE_FILE_RESOLV="yes" + touch "/etc/resolv.conf" + fi # - - - - - - - - - - - - - - - - - - - - - - - - - # Set timezone - [ -n "$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ] && echo "$TZ" >"/etc/timezone" - [ -f "/usr/share/zoneinfo/$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ] && ln -sf "/usr/share/zoneinfo/$TZ" "/etc/localtime" + if [ -n "$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ]; then + echo "$TZ" >"/etc/timezone" 2>/dev/null || true + fi + if [ -f "/usr/share/zoneinfo/$TZ" ] && [ "$UPDATE_FILE_TZ" = "yes" ]; then + ln -sf "/usr/share/zoneinfo/$TZ" "/etc/localtime" 2>/dev/null || true + fi # - - - - - - - - - - - - - - - - - - - - - - - - - # if ipv6 add it to /etc/hosts if [ "$UPDATE_FILE_HOSTS" = "yes" ]; then - echo "# known hostname mappings" >"/etc/hosts" + echo "# known hostname mappings" >"/etc/hosts" 2>/dev/null || true if [ -n "$(ip a 2>/dev/null | grep 'inet6.*::' || ifconfig 2>/dev/null | grep 'inet6.*::')" ]; then - __printf_space "40" "::1" "localhost" >>"/etc/hosts" - __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" + __printf_space "40" "::1" "localhost" >>"/etc/hosts" 2>/dev/null || true + __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" 2>/dev/null || true else - __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" + __printf_space "40" "127.0.0.1" "localhost" >>"/etc/hosts" 2>/dev/null || true fi fi # - - - - - - - - - - - - - - - - - - - - - - - - - # add .internal domain if [ "$UPDATE_FILE_HOSTS" = "yes" ] && [ -n "$HOSTNAME" ]; then - __grep_test " $HOSTNAME" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "$HOSTNAME" >>"/etc/hosts" - __grep_test " ${HOSTNAME%%.*}.internal" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.internal" >>"/etc/hosts" + if ! __grep_test " $HOSTNAME" "/etc/hosts"; then + __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "$HOSTNAME" >>"/etc/hosts" 2>/dev/null || true + fi + if ! __grep_test " ${HOSTNAME%%.*}.internal" "/etc/hosts"; then + __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.internal" >>"/etc/hosts" 2>/dev/null || true + fi fi # - - - - - - - - - - - - - - - - - - - - - - - - - # add domainname if [ "$UPDATE_FILE_HOSTS" = "yes" ] && [ "$DOMAINNAME" != "internal" ] && [ -n "$DOMAINNAME" ] && [ "$HOSTNAME.$DOMAINNAME" != "$DOMAINNAME" ]; then - __grep_test " ${HOSTNAME%%.*}.$DOMAINNAME" "/etc/hosts" || __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.$DOMAINNAME" >>"/etc/hosts" + if ! __grep_test " ${HOSTNAME%%.*}.$DOMAINNAME" "/etc/hosts"; then + __printf_space "40" "${CONTAINER_IP4_ADDRESS:-127.0.0.1}" "${HOSTNAME%%.*}.$DOMAINNAME" >>"/etc/hosts" 2>/dev/null || true + fi fi # - - - - - - - - - - - - - - - - - - - - - - - - - # Set containers hostname - [ -n "$HOSTNAME" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ] && echo "$HOSTNAME" >"/etc/hostname" + if [ -n "$HOSTNAME" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ]; then + echo "$HOSTNAME" >"/etc/hostname" 2>/dev/null || true + fi # - - - - - - - - - - - - - - - - - - - - - - - - - if [ -f "/etc/hostname" ]; then - [ -n "$(type -P hostname)" ] && hostname -F "/etc/hostname" &>/dev/null || HOSTNAME="$(<"/etc/hostname")" + if [ -n "$(type -P hostname 2>/dev/null)" ]; then + hostname -F "/etc/hostname" 2>/dev/null || true + else + HOSTNAME="$(<"/etc/hostname")" 2>/dev/null || true + fi export HOSTNAME fi # - - - - - - - - - - - - - - - - - - - - - - - - - # import hosts file into container - [ -f "/usr/local/etc/hosts" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ] && cat "/usr/local/etc/hosts" | grep -vF "$HOSTNAME" >>"/etc/hosts" + if [ -f "/usr/local/etc/hosts" ] && [ "$UPDATE_FILE_HOSTS" = "yes" ]; then + grep -vF "$HOSTNAME" "/usr/local/etc/hosts" 2>/dev/null >>"/etc/hosts" 2>/dev/null || true + fi # - - - - - - - - - - - - - - - - - - - - - - - - - # import resolv.conf file into container - [ "$CUSTOM_DNS" != "yes" ] && [ -f "/usr/local/etc/resolv.conf" ] && [ "$UPDATE_FILE_RESOLV" = "yes" ] && cat "/usr/local/etc/resolv.conf" >"/etc/resolv.conf" + if [ "$CUSTOM_DNS" != "yes" ] && [ -f "/usr/local/etc/resolv.conf" ] && [ "$UPDATE_FILE_RESOLV" = "yes" ]; then + cat "/usr/local/etc/resolv.conf" >"/etc/resolv.conf" 2>/dev/null || true + fi # - - - - - - - - - - - - - - - - - - - - - - - - - if [ -n "$HOME" ] && [ -d "/usr/local/etc/skel" ]; then - [ -d "$HOME" ] && cp -Rf "/usr/local/etc/skel/." "$HOME/" + if [ -d "$HOME" ]; then + cp -Rf "/usr/local/etc/skel/." "$HOME/" 2>/dev/null || true + fi fi # - - - - - - - - - - - - - - - - - - - - - - - - - fi # - - - - - - - - - - - - - - - - - - - - - - - - - # Delete any .gitkeep files -[ -d "/data" ] && rm -Rf "/data/.gitkeep" "/data"/*/*.gitkeep -[ -d "/config" ] && rm -Rf "/config/.gitkeep" "/config"/*/*.gitkeep -[ -f "/usr/local/bin/.gitkeep" ] && rm -Rf "/usr/local/bin/.gitkeep" -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Setup bin directory - /config/bin > /usr/local/bin -__initialize_custom_bin_dir -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Copy default system configs - /usr/local/share/template-files/defaults > /config/ -__initialize_default_templates -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Copy custom config files - /usr/local/share/template-files/config > /config/ -__initialize_config_dir -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Copy custom data files - /usr/local/share/template-files/data > /data/ -__initialize_data_dir -# - - - - - - - - - - - - - - - - - - - - - - - - - -__initialize_ssl_certs -# - - - - - - - - - - - - - - - - - - - - - - - - - -if [ -f "$ENTRYPOINT_INIT_FILE" ]; then - ENTRYPOINT_FIRST_RUN="no" -fi -# - - - - - - - - - - - - - - - - - - - - - - - - - -if [ -d "/config" ]; then - echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_INIT_FILE" -fi -# - - - - - - - - - - - - - - - - - - - - - - - - - -# Check if this is a new container -if [ -f "$ENTRYPOINT_DATA_INIT_FILE" ]; then - DATA_DIR_INITIALIZED="yes" -fi -# - - - - - - - - - - - - - - - - - - - - - - - - - if [ -d "/data" ]; then - echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_DATA_INIT_FILE" + rm -Rf "/data/.gitkeep" "/data"/*/*.gitkeep 2>/dev/null || true fi -# - - - - - - - - - - - - - - - - - - - - - - - - - -if [ -f "$ENTRYPOINT_CONFIG_INIT_FILE" ]; then - CONFIG_DIR_INITIALIZED="yes" -fi -# - - - - - - - - - - - - - - - - - - - - - - - - - if [ -d "/config" ]; then - echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_CONFIG_INIT_FILE" + rm -Rf "/config/.gitkeep" "/config"/*/*.gitkeep 2>/dev/null || true +fi +if [ -f "/usr/local/bin/.gitkeep" ]; then + rm -Rf "/usr/local/bin/.gitkeep" 2>/dev/null || true fi # - - - - - - - - - - - - - - - - - - - - - - - - - -if [ "$ENTRYPOINT_FIRST_RUN" != "no" ]; then +# Only run initialization on first run or when directories are not initialized +if [ "$ENTRYPOINT_FIRST_RUN" != "no" ] || [ "$CONFIG_DIR_INITIALIZED" = "no" ] || [ "$DATA_DIR_INITIALIZED" = "no" ]; then + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Setup bin directory - /config/bin > /usr/local/bin + __initialize_custom_bin_dir + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Copy default system configs - /usr/local/share/template-files/defaults > /config/ + if [ "$CONFIG_DIR_INITIALIZED" = "no" ]; then + __initialize_default_templates + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Copy custom config files - /usr/local/share/template-files/config > /config/ + if [ "$CONFIG_DIR_INITIALIZED" = "no" ]; then + __initialize_config_dir + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Copy custom data files - /usr/local/share/template-files/data > /data/ + if [ "$DATA_DIR_INITIALIZED" = "no" ]; then + __initialize_data_dir + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Initialize SSL certificates + __initialize_ssl_certs + # - - - - - - - - - - - - - - - - - - - - - - - - - + # Mark directories as initialized (only write if not already initialized) + if [ -d "/config" ] && [ "$CONFIG_DIR_INITIALIZED" = "no" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_CONFIG_INIT_FILE" 2>/dev/null || true + CONFIG_DIR_INITIALIZED="yes" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - + if [ -d "/data" ] && [ "$DATA_DIR_INITIALIZED" = "no" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_DATA_INIT_FILE" 2>/dev/null || true + DATA_DIR_INITIALIZED="yes" + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - + if [ -d "/config" ] && [ ! -f "$ENTRYPOINT_INIT_FILE" ]; then + echo "Initialized on: $INIT_DATE" >"$ENTRYPOINT_INIT_FILE" 2>/dev/null || true + fi + # - - - - - - - - - - - - - - - - - - - - - - - - - # setup the smtp server __setup_mta + # - - - - - - - - - - - - - - - - - - - - - - - - - + ENTRYPOINT_FIRST_RUN="no" fi # - - - - - - - - - - - - - - - - - - - - - - - - - # if no pid assume container restart - clean stale files on restart if [ -f "$ENTRYPOINT_PID_FILE" ]; then - START_SERVICES="no" - touch "$ENTRYPOINT_PID_FILE" + # Check if the PID in the file is still running + entrypoint_pid=$(cat "$ENTRYPOINT_PID_FILE" 2>/dev/null || echo "") + if [ -n "$entrypoint_pid" ] && kill -0 "$entrypoint_pid" 2>/dev/null; then + # Process is still running, don't restart services + START_SERVICES="no" + touch "$ENTRYPOINT_PID_FILE" + else + # PID file exists but process is dead - this is a restart + START_SERVICES="yes" + # Clean any stale PID files on restart + rm -f /run/__start_init_scripts.pid /run/init.d/*.pid /run/*.pid 2>/dev/null || true + fi else START_SERVICES=yes # Clean any stale PID files on first run - rm -f /run/.start_init_scripts.pid /run/init.d/*.pid /run/*.pid 2>/dev/null || true + rm -f /run/__start_init_scripts.pid /run/init.d/*.pid /run/*.pid 2>/dev/null || true fi # - - - - - - - - - - - - - - - - - - - - - - - - - [ "$ENTRYPOINT_MESSAGE" = "yes" ] && __printf_space "40" "The containers ip address is:" "$CONTAINER_IP4_ADDRESS" @@ -411,6 +499,9 @@ if [ "$START_SERVICES" = "yes" ] || [ -z "$1" ]; then echo "$$" >"$ENTRYPOINT_PID_FILE" __start_init_scripts "/usr/local/etc/docker/init.d" CONTAINER_INIT="${CONTAINER_INIT:-no}" + # Services started successfully - enter monitoring mode + __no_exit + exit $? fi START_SERVICES="no" fi @@ -420,7 +511,7 @@ export START_SERVICES CONTAINER_INIT ENTRYPOINT_PID_FILE case "$1" in init) shift 1 - echo "Container has been Initialized" + __log_info "Container has been initialized" exit 0 ;; tail) @@ -451,7 +542,7 @@ logs) clean) log_files="$(find "/data/logs" -type f)" for log in "${log_files[@]}"; do - echo "clearing $log" + __log_info "Clearing log file: $log" printf '' >$log done ;; @@ -464,7 +555,7 @@ logs) cron) shift 1 __cron "$@" & - echo "cron script is running with pid: $!" + __log_info "Cron script is running with PID: $!" exit ;; # backup data and config dirs @@ -492,7 +583,7 @@ healthcheck) [ "$healthEnabled" = "yes" ] || exit 0 if [ -d "/run/healthcheck" ] && [ "$(ls -A "/run/healthcheck" | wc -l)" -ne 0 ]; then for service in /run/healthcheck/*; do - name=$(basename -- $service) + name="${service##*/}" services+="$name " done fi diff --git a/rootfs/usr/local/bin/pkmgr b/rootfs/usr/local/bin/pkmgr index 205c2b0..bebefdb 100755 --- a/rootfs/usr/local/bin/pkmgr +++ b/rootfs/usr/local/bin/pkmgr @@ -1,10 +1,10 @@ #!/usr/bin/env sh # shellcheck shell=sh # shellcheck disable=SC2016 -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - USER_UID="$(id -u)" USER_GID="$(id -g)" -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - if [ -x "$(command -v apt 2>/dev/null)" ]; then export DEBIAN_FRONTEND=noninteractive pkmgr_cmd="apt" @@ -58,7 +58,7 @@ else pkmgr_update_cmd="$pkmgr_cmd" pkmgr_install_cmd="$pkmgr_cmd" fi -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - if [ -f "/config/pkmgr/settings.conf" ]; then . "/config/pkmgr/settings.conf" elif [ -f "/etc/pkmgr/settings.conf" ]; then @@ -73,9 +73,9 @@ pkmgr_install_cmd="$pkmgr_install_cmd" pkmgr_mkcache_cmd="$pkmgr_mkcache_cmd" EEOF fi -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - [ -n "$pkmgr_cmd" ] || { echo "Can not determine the package manager" && exit 1; } -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - case "$1" in pip) shift 1 @@ -103,7 +103,7 @@ install) [ -n "$1" ] || exit 0 [ "$USER_UID" -eq 0 ] || [ "$USER" = "root" ] || pkmgr_install_cmd="sudo $pkmgr_install_cmd" if [ -f "$1" ]; then - install_list="$(cat "$1")" + install_list="$(tr '\n' ' ' < "$1")" else install_list="$*" fi @@ -138,5 +138,6 @@ clean) exit $? ;; esac -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# - - - - - - - - - - - - - - - - - - - - - - - - - # end + diff --git a/rootfs/usr/local/etc/docker/bin/start-ampache b/rootfs/usr/local/etc/docker/bin/start-ampache new file mode 100755 index 0000000..ccaedee --- /dev/null +++ b/rootfs/usr/local/etc/docker/bin/start-ampache @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +# casjaysdevdocker/ampache - launches php-fpm84 (background) then httpd (foreground). +# +# Single command for the framework's EXEC_CMD_BIN slot. +set -e + +mkdir -p /run/apache2 /run/php-fpm /tmp/php-sessions /data/logs/php-fpm /data/logs/apache2 +chown -Rf apache:apache /run/apache2 /run/php-fpm /tmp/php-sessions /data/logs/php-fpm /data/logs/apache2 2>/dev/null || true + +# php-fpm: daemonize=no per our config; we put it in background here. +if ! pgrep -x php-fpm84 >/dev/null 2>&1; then + /usr/sbin/php-fpm84 --fpm-config /etc/php84/php-fpm.conf >>/data/logs/php-fpm/stdout.log 2>>/data/logs/php-fpm/stderr.log & + # wait up to 10s for the unix socket + i=0 + while [ ! -S /run/php-fpm/php-fpm.sock ] && [ $i -lt 10 ]; do sleep 1; i=$((i+1)); done +fi + +# httpd in foreground (-D FOREGROUND). +exec /usr/sbin/httpd -D FOREGROUND -f /etc/apache2/httpd.conf diff --git a/rootfs/usr/local/etc/docker/init.d/09-mariadb.sh b/rootfs/usr/local/etc/docker/init.d/09-mariadb.sh new file mode 100755 index 0000000..666a6c7 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/09-mariadb.sh @@ -0,0 +1,347 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# casjaysdevdocker/ampache - mariadb init.d (runs before 99-ampache.sh) +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM EXIT +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +SCRIPT_FILE="$0" +SERVICE_NAME="mariadb" +__script_exit() { + local exit_code="${1:-0}" + if [ "${BASH_SOURCE[0]}" != "${0}" ]; then return "$exit_code"; else exit "$exit_code"; fi +} +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +if [ ! -f "/run/.start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + __script_exit 1 +fi +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +RESET_ENV="no" +WWW_ROOT_DIR="/usr/local/share/ampache/public" +DATA_DIR="/data/db/mariadb" +CONF_DIR="/config/my.cnf.d" +ETC_DIR="/etc/my.cnf.d" +VAR_DIR="" +TMP_DIR="/tmp/mysql" +RUN_DIR="/run/mysqld" +LOG_DIR="/data/logs/mariadb" +WORK_DIR="" +SERVICE_PORT="3306" +RUNAS_USER="root" +SERVICE_USER="mysql" +SERVICE_GROUP="mysql" +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +SERVICE_UID="0" +SERVICE_GID="0" +EXEC_CMD_BIN='mariadbd' +EXEC_CMD_ARGS='--user=$SERVICE_USER --datadir=$DATABASE_DIR --socket=/run/mysqld/mysqld.sock' +EXEC_PRE_SCRIPT='' +IS_WEB_SERVER="no" +IS_DATABASE_SERVICE="yes" +USES_DATABASE_SERVICE="no" +DATABASE_SERVICE_TYPE="mariadb" +PRE_EXEC_MESSAGE="" +POST_EXECUTE_WAIT_TIME="1" +PATH="$PATH:." +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +ROOT_FILE_PREFIX="/config/secure/auth/root" +USER_FILE_PREFIX="/config/secure/auth/user" +root_user_name="${MARIADB_ROOT_USER_NAME:-root}" +root_user_pass="${MARIADB_ROOT_PASS_WORD:-random}" +user_name="${MARIADB_USER_NAME:-ampache}" +user_pass="${MARIADB_USER_PASS_WORD:-random}" +DATABASE_CREATE="${DATABASE_CREATE:-ampache}" +[ -f "/config/env/mariadb.script.sh" ] && . "/config/env/mariadb.script.sh" +[ -f "/config/env/mariadb.sh" ] && . "/config/env/mariadb.sh" +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="" +APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR" +ADDITIONAL_CONFIG_DIRS="" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy() { + local hostname=${HOSTNAME} + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +__execute_prerun() { + local hostname=${HOSTNAME} + mkdir -p /run/mysqld /data/db/mariadb /data/logs/mariadb + chown -Rf mysql:mysql /run/mysqld /data/db/mariadb /data/logs/mariadb 2>/dev/null || true + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +__run_pre_execute_checks() { + local exitStatus=0 + local pre_execute_checks_MessageST="Running preexecute check for $SERVICE_NAME" + local pre_execute_checks_MessageEnd="Finished preexecute check for $SERVICE_NAME" + __banner "$pre_execute_checks_MessageST" + { + if [ ! -d "$DATABASE_DIR" ] || [ ! -f "$DATABASE_DIR/ibdata1" ] && [ ! -d "$DATABASE_DIR/mysql" ]; then + rm -Rf "${DATABASE_DIR:?}"/* + mkdir -p "$DATABASE_DIR" + chown -Rf $SERVICE_USER:$SERVICE_GROUP "$DATABASE_DIR" + mariadb-install-db --datadir=$DATABASE_DIR --user=$SERVICE_USER --auth-root-authentication-method=normal 2>/dev/null || \ + mysql_install_db --datadir=$DATABASE_DIR --user=$SERVICE_USER 2>/dev/null + fi + } + exitStatus=$? + __banner "$pre_execute_checks_MessageEnd: Status $exitStatus" + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + __script_exit 1 + fi + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + return $exitStatus +} +__update_conf_files() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + return $exitCode +} +__pre_execute() { + local exitCode=0 + sleep 5 + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + return $exitCode +} +__post_execute() { + local pid="" + local retVal=0 + local ctime=${POST_EXECUTE_WAIT_TIME:-1} + local waitTime=$((ctime * 60)) + local postMessageST="Running post commands for $SERVICE_NAME" + local postMessageEnd="Finished post commands for $SERVICE_NAME" + local DATABASE_ROOT_PASSWORD="${root_user_pass:-$(__random_password)}" + local db_root_user="${MYSQL_ROOT_USER_NAME:-root}" + echo "$DATABASE_ROOT_PASSWORD" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" 2>/dev/null || true + sleep $waitTime + ( + __banner "$postMessageST" + # Wait for socket + local i=0 + while [ ! -S /run/mysqld/mysqld.sock ] && [ $i -lt 30 ]; do sleep 1; i=$((i+1)); done + if [ -f "$CONF_DIR/init.sh" ]; then bash -c "$CONF_DIR/init.sh"; fi + if [ -n "$DATABASE_CREATE" ]; then + mariadb -v -u $db_root_user <"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + return $retVal +} +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + return $exitCode +} +__update_ssl_conf() { + local exitCode=0 + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + return $exitCode +} +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Generated by 09-mariadb.sh - edit to override defaults +#root_user_name="root" +#root_user_pass="random" +#user_name="ampache" +#user_pass="random" +#DATABASE_CREATE="ampache" +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + __run_precopy_local() { true; } + __execute_prerun_local() { true; } + __run_pre_execute_checks_local() { true; } + __update_conf_files_local() { true; } + __pre_execute_local() { true; } + __post_execute_local() { true; } + __pre_message_local() { true; } + __update_ssl_conf_local() { true; } + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +__run_start_script() { + local runExitCode=0 + local workdir="$(eval echo "${WORK_DIR:-}")" + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" + local name="$(eval echo "${EXEC_CMD_NAME:-}")" + local pre="$(eval echo "${EXEC_PRE_SCRIPT:-}")" + local extra_env="$(eval echo "${CMD_ENV//,/ }")" + local lc_type="$(eval echo "${LANG:-${LC_ALL:-$LC_CTYPE}}")" + local home="$(eval echo "${workdir//\/root/\/tmp\/docker}")" + local path="$(eval echo "$PATH")" + local message="$(eval echo "")" + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + if [ -z "$cmd" ]; then + __post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" + retVal=$? + echo "Initializing $SCRIPT_NAME has completed" + __script_exit $retVal + else + if [ ! -x "$cmd" ]; then echo "$name is not a valid executable"; return 2; fi + if __proc_check "$name" || __proc_check "$cmd"; then echo "$name is already running" >&2; return 0; fi + [ -n "$SERVICE_USER" ] && echo "Setting up $cmd to run as $SERVICE_USER" || SERVICE_USER="root" + [ -n "$SERVICE_PORT" ] && echo "$name will be running on port $SERVICE_PORT" || SERVICE_PORT="" + export cmd_exec="$cmd $args" + message="Starting service: $name $args" + [ -n "$su_exec" ] && echo "using $su_exec" | tee -a -p "/data/logs/init.txt" + echo "$message" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + execute_command="$(__trim "$su_exec $cmd_exec")" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;if [ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ]; then rm -Rf "\$SERVICE_PID_FILE"; fi; exit \$exitCode' EXIT +set -Eeo pipefail +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$execute_command 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 2 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $execute_command" >&2 +exit \$retVal +EOF + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + fi + return $runExitCode +} +__run_secure_function() { + local filesperms + for filesperms in "${USER_FILE_PREFIX}"/* "${ROOT_FILE_PREFIX}"/*; do + [ -e "$filesperms" ] && { chmod -Rf 600 "$filesperms"; chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null; } + done 2>/dev/null + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +SERVICE_EXIT_CODE=0 +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" +SERVICE_PID_NUMBER="$(__pgrep)" +EXEC_CMD_BIN="$(type -P "$EXEC_CMD_BIN" || echo "$EXEC_CMD_BIN")" +EXEC_PRE_SCRIPT="$(type -P "$EXEC_PRE_SCRIPT" || echo "$EXEC_PRE_SCRIPT")" +__check_service "$1" && SERVICE_IS_RUNNING=yes +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +if [ "$IS_DATABASE_SERVICE" = "yes" ]; then + DATABASE_USER_NORMAL="${ENV_DATABASE_USER:-${DATABASE_USER_NORMAL:-$user_name}}" + DATABASE_PASS_NORMAL="${ENV_DATABASE_PASSWORD:-${DATABASE_PASS_NORMAL:-$user_pass}}" + DATABASE_USER_ROOT="${ENV_DATABASE_ROOT_USER:-${DATABASE_USER_ROOT:-$root_user_name}}" + DATABASE_PASS_ROOT="${ENV_DATABASE_ROOT_PASSWORD:-${DATABASE_PASS_ROOT:-$root_user_pass}}" + [ -n "$DATABASE_PASS_NORMAL" ] && [ ! -f "${USER_FILE_PREFIX}/db_pass_user" ] && echo "$DATABASE_PASS_NORMAL" >"${USER_FILE_PREFIX}/db_pass_user" + [ -n "$DATABASE_PASS_ROOT" ] && [ ! -f "${ROOT_FILE_PREFIX}/db_pass_root" ] && echo "$DATABASE_PASS_ROOT" >"${ROOT_FILE_PREFIX}/db_pass_root" +fi +DATABASE_DIR="${DATABASE_DIR_MARIADB:-/data/db/mariadb}" +DATABASE_BASE_DIR="$DATABASE_DIR" +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +[ "$user_pass" = "random" ] && user_pass="$(__random_password ${RANDOM_PASS_USER:-16})" +[ "$root_user_pass" = "random" ] && root_user_pass="$(__random_password ${RANDOM_PASS_ROOT:-16})" +[ -n "$user_name" ] && echo "$user_name" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$user_pass" ] && echo "$user_pass" >"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -n "$root_user_name" ] && echo "$root_user_name" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" +[ -n "$root_user_pass" ] && echo "$root_user_pass" >"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_name" && user_name="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${USER_FILE_PREFIX}/${SERVICE_NAME}_pass" && user_pass="$(<"${USER_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name" && root_user_name="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_name")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass" && root_user_pass="$(<"${ROOT_FILE_PREFIX}/${SERVICE_NAME}_pass")" +__file_exists_with_content "${USER_FILE_PREFIX}/db_pass_user" && DATABASE_PASS_NORMAL="$(<"${USER_FILE_PREFIX}/db_pass_user")" +__file_exists_with_content "${ROOT_FILE_PREFIX}/db_pass_root" && DATABASE_PASS_ROOT="$(<"${ROOT_FILE_PREFIX}/db_pass_root")" +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +__create_service_env +__init_config_etc +__execute_prerun +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +__setup_directories +__switch_to_user +__init_working_dir +__pre_message +__initialize_db_users +__update_ssl_conf +__update_ssl_certs +__run_secure_function +__run_precopy +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +__initialize_database +__update_conf_files +__pre_execute +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then SERVICE_EXIT_CODE=0; SERVICE_IS_RUNNING="yes"; else SERVICE_EXIT_CODE=$errorCode; SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}"; [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE"; fi + SERVICE_EXIT_CODE=0 +fi +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +__script_exit $SERVICE_EXIT_CODE diff --git a/rootfs/usr/local/etc/docker/init.d/99-ampache.sh b/rootfs/usr/local/etc/docker/init.d/99-ampache.sh new file mode 100755 index 0000000..202ed44 --- /dev/null +++ b/rootfs/usr/local/etc/docker/init.d/99-ampache.sh @@ -0,0 +1,280 @@ +#!/usr/bin/env bash +# shellcheck shell=bash +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# casjaysdevdocker/ampache - apache + php-fpm init.d (runs after 09-mariadb.sh) +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# shellcheck disable=SC1003,SC2016,SC2031,SC2120,SC2155,SC2199,SC2317 +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +trap 'retVal=$?;[ "$SERVICE_IS_RUNNING" != "yes" ] && [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE";exit $retVal' SIGINT SIGTERM EXIT +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +[ -f "/config/.debug" ] && [ -z "$DEBUGGER_OPTIONS" ] && export DEBUGGER_OPTIONS="$(<"/config/.debug")" || DEBUGGER_OPTIONS="${DEBUGGER_OPTIONS:-}" +{ [ "$DEBUGGER" = "on" ] || [ -f "/config/.debug" ]; } && echo "Enabling debugging" && set -xo pipefail -x$DEBUGGER_OPTIONS && export DEBUGGER="on" || set -o pipefail +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +export PATH="/usr/local/etc/docker/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin" +SCRIPT_FILE="$0" +SERVICE_NAME="ampache" +__script_exit() { + local exit_code="${1:-0}" + if [ "${BASH_SOURCE[0]}" != "${0}" ]; then return "$exit_code"; else exit "$exit_code"; fi +} +SCRIPT_NAME="$(basename -- "$SCRIPT_FILE" 2>/dev/null)" +if [ ! -f "/run/.start_init_scripts.pid" ]; then + echo "__start_init_scripts function hasn't been Initialized" >&2 + SERVICE_IS_RUNNING="no" + __script_exit 1 +fi +if [ -f "/usr/local/etc/docker/functions/entrypoint.sh" ]; then + . "/usr/local/etc/docker/functions/entrypoint.sh" +fi +for set_env in "/root/env.sh" "/usr/local/etc/docker/env"/*.sh "/config/env"/*.sh; do + [ -f "$set_env" ] && . "$set_env" +done +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +START_SCRIPT="/usr/local/etc/docker/exec/$SERVICE_NAME" +RESET_ENV="no" +WWW_ROOT_DIR="/usr/local/share/ampache/public" +DATA_DIR="/data/ampache" +CONF_DIR="/config/apache2" +ETC_DIR="/etc/apache2" +VAR_DIR="" +TMP_DIR="/tmp/ampache" +RUN_DIR="/run/apache2" +LOG_DIR="/data/logs/apache2" +WORK_DIR="" +SERVICE_PORT="80" +RUNAS_USER="root" +SERVICE_USER="apache" +SERVICE_GROUP="apache" +RANDOM_PASS_USER="" +RANDOM_PASS_ROOT="" +SERVICE_UID="0" +SERVICE_GID="0" +EXEC_CMD_BIN='/usr/local/etc/docker/bin/start-ampache' +EXEC_CMD_ARGS='' +EXEC_PRE_SCRIPT='' +IS_WEB_SERVER="yes" +IS_DATABASE_SERVICE="no" +USES_DATABASE_SERVICE="yes" +DATABASE_SERVICE_TYPE="mariadb" +PRE_EXEC_MESSAGE="Open http://localhost:${SERVICE_PORT:-80}/ to run the Ampache web installer." +POST_EXECUTE_WAIT_TIME="1" +PATH="$PATH:." +IP4_ADDRESS="$(__get_ip4)" +IP6_ADDRESS="$(__get_ip6)" +ROOT_FILE_PREFIX="/config/secure/auth/root" +USER_FILE_PREFIX="/config/secure/auth/user" +root_user_name="${AMPACHE_ROOT_USER_NAME:-}" +root_user_pass="${AMPACHE_ROOT_PASS_WORD:-}" +user_name="${AMPACHE_USER_NAME:-}" +user_pass="${AMPACHE_USER_PASS_WORD:-}" +[ -f "/config/env/ampache.script.sh" ] && . "/config/env/ampache.script.sh" +[ -f "/config/env/ampache.sh" ] && . "/config/env/ampache.sh" +ADD_APPLICATION_FILES="" +ADD_APPLICATION_DIRS="/usr/local/share/ampache /usr/local/share/ampache/config /tmp/php-sessions" +APPLICATION_FILES="$LOG_DIR/$SERVICE_NAME.log" +APPLICATION_DIRS="$ETC_DIR $CONF_DIR $LOG_DIR $TMP_DIR $RUN_DIR $VAR_DIR /run/php-fpm /data/logs/php-fpm" +ADDITIONAL_CONFIG_DIRS="/config/php84 /config/ampache" +CMD_ENV="" +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__run_precopy() { + local hostname=${HOSTNAME} + if builtin type -t __run_precopy_local | grep -q 'function'; then __run_precopy_local; fi +} +__execute_prerun() { + local hostname=${HOSTNAME} + # Ensure runtime dirs + mkdir -p /run/apache2 /run/php-fpm /tmp/php-sessions \ + /data/logs/apache2 /data/logs/php-fpm /data/ampache + chown -Rf apache:apache /run/apache2 /run/php-fpm /tmp/php-sessions \ + /data/logs/apache2 /data/logs/php-fpm 2>/dev/null || true + # Ampache writable dirs + if [ -d /usr/local/share/ampache ]; then + mkdir -p /usr/local/share/ampache/config + chown -Rf apache:apache /usr/local/share/ampache/config 2>/dev/null || true + # Live ampache.cfg.php is mirrored out to /config/ampache/ once install.php writes it. + if [ -f /usr/local/share/ampache/config/ampache.cfg.php ] && [ ! -L /usr/local/share/ampache/config/ampache.cfg.php ]; then + cp -f /usr/local/share/ampache/config/ampache.cfg.php /config/ampache/ampache.cfg.php 2>/dev/null || true + ln -sf /config/ampache/ampache.cfg.php /usr/local/share/ampache/config/ampache.cfg.php + elif [ -f /config/ampache/ampache.cfg.php ] && [ ! -e /usr/local/share/ampache/config/ampache.cfg.php ]; then + ln -sf /config/ampache/ampache.cfg.php /usr/local/share/ampache/config/ampache.cfg.php + fi + fi + if builtin type -t __execute_prerun_local | grep -q 'function'; then __execute_prerun_local; fi +} +__run_pre_execute_checks() { + local exitStatus=0 + __banner "Running preexecute check for $SERVICE_NAME" + # Wait briefly for mariadb socket + local i=0 + while [ ! -S /run/mysqld/mysqld.sock ] && [ $i -lt 30 ]; do sleep 1; i=$((i+1)); done + if [ ! -S /run/mysqld/mysqld.sock ]; then + echo "Warning: mariadb socket not found after 30s; ampache install.php will need it before continuing" >&2 + fi + # Validate apache config syntax + httpd -t -f /etc/apache2/httpd.conf 2>&1 | head -20 || exitStatus=$? + __banner "Finished preexecute check for $SERVICE_NAME: Status $exitStatus" + if [ $exitStatus -ne 0 ]; then + echo "The pre-execution check has failed" >&2 + [ -f "$SERVICE_PID_FILE" ] && rm -Rf "$SERVICE_PID_FILE" + __script_exit 1 + fi + if builtin type -t __run_pre_execute_checks_local | grep -q 'function'; then __run_pre_execute_checks_local; fi + return $exitStatus +} +__update_conf_files() { + local exitCode=0 + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" + __replace "REPLACE_TZ" "${TZ:-UTC}" "/etc/php84/php.ini" + if builtin type -t __update_conf_files_local | grep -q 'function'; then __update_conf_files_local; fi + return $exitCode +} +__pre_execute() { + local exitCode=0 + sleep 5 + if builtin type -t __pre_execute_local | grep -q 'function'; then __pre_execute_local; fi + return $exitCode +} +__post_execute() { + local pid="" + local retVal=0 + local ctime=${POST_EXECUTE_WAIT_TIME:-1} + local waitTime=$((ctime * 60)) + sleep $waitTime + ( + __banner "Running post commands for $SERVICE_NAME" + # Mirror live ampache.cfg.php out to /config once install.php has written it + if [ -f /usr/local/share/ampache/config/ampache.cfg.php ] && [ ! -L /usr/local/share/ampache/config/ampache.cfg.php ]; then + cp -f /usr/local/share/ampache/config/ampache.cfg.php /config/ampache/ampache.cfg.php + ln -sf /config/ampache/ampache.cfg.php /usr/local/share/ampache/config/ampache.cfg.php + fi + __banner "Finished post commands for $SERVICE_NAME: Status $retVal" + ) 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & + pid=$! + if builtin type -t __post_execute_local | grep -q 'function'; then __post_execute_local; fi + return $retVal +} +__pre_message() { + local exitCode=0 + [ -n "$PRE_EXEC_MESSAGE" ] && eval echo "$PRE_EXEC_MESSAGE" + if builtin type -t __pre_message_local | grep -q 'function'; then __pre_message_local; fi + return $exitCode +} +__update_ssl_conf() { + local exitCode=0 + if builtin type -t __update_ssl_conf_local | grep -q 'function'; then __update_ssl_conf_local; fi + return $exitCode +} +__create_service_env() { + local exitCode=0 + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ]; then + cat </dev/null +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +# Generated by 99-ampache.sh - edit to override defaults +#user_name="" +#user_pass="" +EOF + fi + if [ ! -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" ]; then + __run_precopy_local() { true; } + __execute_prerun_local() { true; } + __run_pre_execute_checks_local() { true; } + __update_conf_files_local() { true; } + __pre_execute_local() { true; } + __post_execute_local() { true; } + __pre_message_local() { true; } + __update_ssl_conf_local() { true; } + fi + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" || exitCode=$((exitCode + 1)) + __file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" || exitCode=$((exitCode + 1)) + return $exitCode +} +__run_start_script() { + local runExitCode=0 + local cmd="$(eval echo "${EXEC_CMD_BIN:-}")" + local args="$(eval echo "${EXEC_CMD_ARGS:-}")" + local name="$(eval echo "${EXEC_CMD_NAME:-}")" + local sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" + [ -f "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" ] && . "$CONF_DIR/$SERVICE_NAME.exec_cmd.sh" + if [ ! -x "$cmd" ]; then echo "$cmd is not executable" >&2; return 2; fi + if __proc_check "httpd"; then echo "httpd already running" >&2; return 0; fi + echo "Starting $cmd $args" | tee -a -p "/data/logs/init.txt" + su_cmd touch "$SERVICE_PID_FILE" + if [ ! -f "$START_SCRIPT" ]; then + cat <"$START_SCRIPT" +#!/usr/bin/env bash +trap 'exitCode=\$?;if [ \$exitCode -ne 0 ] && [ -f "\$SERVICE_PID_FILE" ]; then rm -Rf "\$SERVICE_PID_FILE"; fi; exit \$exitCode' EXIT +set -Eeo pipefail +retVal=10 +cmd="$cmd" +SERVICE_NAME="$SERVICE_NAME" +SERVICE_PID_FILE="$SERVICE_PID_FILE" +$cmd $args 2>>"/dev/stderr" >>"$LOG_DIR/$SERVICE_NAME.log" & +execPid=\$! +sleep 3 +checkPID="\$(ps ax | awk '{print \$1}' | grep -v grep | grep "\$execPid$" || false)" +[ -n "\$execPid" ] && [ -n "\$checkPID" ] && echo "\$execPid" >"\$SERVICE_PID_FILE" && retVal=0 || retVal=10 +[ "\$retVal" = 0 ] && echo "\$cmd has been started" || echo "Failed to start $cmd $args" >&2 +exit \$retVal +EOF + fi + [ -x "$START_SCRIPT" ] || chmod 755 -Rf "$START_SCRIPT" + [ "$CONTAINER_INIT" = "yes" ] || eval sh -c "$START_SCRIPT" + runExitCode=$? + return $runExitCode +} +__run_secure_function() { + local filesperms + for filesperms in "${USER_FILE_PREFIX}"/* "${ROOT_FILE_PREFIX}"/*; do + [ -e "$filesperms" ] && { chmod -Rf 600 "$filesperms"; chown -Rf $SERVICE_USER:$SERVICE_USER "$filesperms" 2>/dev/null; } + done 2>/dev/null + unset filesperms +} +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +__file_exists_with_content "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.local.sh" +SERVICE_EXIT_CODE=0 +EXEC_CMD_NAME="$(basename -- "$EXEC_CMD_BIN")" +SERVICE_PID_FILE="/run/init.d/$EXEC_CMD_NAME.pid" +SERVICE_PID_NUMBER="$(__pgrep)" +__check_service "$1" && SERVICE_IS_RUNNING=yes +[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" +[ -d "$RUN_DIR" ] || mkdir -p "$RUN_DIR" +[ -n "$USER_FILE_PREFIX" ] && { [ -d "$USER_FILE_PREFIX" ] || mkdir -p "$USER_FILE_PREFIX"; } +[ -n "$ROOT_FILE_PREFIX" ] && { [ -d "$ROOT_FILE_PREFIX" ] || mkdir -p "$ROOT_FILE_PREFIX"; } +[ -n "$RUNAS_USER" ] || RUNAS_USER="root" +[ -n "$SERVICE_USER" ] || SERVICE_USER="$RUNAS_USER" +[ -n "$SERVICE_GROUP" ] || SERVICE_GROUP="${SERVICE_USER:-$RUNAS_USER}" +[ "$IS_WEB_SERVER" = "yes" ] && RESET_ENV="yes" && __is_htdocs_mounted +[ "$IS_WEB_SERVER" = "yes" ] && [ -z "$SERVICE_PORT" ] && SERVICE_PORT="80" +[ -f "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" ] && . "/config/env/${SERVICE_NAME:-$SCRIPT_NAME}.sh" +sysname="${SERVER_NAME:-${FULL_DOMAIN_NAME:-$HOSTNAME}}" +__create_service_env +__init_config_etc +__execute_prerun +__create_service_user "$SERVICE_USER" "$SERVICE_GROUP" "${WORK_DIR:-/home/$SERVICE_USER}" "${SERVICE_UID:-}" "${SERVICE_GID:-}" +__set_user_group_id $SERVICE_USER ${SERVICE_UID:-} ${SERVICE_GID:-} +__setup_directories +__switch_to_user +__init_working_dir +__pre_message +__update_ssl_conf +__update_ssl_certs +__run_secure_function +__run_precopy +for config_2_etc in $CONF_DIR $ADDITIONAL_CONFIG_DIRS; do + __initialize_system_etc "$config_2_etc" 2>/dev/stderr | tee -p -a "/data/logs/init.txt" +done +__initialize_replace_variables "$ETC_DIR" "$CONF_DIR" "$ADDITIONAL_CONFIG_DIRS" "$WWW_ROOT_DIR" +__update_conf_files +__pre_execute +__fix_permissions "$SERVICE_USER" "$SERVICE_GROUP" +__run_pre_execute_checks 2>/dev/stderr | tee -a -p "/data/logs/entrypoint.log" "/data/logs/init.txt" || return 20 +__run_start_script 2>>/dev/stderr | tee -p -a "/data/logs/entrypoint.log" +errorCode=$? +if [ -n "$EXEC_CMD_BIN" ]; then + if [ "$errorCode" -eq 0 ]; then SERVICE_EXIT_CODE=0; SERVICE_IS_RUNNING="yes"; else SERVICE_EXIT_CODE=$errorCode; SERVICE_IS_RUNNING="${SERVICE_IS_RUNNING:-no}"; [ -s "$SERVICE_PID_FILE" ] || rm -Rf "$SERVICE_PID_FILE"; fi + SERVICE_EXIT_CODE=0 +fi +__post_execute 2>"/dev/stderr" | tee -p -a "/data/logs/init.txt" & +__banner "Initializing of $SERVICE_NAME has completed with statusCode: $SERVICE_EXIT_CODE" | tee -p -a "/data/logs/entrypoint.log" "/data/logs/init.txt" +__script_exit $SERVICE_EXIT_CODE