From 7c02774924d87c9a5bafbb1efb87e2cd5ce22774 Mon Sep 17 00:00:00 2001 From: Romain de Laage Date: Fri, 5 May 2023 15:46:40 +0200 Subject: [PATCH] build(docker): add ability to configure timeouts, max body size and max memory limit --- docker/production/app/Dockerfile | 4 +- docker/production/app/entrypoint.sh | 1 + docker/production/app/uploads.ini | 6 --- docker/production/app/uploads.template.ini | 6 +++ .../production/{unit => castopod}/Dockerfile | 10 ++-- .../config.template.json} | 14 +++--- .../production/{unit => castopod}/crontab.txt | 0 .../{unit => castopod}/entrypoint.sh | 1 + .../{unit => castopod}/supervisord.conf | 0 .../production/common/prepare_environment.sh | 25 +++++++++- docker/production/web-server/Dockerfile | 4 +- docker/production/web-server/entrypoint.sh | 15 +++++- .../{nginx.conf => nginx.template.conf} | 6 +-- docs/src/getting-started/docker.md | 46 ++++++------------- 14 files changed, 78 insertions(+), 60 deletions(-) delete mode 100644 docker/production/app/uploads.ini create mode 100644 docker/production/app/uploads.template.ini rename docker/production/{unit => castopod}/Dockerfile (81%) rename docker/production/{unit/config.json => castopod/config.template.json} (63%) rename docker/production/{unit => castopod}/crontab.txt (100%) rename docker/production/{unit => castopod}/entrypoint.sh (67%) rename docker/production/{unit => castopod}/supervisord.conf (100%) rename docker/production/web-server/{nginx.conf => nginx.template.conf} (94%) diff --git a/docker/production/app/Dockerfile b/docker/production/app/Dockerfile index 771a87a8..92231fb4 100644 --- a/docker/production/app/Dockerfile +++ b/docker/production/app/Dockerfile @@ -2,13 +2,13 @@ FROM docker.io/php:8.1-fpm-alpine3.17 COPY docker/production/common/prepare_environment.sh /prepare_environment.sh COPY docker/production/app/entrypoint.sh /entrypoint.sh -COPY docker/production/app/uploads.ini /usr/local/etc/php/conf.d/uploads.ini +COPY docker/production/app/uploads.template.ini /uploads.template.ini RUN echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-activities" > /crontab.txt && \ echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-websub-publish" >> /crontab.txt # TODO: remove freetype (package and gd support) and ffmpeg -RUN apk add --no-cache libpng icu-libs freetype libwebp libjpeg-turbo libxpm ffmpeg && \ +RUN apk add --no-cache libpng icu-libs freetype libwebp libjpeg-turbo libxpm ffmpeg coreutils gettext && \ apk add --no-cache --virtual .php-ext-build-dep freetype-dev libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev libxpm-dev icu-dev && \ docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm && \ docker-php-ext-install gd intl mysqli exif && \ diff --git a/docker/production/app/entrypoint.sh b/docker/production/app/entrypoint.sh index e92dd10d..7e81d438 100644 --- a/docker/production/app/entrypoint.sh +++ b/docker/production/app/entrypoint.sh @@ -3,6 +3,7 @@ ENV_FILE_LOCATION=/opt/castopod/.env . /prepare_environment.sh +cat /uploads.template.ini | envsubst '$CP_MAX_BODY_SIZE$CP_MAX_BODY_SIZE_BYTES$CP_TIMEOUT$CP_PHP_MEMORY_LIMIT' > /usr/local/etc/php/conf.d/uploads.ini /usr/sbin/crond -f /crontab.txt -L /dev/stdout & /usr/local/sbin/php-fpm diff --git a/docker/production/app/uploads.ini b/docker/production/app/uploads.ini deleted file mode 100644 index 0262ec7c..00000000 --- a/docker/production/app/uploads.ini +++ /dev/null @@ -1,6 +0,0 @@ -file_uploads = On -memory_limit = 512M -upload_max_filesize = 500M -post_max_size = 512M -max_execution_time = 300 -max_input_time = 300 diff --git a/docker/production/app/uploads.template.ini b/docker/production/app/uploads.template.ini new file mode 100644 index 00000000..52ac70fc --- /dev/null +++ b/docker/production/app/uploads.template.ini @@ -0,0 +1,6 @@ +file_uploads = On +memory_limit = $CP_PHP_MEMORY_LIMIT +upload_max_filesize = $CP_MAX_BODY_SIZE +post_max_size = $CP_MAX_BODY_SIZE +max_execution_time = $CP_TIMEOUT +max_input_time = $CP_TIMEOUT diff --git a/docker/production/unit/Dockerfile b/docker/production/castopod/Dockerfile similarity index 81% rename from docker/production/unit/Dockerfile rename to docker/production/castopod/Dockerfile index 268ff2e6..fc5db997 100644 --- a/docker/production/unit/Dockerfile +++ b/docker/production/castopod/Dockerfile @@ -34,14 +34,14 @@ COPY --from=UNIT_BUILDER /usr/lib/unit/ /usr/lib/unit/ COPY --from=CRON_BUILDER /usr/local/bin/supercronic /usr/local/bin/supercronic COPY docker/production/common/prepare_environment.sh /prepare_environment.sh -COPY docker/production/unit/entrypoint.sh /entrypoint.sh +COPY docker/production/castopod/entrypoint.sh /entrypoint.sh COPY castopod /var/www/castopod -COPY docker/production/unit/config.json /config.json -COPY docker/production/unit/crontab.txt /crontab.txt -COPY docker/production/unit/supervisord.conf /etc/supervisor/conf.d/supervisord.conf +COPY docker/production/castopod/config.template.json /config.template.json +COPY docker/production/castopod/crontab.txt /crontab.txt +COPY docker/production/castopod/supervisord.conf /etc/supervisor/conf.d/supervisord.conf RUN apt-get update && \ - apt-get install -y supervisor ffmpeg curl libfreetype6-dev libjpeg62-turbo-dev libpng-dev libwebp-dev libxpm-dev libpcre2-8-0 libicu-dev && \ + apt-get install -y supervisor ffmpeg curl gettext-base libfreetype6-dev libjpeg62-turbo-dev libpng-dev libwebp-dev libxpm-dev libpcre2-8-0 libicu-dev && \ rm -rf /var/lib/apt/lists/* && \ pecl install -o -f redis && \ rm -rf /tmp/pear && \ diff --git a/docker/production/unit/config.json b/docker/production/castopod/config.template.json similarity index 63% rename from docker/production/unit/config.json rename to docker/production/castopod/config.template.json index d8d8d76f..1290fbbd 100644 --- a/docker/production/unit/config.json +++ b/docker/production/castopod/config.template.json @@ -22,11 +22,11 @@ "options": { "admin": { "file_uploads": "On", - "memory_limit": "512M", - "upload_max_filesize": "500M", - "post_max_size": "512M", - "max_execution_time": "300", - "max_input_time": "300" + "memory_limit": "$CP_PHP_MEMORY_LIMIT", + "upload_max_filesize": "$CP_MAX_BODY_SIZE", + "post_max_size": "$CP_MAX_BODY_SIZE", + "max_execution_time": "$CP_TIMEOUT", + "max_input_time": "$CP_TIMEOUT" } } } @@ -36,8 +36,8 @@ }, "settings": { "http": { - "body_read_timeout": 300, - "max_body_size": 536870912 + "body_read_timeout": $CP_TIMEOUT, + "max_body_size": $CP_MAX_BODY_SIZE_BYTES } } } diff --git a/docker/production/unit/crontab.txt b/docker/production/castopod/crontab.txt similarity index 100% rename from docker/production/unit/crontab.txt rename to docker/production/castopod/crontab.txt diff --git a/docker/production/unit/entrypoint.sh b/docker/production/castopod/entrypoint.sh similarity index 67% rename from docker/production/unit/entrypoint.sh rename to docker/production/castopod/entrypoint.sh index 544bda06..1cd559ba 100644 --- a/docker/production/unit/entrypoint.sh +++ b/docker/production/castopod/entrypoint.sh @@ -3,6 +3,7 @@ ENV_FILE_LOCATION=/var/www/castopod/.env . /prepare_environment.sh +cat /config.template.json | envsubst '$CP_MAX_BODY_SIZE$CP_MAX_BODY_SIZE_BYTES$CP_TIMEOUT$CP_PHP_MEMORY_LIMIT' > /config.json #Apply configuration after unit is started (sleep 2 && curl -X PUT --data-binary @/config.json --unix-socket /var/run/control.unit.sock http://localhost/config/) & diff --git a/docker/production/unit/supervisord.conf b/docker/production/castopod/supervisord.conf similarity index 100% rename from docker/production/unit/supervisord.conf rename to docker/production/castopod/supervisord.conf diff --git a/docker/production/common/prepare_environment.sh b/docker/production/common/prepare_environment.sh index d038a4a4..6d149a2c 100644 --- a/docker/production/common/prepare_environment.sh +++ b/docker/production/common/prepare_environment.sh @@ -16,7 +16,8 @@ fi if [ -z "${CP_MEDIA_BASEURL}" ] then - echo "CP_MEDIA_BASEURL is empty, leaving empty by default" + echo "CP_MEDIA_BASEURL is empty, using CP_BASEURL by default" + CP_MEDIA_BASEURL=$CP_BASEURL fi if [ -z "${CP_ADMIN_GATEWAY}" ] @@ -133,6 +134,28 @@ then fi fi +if [ -z "${CP_PHP_MEMORY_LIMIT}" ] +then + export CP_PHP_MEMORY_LIMIT="512M" +fi + +if [ -z "${CP_MAX_BODY_SIZE}" ] +then + export CP_MAX_BODY_SIZE="512M" +fi + +CP_MAX_BODY_SIZE_BYTES=$(numfmt --from=iec "$CP_MAX_BODY_SIZE") +if [ $? -ne 0 ] +then + log_error "Failed to parse CP_MAX_BODY_SIZE ($CP_MAX_BODY_SIZE) as human readable number" +fi +export CP_MAX_BODY_SIZE_BYTES=$CP_MAX_BODY_SIZE_BYTES + +if [ -z "${CP_TIMEOUT}" ] +then + export CP_TIMEOUT=900 +fi + cat << EOF > $ENV_FILE_LOCATION app.baseURL="${CP_BASEURL}" media.baseURL="${CP_MEDIA_BASEURL}" diff --git a/docker/production/web-server/Dockerfile b/docker/production/web-server/Dockerfile index 3b2320a2..5d735499 100644 --- a/docker/production/web-server/Dockerfile +++ b/docker/production/web-server/Dockerfile @@ -9,11 +9,11 @@ WORKDIR /var/www/html COPY docker/production/web-server/entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh && \ - apk add --no-cache curl + apk add --no-cache curl gettext HEALTHCHECK --interval=30s --timeout=3s CMD curl --fail http://localhost || exit 1 -COPY docker/production/web-server/nginx.conf /etc/nginx/nginx.conf +COPY docker/production/web-server/nginx.template.conf /nginx.template.conf COPY castopod/public /var/www/html diff --git a/docker/production/web-server/entrypoint.sh b/docker/production/web-server/entrypoint.sh index 4365e2cd..5f623781 100644 --- a/docker/production/web-server/entrypoint.sh +++ b/docker/production/web-server/entrypoint.sh @@ -2,8 +2,19 @@ if [ -z "${CP_APP_HOSTNAME}" ] then echo "CP_APP_HOSTNAME is empty, using default" - CP_APP_HOSTNAME="app" + export CP_APP_HOSTNAME="app" fi -sed -i "s/CP_APP_HOSTNAME/${CP_APP_HOSTNAME}/" /etc/nginx/nginx.conf +if [ -z "${CP_MAX_BODY_SIZE}" ] +then + export CP_MAX_BODY_SIZE=512M +fi + +if [ -z "${CP_TIMEOUT}" ] +then + export CP_TIMEOUT=900 +fi + +cat /nginx.template.conf | envsubst '$CP_APP_HOSTNAME$CP_MAX_BODY_SIZE$CP_TIMEOUT' > /etc/nginx/nginx.conf + nginx -g "daemon off;" diff --git a/docker/production/web-server/nginx.conf b/docker/production/web-server/nginx.template.conf similarity index 94% rename from docker/production/web-server/nginx.conf rename to docker/production/web-server/nginx.template.conf index 669c4f9b..58f9ecde 100644 --- a/docker/production/web-server/nginx.conf +++ b/docker/production/web-server/nginx.template.conf @@ -27,7 +27,7 @@ http { real_ip_header X-Real-IP; upstream php-handler { - server CP_APP_HOSTNAME:9000; + server $CP_APP_HOSTNAME:9000; } server { @@ -40,8 +40,8 @@ http { add_header Permissions-Policy interest-cohort=(); add_header X-Content-Type-Options nosniff; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload;"; - client_max_body_size 512M; - client_body_timeout 300s; + client_max_body_size $CP_MAX_BODY_SIZE; + client_body_timeout ${CP_TIMEOUT}s; fastcgi_buffers 64 4K; diff --git a/docs/src/getting-started/docker.md b/docs/src/getting-started/docker.md index bae0d0d3..437ca7ad 100644 --- a/docs/src/getting-started/docker.md +++ b/docs/src/getting-started/docker.md @@ -42,29 +42,20 @@ can be added as a cache handler. image: castopod/app:latest container_name: "castopod-app" volumes: - - castopod-media:/opt/castopod/public/media + - castopod-media:/var/www/castopod/public/media environment: MYSQL_DATABASE: castopod MYSQL_USER: castopod MYSQL_PASSWORD: changeme - CP_BASEURL: "http://castopod.example.com" + CP_BASEURL: "https://castopod.example.com" CP_ANALYTICS_SALT: changeme CP_CACHE_HANDLER: redis CP_REDIS_HOST: redis networks: - castopod-app - castopod-db - restart: unless-stopped - - web-server: - image: castopod/web-server:latest - container_name: "castopod-web-server" - volumes: - - castopod-media:/var/www/html/media - networks: - - castopod-app ports: - - 8080:80 + - 8000:8000 restart: unless-stopped mariadb: @@ -89,21 +80,6 @@ can be added as a cache handler. networks: - castopod-app - # this container is optional - # add this if you want to use the videoclips feature - video-clipper: - image: castopod/video-clipper:latest - container_name: "castopod-video-clipper" - volumes: - - castopod-media:/opt/castopod/public/media - environment: - MYSQL_DATABASE: castopod - MYSQL_USER: castopod - MYSQL_PASSWORD: changeme - networks: - - castopod-db - restart: unless-stopped - volumes: castopod-media: castopod-db: @@ -125,7 +101,7 @@ can be added as a cache handler. ``` #castopod castopod.example.com { - reverse_proxy localhost:8080 + reverse_proxy localhost:8000 } ``` @@ -146,7 +122,7 @@ can be added as a cache handler. | **`CP_DATABASE_PASSWORD`** | ?string | `MYSQL_PASSWORD` | | **`CP_DATABASE_PREFIX`** | ?string | `"cp_"` | -- **castopod/app** +- **castopod/castopod** and **castopod/app** | Variable name | Type (`default`) | Default | | ------------------------------------- | ----------------------- | ---------------- | @@ -181,9 +157,15 @@ can be added as a cache handler. | **`CP_MEDIA_S3_PROTOCOL`** | ?number | `undefined` | | **`CP_MEDIA_S3_PATH_STYLE_ENDPOINT`** | ?boolean | `undefined` | | **`CP_MEDIA_S3_KEY_PREFIX`** | ?string | `undefined` | + | **`CP_DISABLE_HTTPS`** | ?[`0` or `1`] | `undefined` | + | **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M` | + | **`CP_PHP_MEMORY_LIMIT`** | ?number (with suffix) | `512M` | + | **`CP_TIMEOUT`** | ?number | `900` | - **castopod/web-server** - | Variable name | Type | Default | - | --------------------- | ------- | ------- | - | **`CP_APP_HOSTNAME`** | ?string | `"app"` | + | Variable name | Type | Default | + | ---------------------- | --------------------- | ------- | + | **`CP_APP_HOSTNAME`** | ?string | `"app"` | + | **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M` | + | **`CP_TIMEOUT`** | ?number | `900` |