From fdcb63f25168aaf9292c06f1743298750b2d6e6b Mon Sep 17 00:00:00 2001 From: Mateus Villar <mromeravillar@gmail.com> Date: Wed, 21 Apr 2021 01:14:47 -0300 Subject: [PATCH] Added #9313: Add new fpm-alpine docker image and docker secrets support (#9331) * Add docker secret support * Add docker secret support to selected environment variables below: - APP_KEY_FILE -> APP_KEY; - DB_HOST_FILE -> DB_HOST; - DB_PORT_FILE -> DB_PORT; - DB_DATABASE_FILE -> DB_DATABASE; - DB_USERNAME_FILE -> DB_USERNAME; - DB_PASSWORD_FILE -> DB_PASSWORD; - REDIS_HOST_FILE -> REDIS_HOST; - REDIS_PASSWORD_FILE -> REDIS_PASSWORD; - REDIS_PORT_FILE -> REDIS_PORT; - MAIL_HOST_FILE -> MAIL_HOST; - MAIL_PORT_FILE -> MAIL_PORT; - MAIL_USERNAME_FILE -> MAIL_USERNAME; - MAIL_PASSWORD_FILE -> MAIL_PASSWORD; * Add env file for docker secrets * Added #9313: add new fpm-image using docker secrets * Fix broken symlinks * Add docker secrets support using shell script * Remove old docker config php files --- Dockerfile.fpm-alpine | 102 +++++++++++++++++++++++++++++++ docker/docker-entrypoint.sh | 119 ++++++++++++++++++++++++++++++++++++ docker/docker-secrets.env | 54 ++++++++++++++++ 3 files changed, 275 insertions(+) create mode 100644 Dockerfile.fpm-alpine create mode 100755 docker/docker-entrypoint.sh create mode 100644 docker/docker-secrets.env diff --git a/Dockerfile.fpm-alpine b/Dockerfile.fpm-alpine new file mode 100644 index 000000000..3452a6f89 --- /dev/null +++ b/Dockerfile.fpm-alpine @@ -0,0 +1,102 @@ +ARG ENVIRONMENT=production +ARG SNIPEIT_RELEASE=5.1.3 +ARG PHP_VERSION=7.4.16 +ARG PHP_ALPINE_VERSION=3.13 +ARG COMPOSER_VERSION=2.0.11 + +# Cannot use arguments with 'COPY --from' workaround +# https://github.com/moby/moby/issues/34482#issuecomment-454716952 +FROM composer:${COMPOSER_VERSION} AS composer + +# Final stage +FROM php:${PHP_VERSION}-fpm-alpine${PHP_ALPINE_VERSION} AS source +LABEL maintainer="Mateus Villar <mromeravillar@gmail.com>" + +ARG PACKAGES="\ + mysql-client \ +" +ARG DEV_PACKAGES="\ + git \ +" +ARG ENVIRONMENT +ENV ENVIRONMENT ${ENVIRONMENT} +ARG SNIPEIT_RELEASE +ENV SNIPEIT_RELEASE ${SNIPEIT_RELEASE} + +# Cribbed from wordpress-fpm-alpine image +# set recommended PHP.ini settings +# see https://secure.php.net/manual/en/opcache.installation.php +RUN set -eux; \ + docker-php-ext-enable opcache; \ + { \ + echo 'opcache.memory_consumption=128'; \ + echo 'opcache.interned_strings_buffer=8'; \ + echo 'opcache.max_accelerated_files=4000'; \ + echo 'opcache.revalidate_freq=2'; \ + echo 'opcache.fast_shutdown=1'; \ + } > /usr/local/etc/php/conf.d/opcache-recommended.ini +# https://wordpress.org/support/article/editing-wp-config-php/#configure-error-logging +RUN { \ +# https://www.php.net/manual/en/errorfunc.constants.php +# https://github.com/docker-library/wordpress/issues/420#issuecomment-517839670 + echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR'; \ + echo 'display_errors = Off'; \ + echo 'display_startup_errors = Off'; \ + echo 'log_errors = On'; \ + echo 'error_log = /dev/stderr'; \ + echo 'log_errors_max_len = 1024'; \ + echo 'ignore_repeated_errors = On'; \ + echo 'ignore_repeated_source = Off'; \ + echo 'html_errors = Off'; \ + } > /usr/local/etc/php/conf.d/error-logging.ini + +# Install php extensions inside docker containers easily +# https://github.com/mlocati/docker-php-extension-installer +COPY --from=mlocati/php-extension-installer:1.2.19 /usr/bin/install-php-extensions /usr/local/bin/ +RUN set -eux; \ + install-php-extensions \ + bcmath \ + gd \ + ldap \ + mysqli \ + pdo_mysql \ + zip; \ + rm -f /usr/local/bin/install-php-extensions; \ +# Install prerequisites packages + apk add --no-cache \ + ${PACKAGES}; + +COPY --from=composer /usr/bin/composer /usr/local/bin +ARG COMPOSER_ALLOW_SUPERUSER=1 +RUN set -eux; \ +# Download and extract snipeit tarball + curl -o snipeit.tar.gz -fL "https://github.com/snipe/snipe-it/archive/v$SNIPEIT_RELEASE.tar.gz"; \ + tar -xzf snipeit.tar.gz --strip-components=1 -C /var/www/html/; \ + rm snipeit.tar.gz; \ +# Install composer php dependencies + if [ "$ENVIRONMENT" = "production" ]; then \ + echo "production enviroment detected!"; \ + composer update \ + --no-cache \ + --no-dev \ + --optimize-autoloader \ + --working-dir=/var/www/html; \ + else \ + echo "development enviroment detected!"; \ + apk add --no-cache \ + ${DEV_PACKAGES}; \ + composer update \ + --no-cache \ + --prefer-source \ + --optimize-autoloader \ + --working-dir=/var/www/html; \ + fi; \ + rm -f /usr/local/bin/composer; \ + chown -R www-data:www-data /var/www/html; + +VOLUME [ "/var/lib/snipeit" ] + +COPY --chown=www-data:www-data docker/docker-secrets.env /var/www/html/.env +COPY --chmod=655 docker/docker-entrypoint.sh /usr/local/bin/docker-snipeit-entrypoint +ENTRYPOINT [ "/usr/local/bin/docker-snipeit-entrypoint" ] +CMD [ "/usr/local/bin/docker-php-entrypoint", "php-fpm" ] \ No newline at end of file diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 000000000..3b783419e --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,119 @@ +#!/bin/sh + +set -eo pipefail; + +# Cribbed from nextcloud docker official repo +# https://github.com/nextcloud/docker/blob/master/docker-entrypoint.sh +# usage: file_env VAR [DEFAULT] +# ie: file_env 'XYZ_DB_PASSWORD' 'example' +# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of +# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature) +file_env() { + local var="$1" + local fileVar="${var}_FILE" + local def="${2:-}" + local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//") + local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//") + if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then + echo >&2 "error: both $var and $fileVar are set (but are exclusive)" + exit 1 + fi + if [ -n "${varValue}" ]; then + export "$var"="${varValue}" + elif [ -n "${fileVarValue}" ]; then + export "$var"="$(cat "${fileVarValue}")" + elif [ -n "${def}" ]; then + export "$var"="$def" + fi + unset "$fileVar" +} + +# Add docker secrets support for the variables below: +file_env APP_KEY +file_env DB_HOST +file_env DB_PORT +file_env DB_DATABASE +file_env DB_USERNAME +file_env DB_PASSWORD +file_env REDIS_HOST +file_env REDIS_PASSWORD +file_env REDIS_PORT +file_env MAIL_HOST +file_env MAIL_PORT +file_env MAIL_USERNAME +file_env MAIL_PASSWORD + +echo [INFO docker entrypoint] Start script execution + +# Generate new app key if none is provided +if [ -z "$APP_KEY" -a -z "$APP_KEY_FILE" ] +then + echo "Please re-run this container with an environment variable \$APP_KEY" + echo "An example APP_KEY you could use is: " + php artisan key:generate --show + exit +fi + +# Directory configuration +rm -rf \ + "/var/www/html/storage/private_uploads" \ + "/var/www/html/public/uploads" \ + "/var/www/html/storage/app/backups" + +# Create data directories +for dir in \ + 'data/private_uploads' \ + 'data/uploads/accessories' \ + 'data/uploads/avatars' \ + 'data/uploads/barcodes' \ + 'data/uploads/categories' \ + 'data/uploads/companies' \ + 'data/uploads/components' \ + 'data/uploads/consumables' \ + 'data/uploads/departments' \ + 'data/uploads/locations' \ + 'data/uploads/manufacturers' \ + 'data/uploads/models' \ + 'data/uploads/suppliers' \ + 'dumps' \ + 'keys' +do + [ ! -d "/var/lib/snipeit/$dir" ] && mkdir -p "/var/lib/snipeit/$dir" +done + +# Sync /var/lib/snipeit (docker volume) with /var/www/html directory +ln -fs \ + "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" +ln -fs \ + "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" +ln -fs \ + "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" +ln -fs \ + "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" +ln -fs \ + "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" + +# If the Oauth DB files are not present copy the vendor files over to the db migrations +if [ ! -f "/var/www/html/database/migrations/*create_oauth*" ] +then + cp -a /var/www/html/vendor/laravel/passport/database/migrations/* /var/www/html/database/migrations/ +fi + +# Create laravel log file +touch /var/www/html/storage/logs/laravel.log +# Add correct permissions for files and directories +chown www-data:www-data /var/www/html/storage/logs/laravel.log +chown -R www-data:www-data \ + /var/lib/snipeit/data \ + /var/lib/snipeit/dumps \ + /var/lib/snipeit/keys + +# Migrate/create database +php artisan migrate --force +# Clear cache files +php artisan config:clear +php artisan config:cache + +echo [INFO docker entrypoint] End script execution + +exec "$@" \ No newline at end of file diff --git a/docker/docker-secrets.env b/docker/docker-secrets.env new file mode 100644 index 000000000..45a777f5d --- /dev/null +++ b/docker/docker-secrets.env @@ -0,0 +1,54 @@ +# -------------------------------------------- +# REQUIRED: BASIC APP SETTINGS +# -------------------------------------------- +#APP_ENV=develop +#APP_DEBUG=false +#APP_KEY=Change_this_key_or_snipe_will_get_ya +#APP_URL=http://127.0.0.1:32782 +#APP_TIMEZONE=US/Pacific +#APP_LOCALE=en + + +# -------------------------------------------- +# REQUIRED: DATABASE SETTINGS +# -------------------------------------------- +DB_CONNECTION=mysql +DB_PREFIX=null +DB_DUMP_PATH='/usr/bin' + + +# -------------------------------------------- +# REQUIRED: OUTGOING MAIL SERVER SETTINGS +# -------------------------------------------- +MAIL_DRIVER=smtp +MAIL_ENCRYPTION=${MAIL_ENV_ENCRYPTION} +MAIL_FROM_ADDR=${MAIL_ENV_FROM_ADDR} +MAIL_FROM_NAME=${MAIL_ENV_FROM_NAME} +MAIL_REPLYTO_ADDR=${MAIL_ENV_FROM_ADDR} +MAIL_REPLYTO_NAME=${MAIL_ENV_FROM_NAME} + + +# -------------------------------------------- +# REQUIRED: IMAGE LIBRARY +# This should be gd or imagick +# -------------------------------------------- +IMAGE_LIB=gd + + +# -------------------------------------------- +# OPTIONAL: SESSION SETTINGS +# -------------------------------------------- +SESSION_LIFETIME=12000 +EXPIRE_ON_CLOSE=false +ENCRYPT=false +COOKIE_NAME=snipeit_session +COOKIE_DOMAIN=null +SECURE_COOKIES=false + + +# -------------------------------------------- +# OPTIONAL: CACHE SETTINGS +# -------------------------------------------- +CACHE_DRIVER=file +SESSION_DRIVER=file +QUEUE_DRIVER=sync -- GitLab