From ab275e978c895e345e7ac3a690bb1d1d5162d398 Mon Sep 17 00:00:00 2001 From: Romain de Laage Date: Sat, 25 Feb 2023 15:10:19 +0000 Subject: [PATCH] build(docker): add alternative Nginx Unit image --- docker/production/.gitlab-ci.yml | 3 + docker/production/unit/Dockerfile | 61 +++++++++ docker/production/unit/config.json | 43 ++++++ docker/production/unit/crontab.txt | 3 + docker/production/unit/entrypoint.sh | 197 +++++++++++++++++++++++++++ 5 files changed, 307 insertions(+) create mode 100644 docker/production/unit/Dockerfile create mode 100644 docker/production/unit/config.json create mode 100644 docker/production/unit/crontab.txt create mode 100644 docker/production/unit/entrypoint.sh diff --git a/docker/production/.gitlab-ci.yml b/docker/production/.gitlab-ci.yml index 67b26ccc..f55b96fa 100644 --- a/docker/production/.gitlab-ci.yml +++ b/docker/production/.gitlab-ci.yml @@ -13,6 +13,7 @@ docker-build-rolling: - /kaniko/executor --cleanup --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${TAG} - /kaniko/executor --cleanup --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${TAG} - /kaniko/executor --cleanup --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${TAG} + - /kaniko/executor --cleanup --context . --dockerfile docker/production/unit/Dockerfile --destination ${DOCKER_IMAGE_UNIT}:${TAG} needs: - pipeline: $PARENT_PIPELINE_ID job: bundle @@ -31,6 +32,7 @@ docker-build-main-release: - /kaniko/executor --cleanup --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${CP_VERSION} --destination ${DOCKER_IMAGE_WEB_SERVER}:latest - /kaniko/executor --cleanup --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${CP_VERSION} --destination ${DOCKER_IMAGE_APP}:latest - /kaniko/executor --cleanup --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${CP_VERSION} --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:latest + - /kaniko/executor --cleanup --context . --dockerfile docker/production/unit/Dockerfile --destination ${DOCKER_IMAGE_UNIT}:${CP_VERSION} --destination ${DOCKER_IMAGE_UNIT}:latest needs: - pipeline: $PARENT_PIPELINE_ID job: release @@ -51,6 +53,7 @@ docker-build-alpha-beta-release: - /kaniko/executor --cleanup --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${CP_VERSION} --destination ${DOCKER_IMAGE_WEB_SERVER}:${TAG} - /kaniko/executor --cleanup --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${CP_VERSION} --destination ${DOCKER_IMAGE_APP}:${TAG} - /kaniko/executor --cleanup --context . --dockerfile docker/production/video-clipper/Dockerfile --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${CP_VERSION} --destination ${DOCKER_IMAGE_VIDEO_CLIPPER}:${TAG} + - /kaniko/executor --cleanup --context . --dockerfile docker/production/unit/Dockerfile --destination ${DOCKER_IMAGE_UNIT}:${CP_VERSION} --destination ${DOCKER_IMAGE_UNIT}:${TAG} needs: - pipeline: $PARENT_PIPELINE_ID job: release diff --git a/docker/production/unit/Dockerfile b/docker/production/unit/Dockerfile new file mode 100644 index 00000000..ab2cad76 --- /dev/null +++ b/docker/production/unit/Dockerfile @@ -0,0 +1,61 @@ +FROM docker.io/golang:1.20-bullseye AS CRON_BUILDER + +ARG SUPERCRONIC_VERSION=v0.2.1 + +RUN apt-get update && \ + apt-get install -y git && \ + git clone https://github.com/aptible/supercronic.git && \ + cd supercronic && \ + git checkout $SUPERCRONIC_VERSION && \ + go build && \ + mv supercronic /usr/local/bin + + +FROM docker.io/php:8.1-cli AS UNIT_BUILDER + +ARG UNIT_VERSION=1.29.0 + +RUN apt-get update && \ + apt-get install -y libpcre2-dev git && \ + mkdir -p /usr/lib/unit/modules && \ + git clone https://github.com/nginx/unit.git && \ + cd unit && \ + git checkout $UNIT_VERSION && \ + ./configure --prefix=/usr --state=/var/lib/unit --control=unix:/var/run/control.unit.sock --log=/var/log/unit.log --user=www-data --group=www-data --tmp=/tmp --modules=/usr/lib/unit/modules && \ + ./configure php && \ + make && \ + make install + + +FROM docker.io/php:8.1-cli + +COPY --from=UNIT_BUILDER /usr/sbin/unitd /usr/sbin/unitd +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/unit/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 + +RUN apt-get update && \ + apt-get install -y ffmpeg curl 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 && \ + docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm && \ + docker-php-ext-install mysqli gd intl exif && \ + docker-php-ext-enable mysqli gd intl exif redis && \ + ln -s /dev/stdout /var/log/unit.log && \ + mkdir -p /var/lib/unit && \ + chmod 544 /entrypoint.sh && \ + chmod -R 750 /var/www/castopod && \ + chown -R root:www-data /var/www/castopod && \ + chown -R www-data:www-data /var/www/castopod/writable /var/www/castopod/public/media + +WORKDIR /var/www/castopod +VOLUME /var/www/castopod/public/media +EXPOSE 8000 + +ENTRYPOINT [ "sh", "-c" ] +CMD [ "/entrypoint.sh" ] diff --git a/docker/production/unit/config.json b/docker/production/unit/config.json new file mode 100644 index 00000000..d8d8d76f --- /dev/null +++ b/docker/production/unit/config.json @@ -0,0 +1,43 @@ +{ + "listeners": { + "*:8000": { + "pass": "routes" + } + }, + "routes": [ + { + "action": { + "share": "/var/www/castopod/public$uri", + "fallback": { + "pass": "applications/castopod" + } + } + } + ], + "applications": { + "castopod": { + "type": "php", + "root": "/var/www/castopod/public/", + "script": "index.php", + "options": { + "admin": { + "file_uploads": "On", + "memory_limit": "512M", + "upload_max_filesize": "500M", + "post_max_size": "512M", + "max_execution_time": "300", + "max_input_time": "300" + } + } + } + }, + "access_log": { + "path": "/dev/stdout" + }, + "settings": { + "http": { + "body_read_timeout": 300, + "max_body_size": 536870912 + } + } +} diff --git a/docker/production/unit/crontab.txt b/docker/production/unit/crontab.txt new file mode 100644 index 00000000..b1f18a1e --- /dev/null +++ b/docker/production/unit/crontab.txt @@ -0,0 +1,3 @@ +* * * * * /usr/local/bin/php /var/www/castopod/public/index.php scheduled-activities +* * * * * /usr/local/bin/php /var/www/castopod/public/index.php scheduled-websub-publish +* * * * * /usr/local/bin/php /var/www/castopod/public/index.php scheduled-video-clips diff --git a/docker/production/unit/entrypoint.sh b/docker/production/unit/entrypoint.sh new file mode 100644 index 00000000..62a1036e --- /dev/null +++ b/docker/production/unit/entrypoint.sh @@ -0,0 +1,197 @@ +#!/bin/sh + +if [ -z "${CP_BASEURL}" ] +then + echo "CP_BASEURL must be set" + exit 1 +fi + +if [ -z "${CP_MEDIA_BASEURL}" ] +then + echo "CP_MEDIA_BASEURL is empty, leaving empty by default" +fi + +if [ -z "${CP_ADMIN_GATEWAY}" ] +then + echo "CP_ADMIN_GATEWAY is empty, using default" + CP_ADMIN_GATEWAY="cp-admin" +fi + +if [ -z "${CP_AUTH_GATEWAY}" ] +then + echo "CP_AUTH_GATEWAY is empty, using default" + CP_AUTH_GATEWAY="cp-auth" +fi + +if [ -z "${CP_ANALYTICS_SALT}" ] +then + echo "CP_ANALYTICS_SALT is empty, this is mandatory, generate a new one with tr -dc \\!\\#-\\&\\(-\\[\\]-\\_a-\\~ /var/www/castopod/.env +app.baseURL="${CP_BASEURL}" +app.mediaBaseURL="${CP_MEDIA_BASEURL}" +EOF + +if [ "${CP_DISABLE_HTTPS}" = "1" ] +then + echo "HTTPS redirection is disabled for testing purposes, please enable it in production mode" + echo "app.forceGlobalSecureRequests=false" >> /var/www/castopod/.env +else + echo "HTTPS redirection is enabled by default (mandatory to federate with the fediverse), use CP_DISABLE_HTTPS=1 to disable it for testing purposes" +fi + +cat << EOF >> /var/www/castopod/.env +admin.gateway="${CP_ADMIN_GATEWAY}" +auth.gateway="${CP_AUTH_GATEWAY}" + +analytics.salt="${CP_ANALYTICS_SALT}" + +database.default.hostname="${CP_DATABASE_HOSTNAME}" +database.default.database="${CP_DATABASE_NAME}" +database.default.username="${CP_DATABASE_USERNAME}" +database.default.password="${CP_DATABASE_PASSWORD}" +database.default.DBPrefix="${CP_DATABASE_PREFIX}" + +cache.handler="${CP_CACHE_HANDLER}" +EOF + +if [ "${CP_CACHE_HANDLER}" = "redis" ] +then + cat << EOF >> /var/www/castopod/.env +cache.redis.host="${CP_REDIS_HOST}" +cache.redis.password=${CP_REDIS_PASSWORD} +cache.redis.port=${CP_REDIS_PORT} +cache.redis.database=${CP_REDIS_DATABASE} +EOF +fi + +if [ ! -z "${CP_EMAIL_SMTP_HOST}" ] +then + if [ -z "${CP_EMAIL_SMTP_USERNAME}" ] + then + echo "When CP_EMAIL_SMTP_HOST is provided, CP_EMAIL_SMTP_USERNAME must be set" + exit 1 + fi + + if [ -z "${CP_EMAIL_SMTP_PASSWORD}" ] + then + echo "When CP_EMAIL_SMTP_HOST is provided, CP_EMAIL_SMTP_PASSWORD must be set" + exit 1 + fi + + if [ -z "${CP_EMAIL_FROM}" ] + then + echo "When CP_EMAIL_SMTP_HOST is provided, CP_EMAIL_FROM must be set" + exit 1 + fi + + cat << EOF >> /var/www/castopod/.env +email.protocol="smtp" +email.SMTPHost="${CP_EMAIL_SMTP_HOST}" +email.SMTPUser=${CP_EMAIL_SMTP_USERNAME} +email.SMTPPass=${CP_EMAIL_SMTP_PASSWORD} +email.fromEmail=${CP_EMAIL_FROM} +EOF + + if [ ! -z "${CP_EMAIL_SMTP_PORT}" ] + then + cat << EOF >> /var/www/castopod/.env +email.SMTPPort=${CP_EMAIL_SMTP_PORT} +EOF + fi + + if [ ! -z "${CP_EMAIL_SMTP_CRYPTO}" ] + then + if [ "${CP_EMAIL_SMTP_CRYPTO}" != "ssl" ] && [ "${CP_EMAIL_SMTP_CRYPTO}" != "tls" ] + then + echo "CP_EMAIL_SMTP_CRYPTO must be ssl or tls" + exit 1 + fi + cat << EOF >> /var/www/castopod/.env +email.SMTPCrypto=${CP_EMAIL_SMTP_CRYPTO} +EOF + fi +fi + +unitd --no-daemon & +php spark castopod:database-update +sleep 2 && curl -X PUT --data-binary @/config.json --unix-socket /var/run/control.unit.sock http://localhost/config/ +supercronic /crontab.txt