Переглянути джерело

more refactoring for templating

Christian Winther 1 рік тому
батько
коміт
c369ef50a7

+ 11 - 16
contrib/docker/Dockerfile

@@ -86,10 +86,10 @@ WORKDIR /var/www/
 ENV APT_PACKAGES_EXTRA=${APT_PACKAGES_EXTRA}
 
 # Install and configure base layer
-COPY contrib/docker/install/base.sh /install/base.sh
+COPY contrib/docker/shared/root/docker/install/base.sh /docker/install/base.sh
 RUN --mount=type=cache,id=pixelfed-apt-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/lib/apt \
 	--mount=type=cache,id=pixelfed-apt-cache-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/cache/apt \
-    /install/base.sh
+    /docker/install/base.sh
 
 #######################################################
 # PHP: extensions
@@ -115,11 +115,11 @@ ENV PHP_PECL_EXTENSIONS=${PHP_PECL_EXTENSIONS}
 ENV PHP_VERSION=${PHP_VERSION}
 ENV TARGETPLATFORM=${TARGETPLATFORM}
 
-COPY contrib/docker/install/php-extensions.sh /install/php-extensions.sh
+COPY contrib/docker/shared/root/docker/install/php-extensions.sh /docker/install/php-extensions.sh
 RUN --mount=type=cache,id=pixelfed-php-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/usr/src/php/ \
     --mount=type=cache,id=pixelfed-apt-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/lib/apt \
 	--mount=type=cache,id=pixelfed-apt-cache-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/cache/apt \
-    /install/php-extensions.sh
+    /docker/install/php-extensions.sh
 
 #######################################################
 # PHP: composer and source code
@@ -183,18 +183,15 @@ COPY --link --from=php-extensions /usr/local/lib/php/extensions /usr/local/lib/p
 COPY --link --from=php-extensions /usr/local/etc/php /usr/local/etc/php
 COPY --link --from=composer-and-src --chown=${RUNTIME_UID}:${RUNTIME_GID} /var/www /var/www
 COPY --link --from=forego-image /usr/local/bin/forego /usr/local/bin/forego
-COPY --link contrib/docker/php.production.ini "$PHP_INI_DIR/php.ini"
 
 # for detail why storage is copied this way, pls refer to https://github.com/pixelfed/pixelfed/pull/2137#discussion_r434468862
 RUN set -ex \
 	&& cp --recursive --link --preserve=all storage storage.skel \
 	&& rm -rf html && ln -s public html
 
-COPY contrib/docker/docker-entrypoint.sh /docker-entrypoint.sh
-COPY contrib/docker/shared/lib.sh /lib.sh
-COPY contrib/docker/shared/docker-entrypoint.d /docker-entrypoint.d/
+COPY contrib/docker/shared/root /
 
-ENTRYPOINT ["/docker-entrypoint.sh"]
+ENTRYPOINT ["/docker/entrypoint.sh"]
 
 VOLUME /var/www/storage /var/www/bootstrap
 
@@ -204,8 +201,7 @@ VOLUME /var/www/storage /var/www/bootstrap
 
 FROM shared-runtime AS apache-runtime
 
-COPY --link contrib/docker/apache/conf-available/remoteip.conf /etc/apache2/conf-available/remoteip.conf
-COPY --link contrib/docker/apache/docker-entrypoint.d /docker-entrypoint.d/
+COPY contrib/docker/apache/root /
 
 RUN set -ex \
 	&& a2enmod rewrite remoteip proxy proxy_http \
@@ -221,7 +217,7 @@ EXPOSE 80
 
 FROM shared-runtime AS fpm-runtime
 
-COPY --link contrib/docker/fpm/docker-entrypoint.d /docker-entrypoint.d/
+COPY contrib/docker/fpm/root /
 
 CMD ["php-fpm"]
 
@@ -252,10 +248,9 @@ RUN --mount=type=cache,id=pixelfed-apt-lists-${PHP_VERSION}-${PHP_DEBIAN_RELEASE
 		nginx=${NGINX_VERSION}*
 
 # copy docker entrypoints from the *real* nginx image directly
-COPY --link --from=nginx-image /docker-entrypoint.d /docker-entrypoint.d/
-COPY --link contrib/docker/nginx/docker-entrypoint.d /docker-entrypoint.d/
-COPY --link contrib/docker/nginx/default-http.conf /etc/nginx/templates/default.conf.template
-COPY --link contrib/docker/nginx/Procfile .
+COPY --link --from=nginx-image /docker-entrypoint.d /docker/entrypoint.d/
+COPY contrib/docker/nginx/root /
+COPY contrib/docker/nginx/Procfile .
 
 EXPOSE 80
 

+ 4 - 0
contrib/docker/apache/conf-available/remoteip.conf → contrib/docker/apache/root/etc/apache2/conf-available/remoteip.conf

@@ -1,4 +1,8 @@
 RemoteIPHeader X-Real-IP
+
+# All private IPs as outlined in rfc1918
+#
+# See: https://datatracker.ietf.org/doc/html/rfc1918
 RemoteIPTrustedProxy 10.0.0.0/8
 RemoteIPTrustedProxy 172.16.0.0/12
 RemoteIPTrustedProxy 192.168.0.0/16

+ 0 - 45
contrib/docker/docker-entrypoint.sh

@@ -1,45 +0,0 @@
-#!/bin/bash
-# vim:sw=4:ts=4:et
-
-set -e
-
-source /lib.sh
-
-mkdir -p /docker-entrypoint.d/
-
-if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
-	entrypoint_log "/docker-entrypoint.d/ is not empty, will attempt to perform configuration"
-
-	entrypoint_log "looking for shell scripts in /docker-entrypoint.d/"
-	find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
-		case "$f" in
-			*.envsh)
-				if [ -x "$f" ]; then
-					entrypoint_log "Sourcing $f";
-					. "$f"
-				else
-					# warn on shell scripts without exec bit
-					entrypoint_log "Ignoring $f, not executable";
-				fi
-				;;
-
-			*.sh)
-				if [ -x "$f" ]; then
-					entrypoint_log "Launching $f";
-					"$f"
-				else
-					# warn on shell scripts without exec bit
-					entrypoint_log "Ignoring $f, not executable";
-				fi
-				;;
-
-			*) entrypoint_log "Ignoring $f";;
-		esac
-	done
-
-	entrypoint_log "Configuration complete; ready for start up"
-else
-	entrypoint_log "No files found in /docker-entrypoint.d/, skipping configuration"
-fi
-
-exec "$@"

+ 0 - 0
contrib/docker/fpm/docker-entrypoint.d/.gitkeep


+ 0 - 0
contrib/docker/apache/docker-entrypoint.d/.gitkeep → contrib/docker/fpm/root/.gitkeep


+ 0 - 49
contrib/docker/nginx/default-http.conf

@@ -1,49 +0,0 @@
-server {
-	listen 80 default_server;
-
-	server_name ${APP_DOMAIN};
-	root /var/www/public;
-
-	add_header X-Frame-Options "SAMEORIGIN";
-	add_header X-XSS-Protection "1; mode=block";
-	add_header X-Content-Type-Options "nosniff";
-
-	access_log /dev/stdout;
-	error_log /dev/stderr warn;
-
-	index index.html index.htm index.php;
-
-	charset utf-8;
-	client_max_body_size 100M;
-
-	location / {
-		try_files $uri $uri/ /index.php?$query_string;
-	}
-
-	location = /favicon.ico {
-		access_log off;
-		log_not_found off;
-	}
-
-	location = /robots.txt {
-		access_log off;
-		log_not_found off;
-	}
-
-	error_page 404 /index.php;
-
-	location ~ \.php$ {
-		fastcgi_split_path_info ^(.+\.php)(/.+)$;
-
-		fastcgi_pass 127.0.0.1:9000;
-		fastcgi_index index.php;
-
-		include fastcgi_params;
-
-		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-	}
-
-	location ~ /\.(?!well-known).* {
-		deny all;
-	}
-}

+ 0 - 0
contrib/docker/nginx/docker-entrypoint.d/.gitkeep


+ 49 - 0
contrib/docker/nginx/root/etc/nginx/conf.d/default.conf

@@ -0,0 +1,49 @@
+server {
+    listen 80 default_server;
+
+    server_name ${APP_DOMAIN};
+    root /var/www/public;
+
+    add_header X-Frame-Options "SAMEORIGIN";
+    add_header X-XSS-Protection "1; mode=block";
+    add_header X-Content-Type-Options "nosniff";
+
+    access_log /dev/stdout;
+    error_log /dev/stderr warn;
+
+    index index.html index.htm index.php;
+
+    charset utf-8;
+    client_max_body_size ${POST_MAX_SIZE};
+
+    location / {
+        try_files $uri $uri/ /index.php?$query_string;
+    }
+
+    location = /favicon.ico {
+        access_log off;
+        log_not_found off;
+    }
+
+    location = /robots.txt {
+        access_log off;
+        log_not_found off;
+    }
+
+    error_page 404 /index.php;
+
+    location ~ \.php$ {
+        fastcgi_split_path_info ^(.+\.php)(/.+)$;
+
+        fastcgi_pass 127.0.0.1:9000;
+        fastcgi_index index.php;
+
+        include fastcgi_params;
+
+        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+    }
+
+    location ~ /\.(?!well-known).* {
+        deny all;
+    }
+}

+ 0 - 13
contrib/docker/shared/docker-entrypoint.d/10-storage.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-set -o errexit -o nounset -o pipefail
-
-source /lib.sh
-
-entrypoint_log "==> Create the storage tree if needed"
-as_runtime_user cp --recursive storage.skel/* storage/
-
-entrypoint_log "==> Ensure storage is linked"
-as_runtime_user php artisan storage:link
-
-entrypoint_log "==> Ensure permissions are correct"
-chown --recursive ${RUNTIME_UID}:${RUNTIME_GID} storage/ bootstrap/

+ 0 - 13
contrib/docker/shared/docker-entrypoint.d/30-cache.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-set -o errexit -o nounset -o pipefail
-
-source /lib.sh
-
-entrypoint_log "==> route:cache"
-as_runtime_user php artisan route:cache
-
-entrypoint_log "==> view:cache"
-as_runtime_user php artisan view:cache
-
-entrypoint_log "==> config:cache"
-as_runtime_user php artisan config:cache

+ 0 - 13
contrib/docker/shared/lib.sh

@@ -1,13 +0,0 @@
-#!/bin/bash
-
-set -e
-
-function entrypoint_log() {
-    if [ -z "${ENTRYPOINT_QUIET_LOGS:-}" ]; then
-        echo "/docker-entrypoint.sh: $@"
-    fi
-}
-
-function as_runtime_user() {
-    su --preserve-environment ${RUNTIME_UID} --shell /bin/bash --command "${*}"
-}

+ 26 - 0
contrib/docker/shared/root/docker/entrypoint.d/04-defaults.envsh

@@ -0,0 +1,26 @@
+#!/bin/bash
+
+# NOTE:
+#
+# this file is *sourced* not run by the entrypoint runner
+# so any environment values set here will be accessible to all sub-processes
+# and future entrypoint.d scripts
+#
+
+set_identity "${BASH_SOURCE[0]}"
+
+load-config-files
+
+: ${POST_MAX_SIZE_BUFFER:=1M}
+log "POST_MAX_SIZE_BUFFER is set to [${POST_MAX_SIZE_BUFFER}]"
+buffer=$(numfmt --invalid=fail --from=auto --to=none --to-unit=K "${POST_MAX_SIZE_BUFFER}")
+log "POST_MAX_SIZE_BUFFER converted to KB is [${buffer}]"
+
+log "POST_MAX_SIZE will be calculated by [({MAX_PHOTO_SIZE} * {MAX_ALBUM_LENGTH}) + {POST_MAX_SIZE_BUFFER}]"
+log "  MAX_PHOTO_SIZE=${MAX_PHOTO_SIZE}"
+log "  MAX_ALBUM_LENGTH=${MAX_ALBUM_LENGTH}"
+log "  POST_MAX_SIZE_BUFFER=${buffer}"
+: ${POST_MAX_SIZE:=$(numfmt --invalid=fail --from=auto --from-unit=K --to=si $(((${MAX_PHOTO_SIZE} * ${MAX_ALBUM_LENGTH}) + ${buffer})))}
+log "POST_MAX_SIZE was calculated to [${POST_MAX_SIZE}]"
+
+export POST_MAX_SIZE

+ 40 - 0
contrib/docker/shared/root/docker/entrypoint.d/05-templating.sh

@@ -0,0 +1,40 @@
+#!/bin/bash
+source /docker/helpers.sh
+
+set_identity "$0"
+
+auto_envsubst() {
+    local template_dir="${ENVSUBST_TEMPLATE_DIR:-/docker/templates}"
+    local output_dir="${ENVSUBST_OUTPUT_DIR:-}"
+    local filter="${ENVSUBST_FILTER:-}"
+    local template defined_envs relative_path output_path output_dir subdir
+
+    # load all dot-env files
+    load-config-files
+
+    # export all dot-env variables so they are available in templating
+    export ${seen_dot_env_variables[@]}
+
+    defined_envs=$(printf '${%s} ' $(awk "END { for (name in ENVIRON) { print ( name ~ /${filter}/ ) ? name : \"\" } }" </dev/null))
+
+    find "$template_dir" -follow -type f -print | while read -r template; do
+        relative_path="${template#"$template_dir/"}"
+        subdir=$(dirname "$relative_path")
+        output_path="$output_dir/${relative_path}"
+        output_dir=$(dirname "$output_path")
+
+        if [ ! -w "$output_dir" ]; then
+            log_error_and_exit "ERROR: $template_dir exists, but $output_dir is not writable"
+        fi
+
+        # create a subdirectory where the template file exists
+        mkdir -p "$output_dir/$subdir"
+
+        log "Running envsubst on $template to $output_path"
+        envsubst "$defined_envs" <"$template" >"$output_path"
+    done
+}
+
+auto_envsubst
+
+exit 0

+ 13 - 0
contrib/docker/shared/root/docker/entrypoint.d/10-storage.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+source /docker/helpers.sh
+
+set_identity "$0"
+
+log "Create the storage tree if needed"
+as_runtime_user cp --recursive storage.skel/* storage/
+
+log "Ensure storage is linked"
+as_runtime_user php artisan storage:link
+
+log "Ensure permissions are correct"
+chown --recursive ${RUNTIME_UID}:${RUNTIME_GID} storage/ bootstrap/

+ 2 - 2
contrib/docker/shared/docker-entrypoint.d/20-horizon.sh → contrib/docker/shared/root/docker/entrypoint.d/20-horizon.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
-set -o errexit -o nounset -o pipefail
+source /docker/helpers.sh
 
-source /lib.sh
+set_identity "$0"
 
 as_runtime_user php artisan horizon:publish

+ 13 - 0
contrib/docker/shared/root/docker/entrypoint.d/30-cache.sh

@@ -0,0 +1,13 @@
+#!/bin/bash
+source /docker/helpers.sh
+
+set_identity "$0"
+
+log "==> route:cache"
+as_runtime_user php artisan route:cache
+
+log "==> view:cache"
+as_runtime_user php artisan view:cache
+
+log "==> config:cache"
+as_runtime_user php artisan config:cache

+ 50 - 0
contrib/docker/shared/root/docker/entrypoint.sh

@@ -0,0 +1,50 @@
+#!/bin/bash
+set -e -o errexit -o nounset -o pipefail
+
+[[ -n ${ENTRYPOINT_DEBUG:-} ]] && set -x
+
+declare -g ME="$0"
+declare -gr ENTRYPOINT_ROOT=/docker/entrypoint.d/
+
+source /docker/helpers.sh
+
+# ensure the entrypoint folder exists
+mkdir -p "${ENTRYPOINT_ROOT}"
+
+if /usr/bin/find "${ENTRYPOINT_ROOT}" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
+    log "looking for shell scripts in /docker/entrypoint.d/"
+    find "${ENTRYPOINT_ROOT}" -follow -type f -print | sort -V | while read -r f; do
+        case "$f" in
+        *.envsh)
+            if [ -x "$f" ]; then
+                log "Sourcing $f"
+                source "$f"
+                resetore_identity
+            else
+                # warn on shell scripts without exec bit
+                log_warning "Ignoring $f, not executable"
+            fi
+            ;;
+
+        *.sh)
+            if [ -x "$f" ]; then
+                log "Launching $f"
+                "$f"
+            else
+                # warn on shell scripts without exec bit
+                log_warning "Ignoring $f, not executable"
+            fi
+            ;;
+
+        *)
+            log_warning "Ignoring $f"
+            ;;
+        esac
+    done
+
+    log "Configuration complete; ready for start up"
+else
+    log_warning "No files found in ${ENTRYPOINT_ROOT}, skipping configuration"
+fi
+
+exec "$@"

+ 75 - 0
contrib/docker/shared/root/docker/helpers.sh

@@ -0,0 +1,75 @@
+#!/bin/bash
+set -e -o errexit -o nounset -o pipefail
+
+declare -g error_message_color="\033[1;31m"
+declare -g warn_message_color="\033[1;34m"
+declare -g color_clear="\033[1;0m"
+declare -g log_prefix=
+declare -g old_log_prefix=
+declare -ra dot_env_files=(
+    /var/www/.env.docker
+    /var/www/.env
+)
+declare -a seen_dot_env_variables=()
+
+function set_identity() {
+    old_log_prefix="${log_prefix}"
+    log_prefix="ENTRYPOINT - [${1}] - "
+}
+
+function resetore_identity() {
+    log_prefix="${old_log_prefix}"
+}
+
+function as_runtime_user() {
+    su --preserve-environment $(id -un ${RUNTIME_UID}) --shell /bin/bash --command "${*}"
+}
+
+# @description Display the given error message with its line number on stderr and exit with error.
+# @arg $message string A error message.
+function log_error() {
+    echo -e "${error_message_color}${log_prefix}ERROR - ${1}${color_clear}" >/dev/stderr
+}
+
+# @description Display the given error message with its line number on stderr and exit with error.
+# @arg $message string A error message.
+# @exitcode 1
+function log_error_and_exit() {
+    log_error "$1"
+
+    exit 1
+}
+
+# @description Display the given warning message with its line number on stderr.
+# @arg $message string A warning message.
+function log_warning() {
+    echo -e "${warn_message_color}${log_prefix}WARNING - ${1}${color_clear}" >/dev/stderr
+}
+
+function log() {
+    if [ -z "${ENTRYPOINT_QUIET_LOGS:-}" ]; then
+        echo "${log_prefix}$@"
+    fi
+}
+
+function load-config-files() {
+    # Associative array (aka map/disctrionary) holding the unique keys found in dot-env files
+    local -A _tmp_dot_env_keys
+
+    for f in "${dot_env_files[@]}"; do
+        if [ ! -e "$f" ]; then
+            log_warning "Could not source file [${f}]: does not exists"
+            continue
+        fi
+
+        log "Sourcing ${f}"
+        source "${f}"
+
+        # find all keys in the dot-env file and store them in our temp associative array
+        for k in "$(grep -v '^#' "${f}" | sed -E 's/(.*)=.*/\1/' | xargs)"; do
+            _tmp_dot_env_keys[$k]=1
+        done
+    done
+
+    seen_dot_env_variables=(${!_tmp_dot_env_keys[@]})
+}

+ 0 - 0
contrib/docker/install/base.sh → contrib/docker/shared/root/docker/install/base.sh


+ 0 - 0
contrib/docker/install/php-extensions.sh → contrib/docker/shared/root/docker/install/php-extensions.sh


+ 3 - 3
contrib/docker/php.production.ini → contrib/docker/shared/root/docker/templates/usr/local/etc/php/php.ini

@@ -679,7 +679,7 @@ auto_globals_jit = On
 ; Its value may be 0 to disable the limit. It is ignored if POST data reading
 ; is disabled through enable_post_data_reading.
 ; http://php.net/post-max-size
-post_max_size = 95M
+post_max_size = ${POST_MAX_SIZE}
 
 ; Automatically add files before PHP document.
 ; http://php.net/auto-prepend-file
@@ -831,10 +831,10 @@ file_uploads = On
 
 ; Maximum allowed size for uploaded files.
 ; http://php.net/upload-max-filesize
-upload_max_filesize = 95M
+upload_max_filesize = ${POST_MAX_SIZE}
 
 ; Maximum number of files that can be uploaded via a single request
-max_file_uploads = 20
+max_file_uploads = ${MAX_ALBUM_LENGTH}
 
 ;;;;;;;;;;;;;;;;;;
 ; Fopen wrappers ;