From 19967bd42ea78e8af1a4be4ff163cec3642fc83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 18:05:21 +0100 Subject: [PATCH 01/10] Added files from frankenphp symfony skeleton --- Dockerfile | 202 +++++++++++++------------------- Dockerfile.old | 133 +++++++++++++++++++++ compose.override.yaml | 24 ++++ compose.prod.yaml | 10 ++ compose.yaml | 45 +++++++ frankenphp/Caddyfile | 55 +++++++++ frankenphp/conf.d/app.dev.ini | 5 + frankenphp/conf.d/app.ini | 13 ++ frankenphp/conf.d/app.prod.ini | 2 + frankenphp/docker-entrypoint.sh | 60 ++++++++++ frankenphp/worker.Caddyfile | 4 + 11 files changed, 431 insertions(+), 122 deletions(-) create mode 100644 Dockerfile.old create mode 100644 compose.override.yaml create mode 100644 compose.prod.yaml create mode 100644 compose.yaml create mode 100644 frankenphp/Caddyfile create mode 100644 frankenphp/conf.d/app.dev.ini create mode 100644 frankenphp/conf.d/app.ini create mode 100644 frankenphp/conf.d/app.prod.ini create mode 100644 frankenphp/docker-entrypoint.sh create mode 100644 frankenphp/worker.Caddyfile diff --git a/Dockerfile b/Dockerfile index 85536666..b9080886 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,133 +1,91 @@ -FROM debian:bullseye-slim +#syntax=docker/dockerfile:1.4 -# Install needed dependencies for PHP build -#RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \ -# libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \ -# && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* +# Versions +FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream -RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client \ - && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ - && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ - && apt-get update && apt-get upgrade -y \ - && apt-get install -y apache2 php8.1 php8.1-fpm php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql gpg \ - && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; - -ENV APACHE_CONFDIR /etc/apache2 -ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars - -# Create workdir and set permissions if directory does not exists -RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html - -# Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile) -# generically convert lines like -# export APACHE_RUN_USER=www-data -# into -# : ${APACHE_RUN_USER:=www-data} -# export APACHE_RUN_USER -# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") -RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ - set -eux; . "$APACHE_ENVVARS"; \ - # delete the "index.html" that installing Apache drops in here - rm -rvf /var/www/html/*; \ - \ - # logs should go to stdout / stderr - ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ - ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ - ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ - chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"; - -# Enable php-fpm -RUN a2enmod proxy_fcgi setenvif && a2enconf php8.1-fpm - -# Configure php-fpm to log to stdout of the container (stdout of PID 1) -# We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint) -# We also disable the clear_env option to allow the use of environment variables in php-fpm -RUN { \ - echo '[global]'; \ - echo 'error_log = /proc/1/fd/1'; \ - echo; \ - echo '[www]'; \ - echo 'access.log = /proc/1/fd/1'; \ - echo 'catch_workers_output = yes'; \ - echo 'decorate_workers_output = no'; \ - echo 'clear_env = no'; \ - } | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf" - -# PHP files should be handled by PHP, and should be preferred over any other file type -RUN { \ - echo ''; \ - echo '\tSetHandler application/x-httpd-php'; \ - echo ''; \ - echo; \ - echo 'DirectoryIndex disabled'; \ - echo 'DirectoryIndex index.php index.html'; \ - echo; \ - echo ''; \ - echo '\tOptions -Indexes'; \ - echo '\tAllowOverride All'; \ - echo ''; \ - } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ - && a2enconf docker-php - -# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html) -RUN \ - { \ - echo 'opcache.memory_consumption=256'; \ - echo 'opcache.max_accelerated_files=20000'; \ - echo 'opcache.validate_timestamp=0'; \ - # Configure Realpath cache for performance - echo 'realpath_cache_size=4096K'; \ - echo 'realpath_cache_ttl=600'; \ - } > /etc/php/8.1/fpm/conf.d/symfony-recommended.ini - -# Increase upload limit and enable preloading -RUN \ - { \ - echo 'upload_max_filesize=256M'; \ - echo 'post_max_size=300M'; \ - echo 'opcache.preload_user=www-data'; \ - echo 'opcache.preload=/var/www/html/config/preload.php'; \ - } > /etc/php/8.1/fpm/conf.d/partdb.ini - -# Install node and yarn -RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* - -# Install composer -COPY --from=composer:latest /usr/bin/composer /usr/bin/composer +# The different stages of this Dockerfile are meant to be built into separate images +# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage +# https://docs.docker.com/compose/compose-file/#target -# Set working dir -WORKDIR /var/www/html -COPY --chown=www-data:www-data . . +# Base FrankenPHP image +FROM frankenphp_upstream AS frankenphp_base -# Setup apache2 -RUN a2dissite 000-default.conf -COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf -RUN a2ensite symfony.conf -RUN a2enmod rewrite +WORKDIR /app -# Install composer and yarn dependencies for Part-DB -USER www-data -RUN composer install -a --no-dev && composer clear-cache -RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ +# persistent / runtime deps +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -y --no-install-recommends \ + acl \ + file \ + gettext \ + git \ + && rm -rf /var/lib/apt/lists/* -# Use docker env to output logs to stdout -ENV APP_ENV=docker -ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" +RUN set -eux; \ + install-php-extensions \ + @composer \ + apcu \ + intl \ + opcache \ + zip \ + ; -USER root +# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser +ENV COMPOSER_ALLOW_SUPERUSER=1 -# Copy entrypoint to /usr/local/bin and make it executable -RUN cp ./.docker/partdb-entrypoint.sh /usr/local/bin/partdb-entrypoint.sh && chmod +x /usr/local/bin/partdb-entrypoint.sh -# Copy apache2-foreground to /usr/local/bin and make it executable -RUN cp ./.docker/apache2-foreground /usr/local/bin/apache2-foreground && chmod +x /usr/local/bin/apache2-foreground -ENTRYPOINT ["partdb-entrypoint.sh"] -CMD ["apache2-foreground"] +###> recipes ### +###< recipes ### -# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop -STOPSIGNAL SIGWINCH +COPY --link frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ +COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link frankenphp/Caddyfile /etc/caddy/Caddyfile -EXPOSE 80 -VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] \ No newline at end of file +ENTRYPOINT ["docker-entrypoint"] + +HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] + +# Dev FrankenPHP image +FROM frankenphp_base AS frankenphp_dev + +ENV APP_ENV=dev XDEBUG_MODE=off +VOLUME /app/var/ + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + +RUN set -eux; \ + install-php-extensions \ + xdebug \ + ; + +COPY --link frankenphp/conf.d/app.dev.ini $PHP_INI_DIR/conf.d/ + +CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ] + +# Prod FrankenPHP image +FROM frankenphp_base AS frankenphp_prod + +ENV APP_ENV=prod +ENV FRANKENPHP_CONFIG="import worker.Caddyfile" + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +COPY --link frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile + +# prevent the reinstallation of vendors at every changes in the source code +COPY --link composer.* symfony.* ./ +RUN set -eux; \ + composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress + +# copy sources +COPY --link . ./ +RUN rm -Rf frankenphp/ + +RUN set -eux; \ + mkdir -p var/cache var/log; \ + composer dump-autoload --classmap-authoritative --no-dev; \ + composer dump-env prod; \ + composer run-script --no-dev post-install-cmd; \ + chmod +x bin/console; sync; diff --git a/Dockerfile.old b/Dockerfile.old new file mode 100644 index 00000000..85536666 --- /dev/null +++ b/Dockerfile.old @@ -0,0 +1,133 @@ +FROM debian:bullseye-slim + +# Install needed dependencies for PHP build +#RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \ +# libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \ +# && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* + +RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client \ + && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ + && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ + && apt-get update && apt-get upgrade -y \ + && apt-get install -y apache2 php8.1 php8.1-fpm php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql gpg \ + && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; + +ENV APACHE_CONFDIR /etc/apache2 +ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars + +# Create workdir and set permissions if directory does not exists +RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html + +# Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile) +# generically convert lines like +# export APACHE_RUN_USER=www-data +# into +# : ${APACHE_RUN_USER:=www-data} +# export APACHE_RUN_USER +# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") +RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ + set -eux; . "$APACHE_ENVVARS"; \ + # delete the "index.html" that installing Apache drops in here + rm -rvf /var/www/html/*; \ + \ + # logs should go to stdout / stderr + ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ + chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"; + +# Enable php-fpm +RUN a2enmod proxy_fcgi setenvif && a2enconf php8.1-fpm + +# Configure php-fpm to log to stdout of the container (stdout of PID 1) +# We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint) +# We also disable the clear_env option to allow the use of environment variables in php-fpm +RUN { \ + echo '[global]'; \ + echo 'error_log = /proc/1/fd/1'; \ + echo; \ + echo '[www]'; \ + echo 'access.log = /proc/1/fd/1'; \ + echo 'catch_workers_output = yes'; \ + echo 'decorate_workers_output = no'; \ + echo 'clear_env = no'; \ + } | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf" + +# PHP files should be handled by PHP, and should be preferred over any other file type +RUN { \ + echo ''; \ + echo '\tSetHandler application/x-httpd-php'; \ + echo ''; \ + echo; \ + echo 'DirectoryIndex disabled'; \ + echo 'DirectoryIndex index.php index.html'; \ + echo; \ + echo ''; \ + echo '\tOptions -Indexes'; \ + echo '\tAllowOverride All'; \ + echo ''; \ + } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ + && a2enconf docker-php + +# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html) +RUN \ + { \ + echo 'opcache.memory_consumption=256'; \ + echo 'opcache.max_accelerated_files=20000'; \ + echo 'opcache.validate_timestamp=0'; \ + # Configure Realpath cache for performance + echo 'realpath_cache_size=4096K'; \ + echo 'realpath_cache_ttl=600'; \ + } > /etc/php/8.1/fpm/conf.d/symfony-recommended.ini + +# Increase upload limit and enable preloading +RUN \ + { \ + echo 'upload_max_filesize=256M'; \ + echo 'post_max_size=300M'; \ + echo 'opcache.preload_user=www-data'; \ + echo 'opcache.preload=/var/www/html/config/preload.php'; \ + } > /etc/php/8.1/fpm/conf.d/partdb.ini + +# Install node and yarn +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* + +# Install composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + + +# Set working dir +WORKDIR /var/www/html +COPY --chown=www-data:www-data . . + +# Setup apache2 +RUN a2dissite 000-default.conf +COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf +RUN a2ensite symfony.conf +RUN a2enmod rewrite + +# Install composer and yarn dependencies for Part-DB +USER www-data +RUN composer install -a --no-dev && composer clear-cache +RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ + +# Use docker env to output logs to stdout +ENV APP_ENV=docker +ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" + +USER root + +# Copy entrypoint to /usr/local/bin and make it executable +RUN cp ./.docker/partdb-entrypoint.sh /usr/local/bin/partdb-entrypoint.sh && chmod +x /usr/local/bin/partdb-entrypoint.sh +# Copy apache2-foreground to /usr/local/bin and make it executable +RUN cp ./.docker/apache2-foreground /usr/local/bin/apache2-foreground && chmod +x /usr/local/bin/apache2-foreground +ENTRYPOINT ["partdb-entrypoint.sh"] +CMD ["apache2-foreground"] + +# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop +STOPSIGNAL SIGWINCH + +EXPOSE 80 +VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] \ No newline at end of file diff --git a/compose.override.yaml b/compose.override.yaml new file mode 100644 index 00000000..5f141b1f --- /dev/null +++ b/compose.override.yaml @@ -0,0 +1,24 @@ +# Development environment override +services: + php: + build: + context: . + target: frankenphp_dev + volumes: + - ./:/app + - ./frankenphp/Caddyfile:/etc/caddy/Caddyfile:ro + - ./frankenphp/conf.d/app.dev.ini:/usr/local/etc/php/conf.d/app.dev.ini:ro + # If you develop on Mac or Windows you can remove the vendor/ directory + # from the bind-mount for better performance by enabling the next line: + #- /app/vendor + environment: + MERCURE_EXTRA_DIRECTIVES: demo + # See https://xdebug.org/docs/all_settings#mode + XDEBUG_MODE: "${XDEBUG_MODE:-off}" + extra_hosts: + # Ensure that host.docker.internal is correctly defined on Linux + - host.docker.internal:host-gateway + tty: true + +###> symfony/mercure-bundle ### +###< symfony/mercure-bundle ### diff --git a/compose.prod.yaml b/compose.prod.yaml new file mode 100644 index 00000000..f0db05da --- /dev/null +++ b/compose.prod.yaml @@ -0,0 +1,10 @@ +# Production environment override +services: + php: + build: + context: . + target: frankenphp_prod + environment: + APP_SECRET: ${APP_SECRET} + MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} + MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 00000000..43a07900 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,45 @@ +services: + php: + image: ${IMAGES_PREFIX:-}app-php + restart: unless-stopped + environment: + SERVER_NAME: ${SERVER_NAME:-localhost}, php:80 + MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + TRUSTED_PROXIES: ${TRUSTED_PROXIES:-127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16} + TRUSTED_HOSTS: ^${SERVER_NAME:-example\.com|localhost}|php$$ + # Run "composer require symfony/orm-pack" to install and configure Doctrine ORM + DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} + # Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration + MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure} + MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure + MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} + # The two next lines can be removed after initial installation + SYMFONY_VERSION: ${SYMFONY_VERSION:-} + STABILITY: ${STABILITY:-stable} + volumes: + - caddy_data:/data + - caddy_config:/config + ports: + # HTTP + - target: 80 + published: ${HTTP_PORT:-80} + protocol: tcp + # HTTPS + - target: 443 + published: ${HTTPS_PORT:-443} + protocol: tcp + # HTTP/3 + - target: 443 + published: ${HTTP3_PORT:-443} + protocol: udp + +# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service +###> symfony/mercure-bundle ### +###< symfony/mercure-bundle ### + +volumes: + caddy_data: + caddy_config: +###> symfony/mercure-bundle ### +###< symfony/mercure-bundle ### diff --git a/frankenphp/Caddyfile b/frankenphp/Caddyfile new file mode 100644 index 00000000..83839304 --- /dev/null +++ b/frankenphp/Caddyfile @@ -0,0 +1,55 @@ +{ + {$CADDY_GLOBAL_OPTIONS} + + frankenphp { + {$FRANKENPHP_CONFIG} + } + + # https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm + order mercure after encode + order vulcain after reverse_proxy + order php_server before file_server +} + +{$CADDY_EXTRA_CONFIG} + +{$SERVER_NAME:localhost} { + log { + # Redact the authorization query parameter that can be set by Mercure + format filter { + wrap console + fields { + uri query { + replace authorization REDACTED + } + } + } + } + + root * /app/public + encode zstd br gzip + + mercure { + # Transport to use (default to Bolt) + transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db} + # Publisher JWT key + publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG} + # Subscriber JWT key + subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG} + # Allow anonymous subscribers (double-check that it's what you want) + anonymous + # Enable the subscription API (double-check that it's what you want) + subscriptions + # Extra directives + {$MERCURE_EXTRA_DIRECTIVES} + } + + vulcain + + {$CADDY_SERVER_EXTRA_DIRECTIVES} + + # Disable Topics tracking if not enabled explicitly: https://github.com/jkarlin/topics + header ?Permissions-Policy "browsing-topics=()" + + php_server +} diff --git a/frankenphp/conf.d/app.dev.ini b/frankenphp/conf.d/app.dev.ini new file mode 100644 index 00000000..e50f43d0 --- /dev/null +++ b/frankenphp/conf.d/app.dev.ini @@ -0,0 +1,5 @@ +; See https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host +; See https://github.com/docker/for-linux/issues/264 +; The `client_host` below may optionally be replaced with `discover_client_host=yes` +; Add `start_with_request=yes` to start debug session on each request +xdebug.client_host = host.docker.internal diff --git a/frankenphp/conf.d/app.ini b/frankenphp/conf.d/app.ini new file mode 100644 index 00000000..79a17dd8 --- /dev/null +++ b/frankenphp/conf.d/app.ini @@ -0,0 +1,13 @@ +expose_php = 0 +date.timezone = UTC +apc.enable_cli = 1 +session.use_strict_mode = 1 +zend.detect_unicode = 0 + +; https://symfony.com/doc/current/performance.html +realpath_cache_size = 4096K +realpath_cache_ttl = 600 +opcache.interned_strings_buffer = 16 +opcache.max_accelerated_files = 20000 +opcache.memory_consumption = 256 +opcache.enable_file_override = 1 diff --git a/frankenphp/conf.d/app.prod.ini b/frankenphp/conf.d/app.prod.ini new file mode 100644 index 00000000..3bcaa71e --- /dev/null +++ b/frankenphp/conf.d/app.prod.ini @@ -0,0 +1,2 @@ +opcache.preload_user = root +opcache.preload = /app/config/preload.php diff --git a/frankenphp/docker-entrypoint.sh b/frankenphp/docker-entrypoint.sh new file mode 100644 index 00000000..bdddc3ac --- /dev/null +++ b/frankenphp/docker-entrypoint.sh @@ -0,0 +1,60 @@ +#!/bin/sh +set -e + +if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then + # Install the project the first time PHP is started + # After the installation, the following block can be deleted + if [ ! -f composer.json ]; then + rm -Rf tmp/ + composer create-project "symfony/skeleton $SYMFONY_VERSION" tmp --stability="$STABILITY" --prefer-dist --no-progress --no-interaction --no-install + + cd tmp + cp -Rp . .. + cd - + rm -Rf tmp/ + + composer require "php:>=$PHP_VERSION" runtime/frankenphp-symfony + composer config --json extra.symfony.docker 'true' + + if grep -q ^DATABASE_URL= .env; then + echo "To finish the installation please press Ctrl+C to stop Docker Compose and run: docker compose up --build -d --wait" + sleep infinity + fi + fi + + if [ -z "$(ls -A 'vendor/' 2>/dev/null)" ]; then + composer install --prefer-dist --no-progress --no-interaction + fi + + if grep -q ^DATABASE_URL= .env; then + echo "Waiting for database to be ready..." + ATTEMPTS_LEFT_TO_REACH_DATABASE=60 + until [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ] || DATABASE_ERROR=$(php bin/console dbal:run-sql -q "SELECT 1" 2>&1); do + if [ $? -eq 255 ]; then + # If the Doctrine command exits with 255, an unrecoverable error occurred + ATTEMPTS_LEFT_TO_REACH_DATABASE=0 + break + fi + sleep 1 + ATTEMPTS_LEFT_TO_REACH_DATABASE=$((ATTEMPTS_LEFT_TO_REACH_DATABASE - 1)) + echo "Still waiting for database to be ready... Or maybe the database is not reachable. $ATTEMPTS_LEFT_TO_REACH_DATABASE attempts left." + done + + if [ $ATTEMPTS_LEFT_TO_REACH_DATABASE -eq 0 ]; then + echo "The database is not up or not reachable:" + echo "$DATABASE_ERROR" + exit 1 + else + echo "The database is now ready and reachable" + fi + + if [ "$( find ./migrations -iname '*.php' -print -quit )" ]; then + php bin/console doctrine:migrations:migrate --no-interaction + fi + fi + + setfacl -R -m u:www-data:rwX -m u:"$(whoami)":rwX var + setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var +fi + +exec docker-php-entrypoint "$@" diff --git a/frankenphp/worker.Caddyfile b/frankenphp/worker.Caddyfile new file mode 100644 index 00000000..d384ae4c --- /dev/null +++ b/frankenphp/worker.Caddyfile @@ -0,0 +1,4 @@ +worker { + file ./public/index.php + env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime +} From 8d816ab1ee9cac8a5f3efec21a61b1ae5d3cf70a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 18:08:22 +0100 Subject: [PATCH 02/10] Updated recipes to update docker related files --- Dockerfile | 3 + compose.override.yaml | 17 ++++ compose.yaml | 18 +++++ composer.json | 3 +- .../packages/dama_doctrine_test_bundle.yaml | 5 ++ symfony.lock | 80 +++++++++---------- 6 files changed, 85 insertions(+), 41 deletions(-) create mode 100644 config/packages/dama_doctrine_test_bundle.yaml diff --git a/Dockerfile b/Dockerfile index b9080886..009ede2b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,6 +35,9 @@ RUN set -eux; \ ENV COMPOSER_ALLOW_SUPERUSER=1 ###> recipes ### +###> doctrine/doctrine-bundle ### +RUN install-php-extensions pdo_pgsql +###< doctrine/doctrine-bundle ### ###< recipes ### COPY --link frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ diff --git a/compose.override.yaml b/compose.override.yaml index 5f141b1f..a1c02e0e 100644 --- a/compose.override.yaml +++ b/compose.override.yaml @@ -22,3 +22,20 @@ services: ###> symfony/mercure-bundle ### ###< symfony/mercure-bundle ### + +###> doctrine/doctrine-bundle ### + database: + ports: + - "5432" +###< doctrine/doctrine-bundle ### + +###> symfony/mailer ### + mailer: + image: axllent/mailpit + ports: + - "1025" + - "8025" + environment: + MP_SMTP_AUTH_ACCEPT_ANY: 1 + MP_SMTP_AUTH_ALLOW_INSECURE: 1 +###< symfony/mailer ### diff --git a/compose.yaml b/compose.yaml index 43a07900..aa6ad1e0 100644 --- a/compose.yaml +++ b/compose.yaml @@ -38,8 +38,26 @@ services: ###> symfony/mercure-bundle ### ###< symfony/mercure-bundle ### +###> doctrine/doctrine-bundle ### + database: + image: postgres:${POSTGRES_VERSION:-16}-alpine + environment: + POSTGRES_DB: ${POSTGRES_DB:-app} + # You should definitely change the password in production + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} + POSTGRES_USER: ${POSTGRES_USER:-app} + volumes: + - database_data:/var/lib/postgresql/data:rw + # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! + # - ./docker/db/data:/var/lib/postgresql/data:rw +###< doctrine/doctrine-bundle ### + volumes: caddy_data: caddy_config: ###> symfony/mercure-bundle ### ###< symfony/mercure-bundle ### + +###> doctrine/doctrine-bundle ### + database_data: +###< doctrine/doctrine-bundle ### diff --git a/composer.json b/composer.json index 3d760da4..8e0c4c72 100644 --- a/composer.json +++ b/composer.json @@ -165,7 +165,8 @@ "extra": { "symfony": { "allow-contrib": false, - "require": "6.4.*" + "require": "6.4.*", + "docker": true } } } diff --git a/config/packages/dama_doctrine_test_bundle.yaml b/config/packages/dama_doctrine_test_bundle.yaml new file mode 100644 index 00000000..3482cbae --- /dev/null +++ b/config/packages/dama_doctrine_test_bundle.yaml @@ -0,0 +1,5 @@ +when@test: + dama_doctrine_test: + enable_static_connection: true + enable_static_meta_data_cache: true + enable_static_query_cache: true diff --git a/symfony.lock b/symfony.lock index 278cef71..1e04eedd 100644 --- a/symfony.lock +++ b/symfony.lock @@ -44,15 +44,15 @@ "version": "1.3.3" }, "dama/doctrine-test-bundle": { - "version": "7.2", + "version": "8.0", "recipe": { "repo": "github.com/symfony/recipes-contrib", "branch": "main", - "version": "4.0", - "ref": "2c920f73a217f30bd4a37833c91071f4d3dc1ecd" + "version": "7.2", + "ref": "896306d79d4ee143af9eadf9b09fd34a8c391b70" }, "files": [ - "config/packages/test/dama_doctrine_test_bundle.yaml" + "./config/packages/dama_doctrine_test_bundle.yaml" ] }, "dnoegel/php-xdg-base-dir": { @@ -92,12 +92,12 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "2.10", - "ref": "0db4b12b5df45f5122213b4ecd18733ab7fa7d53" + "ref": "c170ded8fc587d6bd670550c43dafcf093762245" }, "files": [ - "config/packages/doctrine.yaml", - "src/Entity/.gitignore", - "src/Repository/.gitignore" + "./config/packages/doctrine.yaml", + "./src/Entity/.gitignore", + "./src/Repository/.gitignore" ] }, "doctrine/doctrine-fixtures-bundle": { @@ -174,7 +174,7 @@ "version": "3.5.0" }, "florianv/swap-bundle": { - "version": "5.0.0" + "version": "5.0.x-dev" }, "friendsofphp/proxy-manager-lts": { "version": "v1.0.5" @@ -183,16 +183,16 @@ "version": "v1.1.7" }, "gregwar/captcha-bundle": { - "version": "v2.0.6" + "version": "v2.2.0" }, "imagine/imagine": { "version": "1.2.2" }, "jbtronics/2fa-webauthn": { - "version": "dev-master" + "version": "v2.2.1" }, "jbtronics/dompdf-font-loader-bundle": { - "version": "dev-main" + "version": "v1.1.1" }, "knpuniversity/oauth2-client-bundle": { "version": "2.15", @@ -232,7 +232,7 @@ "version": "1.24.0" }, "nbgrp/onelogin-saml-bundle": { - "version": "v1.3.2" + "version": "v1.4.0" }, "nelmio/cors-bundle": { "version": "2.3", @@ -451,7 +451,7 @@ "version": "3.0.2" }, "shivas/versioning-bundle": { - "version": "3.1.3" + "version": "4.0.3" }, "symfony/apache-pack": { "version": "1.0", @@ -459,10 +459,10 @@ "repo": "github.com/symfony/recipes-contrib", "branch": "main", "version": "1.0", - "ref": "efb318193e48384eb5c5aadff15396ed698f8ffc" + "ref": "0f18b4decdf5695d692c1d0dfd65516a07a6adf1" }, "files": [ - "public/.htaccess" + "./public/.htaccess" ] }, "symfony/asset": { @@ -590,15 +590,15 @@ "version": "v4.2.3" }, "symfony/mailer": { - "version": "5.4", + "version": "6.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", "version": "4.3", - "ref": "2bf89438209656b85b9a49238c4467bff1b1f939" + "ref": "df66ee1f226c46f01e85c29c2f7acce0596ba35a" }, "files": [ - "config/packages/mailer.yaml" + "./config/packages/mailer.yaml" ] }, "symfony/maker-bundle": { @@ -617,12 +617,12 @@ "version": "v4.4.2" }, "symfony/monolog-bundle": { - "version": "3.7", + "version": "3.10", "recipe": { "repo": "github.com/symfony/recipes", - "branch": "master", + "branch": "main", "version": "3.7", - "ref": "213676c4ec929f046dfde5ea8e97625b81bc0578" + "ref": "aff23899c4440dd995907613c1dd709b6f59503f" }, "files": [ "./config/packages/monolog.yaml" @@ -640,13 +640,13 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "6.3", - "ref": "1f5830c331065b6e4c9d5fa2105e322d29fcd573" + "ref": "a411a0480041243d97382cac7984f7dce7813c08" }, "files": [ - ".env.test", - "bin/phpunit", - "phpunit.xml.dist", - "tests/bootstrap.php" + "./.env.test", + "./bin/phpunit", + "./phpunit.xml.dist", + "./tests/bootstrap.php" ] }, "symfony/polyfill-ctype": { @@ -730,12 +730,12 @@ "version": "v1.1.5" }, "symfony/stimulus-bundle": { - "version": "2.9", + "version": "2.16", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", - "version": "2.9", - "ref": "05c45071c7ecacc1e48f94bc43c1f8d4405fb2b2" + "version": "2.13", + "ref": "6acd9ff4f7fd5626d2962109bd4ebab351d43c43" }, "files": [ "./assets/bootstrap.js", @@ -755,11 +755,11 @@ "repo": "github.com/symfony/recipes", "branch": "main", "version": "6.3", - "ref": "64fe617084223633e1dedf9112935d8c95410d3e" + "ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b" }, "files": [ - "config/packages/translation.yaml", - "translations/.gitignore" + "./config/packages/translation.yaml", + "./translations/.gitignore" ] }, "symfony/translation-contracts": { @@ -769,16 +769,16 @@ "version": "v4.2.3" }, "symfony/twig-bundle": { - "version": "6.3", + "version": "6.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "main", - "version": "6.3", - "ref": "b7772eb20e92f3fb4d4fe756e7505b4ba2ca1a2c" + "version": "6.4", + "ref": "cab5fd2a13a45c266d45a7d9337e28dee6272877" }, "files": [ - "config/packages/twig.yaml", - "templates/base.html.twig" + "./config/packages/twig.yaml", + "./templates/base.html.twig" ] }, "symfony/uid": { @@ -809,7 +809,7 @@ ] }, "symfony/ux-turbo": { - "version": "v2.0.1" + "version": "v2.16.0" }, "symfony/validator": { "version": "5.4", @@ -880,7 +880,7 @@ "version": "v3.0.0" }, "twig/extra-bundle": { - "version": "v3.0.0" + "version": "v3.8.0" }, "twig/html-extra": { "version": "v3.0.3" From f8e92f98d00081c123029a07c51e1f8c748365e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 18:09:56 +0100 Subject: [PATCH 03/10] Updated the dockerignore from the values of frankenphp --- .dockerignore | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.dockerignore b/.dockerignore index 8929729c..ae823819 100644 --- a/.dockerignore +++ b/.dockerignore @@ -42,3 +42,40 @@ yarn-error.log /phpunit.xml .phpunit.result.cache ###< phpunit/phpunit ### + + +### From frankenphp + +**/*.log +**/*.md +**/*.php~ +**/*.dist.php +**/*.dist +**/*.cache +**/._* +**/.dockerignore +**/.DS_Store +**/.git/ +**/.gitattributes +**/.gitignore +**/.gitmodules +**/compose.*.yaml +**/compose.*.yml +**/compose.yaml +**/compose.yml +**/docker-compose.*.yaml +**/docker-compose.*.yml +**/docker-compose.yaml +**/docker-compose.yml +**/Dockerfile +**/Thumbs.db +.github/ +public/bundles/ +var/ +vendor/ +.editorconfig +.env.*.local +.env.local +.env.local.php +.env.test + From 7f78822a12c089e39315b99c821e95ec6876b0b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 18:49:54 +0100 Subject: [PATCH 04/10] Added frankenphp runtime for symfony --- composer.json | 1 + composer.lock | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8e0c4c72..20d02876 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,7 @@ "php-translation/symfony-bundle": "^0.14.0", "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.23", + "runtime/frankenphp-symfony": "^0.2.0", "s9e/text-formatter": "^2.1", "scheb/2fa-backup-code": "^6.8.0", "scheb/2fa-bundle": "^6.8.0", diff --git a/composer.lock b/composer.lock index 229eb618..5a7e5232 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c92c91e2ea0afe0c366c423a217bd0cb", + "content-hash": "19c280b6d5021cb69af33476174dfc1e", "packages": [ { "name": "api-platform/core", @@ -6467,6 +6467,58 @@ }, "time": "2020-09-05T13:00:25+00:00" }, + { + "name": "runtime/frankenphp-symfony", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-runtime/frankenphp-symfony.git", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-runtime/frankenphp-symfony/zipball/56822c3631d9522a3136a4c33082d006bdfe4bad", + "reference": "56822c3631d9522a3136a4c33082d006bdfe4bad", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/runtime": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Runtime\\FrankenPhpSymfony\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "kevin@dunglas.dev" + } + ], + "description": "FrankenPHP runtime for Symfony", + "support": { + "issues": "https://github.com/php-runtime/frankenphp-symfony/issues", + "source": "https://github.com/php-runtime/frankenphp-symfony/tree/0.2.0" + }, + "funding": [ + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-12-12T12:06:11+00:00" + }, { "name": "s9e/regexp-builder", "version": "1.4.6", From aa0ec15e6743343a55688d6776a0397d2c9f8e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 19:27:29 +0100 Subject: [PATCH 05/10] Allow to override the root user CLI check with COMPOSER_ALLOW_SUPERUSER --- src/EventListener/ConsoleEnsureWebserverUserListener.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/EventListener/ConsoleEnsureWebserverUserListener.php b/src/EventListener/ConsoleEnsureWebserverUserListener.php index dbd164c4..7c119304 100644 --- a/src/EventListener/ConsoleEnsureWebserverUserListener.php +++ b/src/EventListener/ConsoleEnsureWebserverUserListener.php @@ -55,6 +55,11 @@ class ConsoleEnsureWebserverUserListener //Check if we are trying to run as root if ($this->isRunningAsRoot()) { + //If the COMPOSER_ALLOW_SUPERUSER environment variable is set, we allow running as root + if ($_SERVER['COMPOSER_ALLOW_SUPERUSER'] ?? false) { + return; + } + $io->warning('You are running this command as root. This is not recommended, as it can cause permission problems. Please run this command as the webserver user "'. ($webserver_user ?? '??') . '" instead.'); $io->info('You might have already caused permission problems by running this command as wrong user. If you encounter issues with Part-DB, delete the var/cache directory completely and let it be recreated by Part-DB.'); if ($input->isInteractive() && !$io->confirm('Do you want to continue?', false)) { From 7271c8c6f1416cf136c6a3be71eda18c56032d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 19:50:21 +0100 Subject: [PATCH 06/10] Restructured frankenphp structure --- {frankenphp => .docker/frankenphp}/Caddyfile | 0 .../frankenphp}/conf.d/app.dev.ini | 0 .../frankenphp}/conf.d/app.ini | 0 .../frankenphp}/conf.d/app.prod.ini | 0 .../frankenphp}/docker-entrypoint.sh | 3 +- .../frankenphp}/worker.Caddyfile | 0 Dockerfile | 123 ++++++++---------- compose.override.yaml | 41 ------ compose.prod.yaml | 10 -- compose.yaml | 63 --------- 10 files changed, 57 insertions(+), 183 deletions(-) rename {frankenphp => .docker/frankenphp}/Caddyfile (100%) rename {frankenphp => .docker/frankenphp}/conf.d/app.dev.ini (100%) rename {frankenphp => .docker/frankenphp}/conf.d/app.ini (100%) rename {frankenphp => .docker/frankenphp}/conf.d/app.prod.ini (100%) rename {frankenphp => .docker/frankenphp}/docker-entrypoint.sh (97%) rename {frankenphp => .docker/frankenphp}/worker.Caddyfile (100%) delete mode 100644 compose.override.yaml delete mode 100644 compose.prod.yaml delete mode 100644 compose.yaml diff --git a/frankenphp/Caddyfile b/.docker/frankenphp/Caddyfile similarity index 100% rename from frankenphp/Caddyfile rename to .docker/frankenphp/Caddyfile diff --git a/frankenphp/conf.d/app.dev.ini b/.docker/frankenphp/conf.d/app.dev.ini similarity index 100% rename from frankenphp/conf.d/app.dev.ini rename to .docker/frankenphp/conf.d/app.dev.ini diff --git a/frankenphp/conf.d/app.ini b/.docker/frankenphp/conf.d/app.ini similarity index 100% rename from frankenphp/conf.d/app.ini rename to .docker/frankenphp/conf.d/app.ini diff --git a/frankenphp/conf.d/app.prod.ini b/.docker/frankenphp/conf.d/app.prod.ini similarity index 100% rename from frankenphp/conf.d/app.prod.ini rename to .docker/frankenphp/conf.d/app.prod.ini diff --git a/frankenphp/docker-entrypoint.sh b/.docker/frankenphp/docker-entrypoint.sh similarity index 97% rename from frankenphp/docker-entrypoint.sh rename to .docker/frankenphp/docker-entrypoint.sh index bdddc3ac..6a3a8f9a 100644 --- a/frankenphp/docker-entrypoint.sh +++ b/.docker/frankenphp/docker-entrypoint.sh @@ -57,4 +57,5 @@ if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var fi -exec docker-php-entrypoint "$@" +#exec docker-php-entrypoint "$@" +exec "$@" \ No newline at end of file diff --git a/frankenphp/worker.Caddyfile b/.docker/frankenphp/worker.Caddyfile similarity index 100% rename from frankenphp/worker.Caddyfile rename to .docker/frankenphp/worker.Caddyfile diff --git a/Dockerfile b/Dockerfile index 009ede2b..489ca40e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,81 +1,41 @@ -#syntax=docker/dockerfile:1.4 - -# Versions -FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream - -# The different stages of this Dockerfile are meant to be built into separate images -# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage -# https://docs.docker.com/compose/compose-file/#target +FROM debian:bookworm-slim -# Base FrankenPHP image -FROM frankenphp_upstream AS frankenphp_base +RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client file acl \ + && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ + && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ + && apt-get update && apt-get upgrade -y \ + && apt-get install -y apache2 php8.3 php8.3-fpm php8.3-opcache php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-intl php8.3-zip php8.3-xsl php8.3-sqlite3 php8.3-mysql gpg \ + && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; +# Create workdir and set permissions if directory does not exists +RUN mkdir -p /app WORKDIR /app -# persistent / runtime deps -# hadolint ignore=DL3008 -RUN apt-get update && apt-get install -y --no-install-recommends \ - acl \ - file \ - gettext \ - git \ - && rm -rf /var/lib/apt/lists/* +# Copy config files for php and caddy +ENV PHP_INI_DIR="/etc/php/8.3/" +COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ +COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile +COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile -RUN set -eux; \ - install-php-extensions \ - @composer \ - apcu \ - intl \ - opcache \ - zip \ - ; +#RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" -# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser -ENV COMPOSER_ALLOW_SUPERUSER=1 +# Install node and yarn +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* -###> recipes ### -###> doctrine/doctrine-bundle ### -RUN install-php-extensions pdo_pgsql -###< doctrine/doctrine-bundle ### -###< recipes ### +# Install FrankenPHP +COPY --from=dunglas/frankenphp:1-php8.3 /usr/local/bin/frankenphp /usr/local/bin/frankenphp -COPY --link frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ -COPY --link --chmod=755 frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint -COPY --link frankenphp/Caddyfile /etc/caddy/Caddyfile - -ENTRYPOINT ["docker-entrypoint"] - -HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 -CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ] - -# Dev FrankenPHP image -FROM frankenphp_base AS frankenphp_dev - -ENV APP_ENV=dev XDEBUG_MODE=off -VOLUME /app/var/ - -RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" - -RUN set -eux; \ - install-php-extensions \ - xdebug \ - ; - -COPY --link frankenphp/conf.d/app.dev.ini $PHP_INI_DIR/conf.d/ - -CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ] - -# Prod FrankenPHP image -FROM frankenphp_base AS frankenphp_prod - -ENV APP_ENV=prod +# And configure it ENV FRANKENPHP_CONFIG="import worker.Caddyfile" -RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" - -COPY --link frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ -COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile +# Install composer +ENV COMPOSER_ALLOW_SUPERUSER=1 +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # prevent the reinstallation of vendors at every changes in the source code COPY --link composer.* symfony.* ./ @@ -84,11 +44,38 @@ RUN set -eux; \ # copy sources COPY --link . ./ -RUN rm -Rf frankenphp/ +# Install composer and yarn dependencies for Part-DB RUN set -eux; \ mkdir -p var/cache var/log; \ composer dump-autoload --classmap-authoritative --no-dev; \ composer dump-env prod; \ composer run-script --no-dev post-install-cmd; \ chmod +x bin/console; sync; + +RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ + +# Use docker env to output logs to stdout +ENV APP_ENV=docker +ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" + +USER root + +ENTRYPOINT ["docker-entrypoint"] +CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] + +# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop +STOPSIGNAL SIGWINCH + +VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] + +HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 + +# See https://caddyserver.com/docs/conventions#file-locations for details +ENV XDG_CONFIG_HOME /config +ENV XDG_DATA_HOME /data + +EXPOSE 80 +EXPOSE 443 +EXPOSE 443/udp +EXPOSE 2019 \ No newline at end of file diff --git a/compose.override.yaml b/compose.override.yaml deleted file mode 100644 index a1c02e0e..00000000 --- a/compose.override.yaml +++ /dev/null @@ -1,41 +0,0 @@ -# Development environment override -services: - php: - build: - context: . - target: frankenphp_dev - volumes: - - ./:/app - - ./frankenphp/Caddyfile:/etc/caddy/Caddyfile:ro - - ./frankenphp/conf.d/app.dev.ini:/usr/local/etc/php/conf.d/app.dev.ini:ro - # If you develop on Mac or Windows you can remove the vendor/ directory - # from the bind-mount for better performance by enabling the next line: - #- /app/vendor - environment: - MERCURE_EXTRA_DIRECTIVES: demo - # See https://xdebug.org/docs/all_settings#mode - XDEBUG_MODE: "${XDEBUG_MODE:-off}" - extra_hosts: - # Ensure that host.docker.internal is correctly defined on Linux - - host.docker.internal:host-gateway - tty: true - -###> symfony/mercure-bundle ### -###< symfony/mercure-bundle ### - -###> doctrine/doctrine-bundle ### - database: - ports: - - "5432" -###< doctrine/doctrine-bundle ### - -###> symfony/mailer ### - mailer: - image: axllent/mailpit - ports: - - "1025" - - "8025" - environment: - MP_SMTP_AUTH_ACCEPT_ANY: 1 - MP_SMTP_AUTH_ALLOW_INSECURE: 1 -###< symfony/mailer ### diff --git a/compose.prod.yaml b/compose.prod.yaml deleted file mode 100644 index f0db05da..00000000 --- a/compose.prod.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# Production environment override -services: - php: - build: - context: . - target: frankenphp_prod - environment: - APP_SECRET: ${APP_SECRET} - MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} - MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET} diff --git a/compose.yaml b/compose.yaml deleted file mode 100644 index aa6ad1e0..00000000 --- a/compose.yaml +++ /dev/null @@ -1,63 +0,0 @@ -services: - php: - image: ${IMAGES_PREFIX:-}app-php - restart: unless-stopped - environment: - SERVER_NAME: ${SERVER_NAME:-localhost}, php:80 - MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} - MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} - TRUSTED_PROXIES: ${TRUSTED_PROXIES:-127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16} - TRUSTED_HOSTS: ^${SERVER_NAME:-example\.com|localhost}|php$$ - # Run "composer require symfony/orm-pack" to install and configure Doctrine ORM - DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8} - # Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration - MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure} - MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure - MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!} - # The two next lines can be removed after initial installation - SYMFONY_VERSION: ${SYMFONY_VERSION:-} - STABILITY: ${STABILITY:-stable} - volumes: - - caddy_data:/data - - caddy_config:/config - ports: - # HTTP - - target: 80 - published: ${HTTP_PORT:-80} - protocol: tcp - # HTTPS - - target: 443 - published: ${HTTPS_PORT:-443} - protocol: tcp - # HTTP/3 - - target: 443 - published: ${HTTP3_PORT:-443} - protocol: udp - -# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service -###> symfony/mercure-bundle ### -###< symfony/mercure-bundle ### - -###> doctrine/doctrine-bundle ### - database: - image: postgres:${POSTGRES_VERSION:-16}-alpine - environment: - POSTGRES_DB: ${POSTGRES_DB:-app} - # You should definitely change the password in production - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} - POSTGRES_USER: ${POSTGRES_USER:-app} - volumes: - - database_data:/var/lib/postgresql/data:rw - # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! - # - ./docker/db/data:/var/lib/postgresql/data:rw -###< doctrine/doctrine-bundle ### - -volumes: - caddy_data: - caddy_config: -###> symfony/mercure-bundle ### -###< symfony/mercure-bundle ### - -###> doctrine/doctrine-bundle ### - database_data: -###< doctrine/doctrine-bundle ### From 1548b9f8c855d4f7d10906f12acfa48608818c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 20:22:47 +0100 Subject: [PATCH 07/10] FrankenPHP dockerfile is now working --- .docker/frankenphp/conf.d/app.ini | 5 ++++ .docker/frankenphp/docker-entrypoint.sh | 3 +- .dockerignore | 1 - Dockerfile | 38 ++++++++++++++----------- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/.docker/frankenphp/conf.d/app.ini b/.docker/frankenphp/conf.d/app.ini index 79a17dd8..10a062f2 100644 --- a/.docker/frankenphp/conf.d/app.ini +++ b/.docker/frankenphp/conf.d/app.ini @@ -11,3 +11,8 @@ opcache.interned_strings_buffer = 16 opcache.max_accelerated_files = 20000 opcache.memory_consumption = 256 opcache.enable_file_override = 1 + +memory_limit = 256M + +upload_max_filesize=256M +post_max_size=300M \ No newline at end of file diff --git a/.docker/frankenphp/docker-entrypoint.sh b/.docker/frankenphp/docker-entrypoint.sh index 6a3a8f9a..1655af5a 100644 --- a/.docker/frankenphp/docker-entrypoint.sh +++ b/.docker/frankenphp/docker-entrypoint.sh @@ -57,5 +57,4 @@ if [ "$1" = 'frankenphp' ] || [ "$1" = 'php' ] || [ "$1" = 'bin/console' ]; then setfacl -dR -m u:www-data:rwX -m u:"$(whoami)":rwX var fi -#exec docker-php-entrypoint "$@" -exec "$@" \ No newline at end of file +exec docker-php-entrypoint "$@" \ No newline at end of file diff --git a/.dockerignore b/.dockerignore index ae823819..0c181569 100644 --- a/.dockerignore +++ b/.dockerignore @@ -47,7 +47,6 @@ yarn-error.log ### From frankenphp **/*.log -**/*.md **/*.php~ **/*.dist.php **/*.dist diff --git a/Dockerfile b/Dockerfile index 489ca40e..a42cd1ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,41 +1,45 @@ -FROM debian:bookworm-slim +FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream - -RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client file acl \ - && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ - && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ - && apt-get update && apt-get upgrade -y \ - && apt-get install -y apache2 php8.3 php8.3-fpm php8.3-opcache php8.3-curl php8.3-gd php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-intl php8.3-zip php8.3-xsl php8.3-sqlite3 php8.3-mysql gpg \ +RUN apt-get update && apt-get -y install curl zip mariadb-client file acl git gettext ca-certificates gnupg \ && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; # Create workdir and set permissions if directory does not exists RUN mkdir -p /app WORKDIR /app +# Install PHP +RUN set -eux; \ + install-php-extensions \ + @composer \ + apcu \ + intl \ + opcache \ + zip \ + pdo_mysql \ + pdo_sqlite \ + gd \ + bcmath \ + xsl \ + ; + # Copy config files for php and caddy -ENV PHP_INI_DIR="/etc/php/8.3/" COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile +ENV FRANKENPHP_CONFIG="import worker.Caddyfile" -#RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" # Install node and yarn RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* - -# Install FrankenPHP -COPY --from=dunglas/frankenphp:1-php8.3 /usr/local/bin/frankenphp /usr/local/bin/frankenphp - -# And configure it -ENV FRANKENPHP_CONFIG="import worker.Caddyfile" +RUN curl -sL https://deb.nodesource.com/setup_20.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* # Install composer ENV COMPOSER_ALLOW_SUPERUSER=1 -COPY --from=composer:latest /usr/bin/composer /usr/bin/composer +#COPY --from=composer:latest /usr/bin/composer /usr/bin/composer # prevent the reinstallation of vendors at every changes in the source code COPY --link composer.* symfony.* ./ From 28d86c8885b24c3b5d534c7bf47b6f76cb1bb83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 20:32:43 +0100 Subject: [PATCH 08/10] Show info about kernel runtime parameters on server info page --- src/Controller/ToolsController.php | 3 +++ templates/tools/server_infos/_php.html.twig | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/Controller/ToolsController.php b/src/Controller/ToolsController.php index b3a4997d..984e50eb 100644 --- a/src/Controller/ToolsController.php +++ b/src/Controller/ToolsController.php @@ -82,6 +82,9 @@ class ToolsController extends AbstractController 'php_opcache_enabled' => ini_get('opcache.enable'), 'php_upload_max_filesize' => ini_get('upload_max_filesize'), 'php_post_max_size' => ini_get('post_max_size'), + 'kernel_runtime_environment' => $this->getParameter('kernel.runtime_environment'), + 'kernel_runtime_mode' => $this->getParameter('kernel.runtime_mode'), + 'kernel_runtime' => $_SERVER['APP_RUNTIME'] ?? $_ENV['APP_RUNTIME'] ?? 'Symfony\\Component\\Runtime\\SymfonyRuntime', //DB section 'db_type' => $DBInfoHelper->getDatabaseType() ?? 'Unknown', diff --git a/templates/tools/server_infos/_php.html.twig b/templates/tools/server_infos/_php.html.twig index 0d9d252d..ea5a0b4c 100644 --- a/templates/tools/server_infos/_php.html.twig +++ b/templates/tools/server_infos/_php.html.twig @@ -31,5 +31,19 @@ Server time {{ "now" | format_datetime("long", "long") }} + + Symfony Kernel Runtime + {{ kernel_runtime }} + + + Symfony Kernel Runtime Environment + {{ kernel_runtime_environment }} + + + Symfony Kernel Runtime mode + {% for key, value in kernel_runtime_mode %} + {{ key }}: {{ value }}
+ {% endfor %} + \ No newline at end of file From 49f82127aaed217e37e3ca61e153484450cd3a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 20:49:33 +0100 Subject: [PATCH 09/10] Do not copy the content of public/media to docker image --- .dockerignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.dockerignore b/.dockerignore index 0c181569..472b1bb3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,8 @@ tests/ docs/ .git +/public/media/* + ###> symfony/framework-bundle ### /.env.local /.env.local.php From 3191028f74a73554e91d8abb320b2866f94654e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 Mar 2024 23:44:34 +0100 Subject: [PATCH 10/10] Added an github action to build the frankenPHP docker image --- .github/workflows/docker_frankenphp.yml | 77 ++++++++++++ Dockerfile | 158 +++++++++++++++--------- Dockerfile-frankenphp | 85 +++++++++++++ Dockerfile.old | 133 -------------------- 4 files changed, 265 insertions(+), 188 deletions(-) create mode 100644 .github/workflows/docker_frankenphp.yml create mode 100644 Dockerfile-frankenphp delete mode 100644 Dockerfile.old diff --git a/.github/workflows/docker_frankenphp.yml b/.github/workflows/docker_frankenphp.yml new file mode 100644 index 00000000..54b50ae3 --- /dev/null +++ b/.github/workflows/docker_frankenphp.yml @@ -0,0 +1,77 @@ +name: Docker Image Build (FrankenPHP) + +on: + #schedule: + # - cron: '0 10 * * *' # everyday at 10am + push: + branches: + - '**' + - '!l10n_**' + tags: + - 'v*.*.*' + - 'v*.*.*-**' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Docker meta + id: docker_meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base name for tags + images: | + partdborg/part-db + # Mark the image build from master as latest (as we dont have really releases yet) + tags: | + type=edge,branch=master + type=ref,event=branch, + type=ref,event=tag, + type=schedule + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=ref,event=branch + type=ref,event=pr + labels: | + org.opencontainers.image.source=${{ github.event.repository.clone_url }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.title=Part-DB + org.opencontainers.image.description=Part-DB is a web application for managing electronic components and your inventory. + org.opencontainers.image.url=https://github.com/Part-DB/Part-DB-server + org.opencontainers.image.source=https://github.com/Part-DB/Part-DB-server + org.opencontainers.image.authors=Jan Böhmer + org.opencontainers.licenses=AGPL-3.0-or-later + + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: 'arm64,arm' + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - + name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + file: Dockerfile-frankenphp + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a42cd1ed..85536666 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,62 +1,116 @@ -FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream +FROM debian:bullseye-slim -RUN apt-get update && apt-get -y install curl zip mariadb-client file acl git gettext ca-certificates gnupg \ +# Install needed dependencies for PHP build +#RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \ +# libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \ +# && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* + +RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client \ + && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ + && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ + && apt-get update && apt-get upgrade -y \ + && apt-get install -y apache2 php8.1 php8.1-fpm php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql gpg \ && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; +ENV APACHE_CONFDIR /etc/apache2 +ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars + # Create workdir and set permissions if directory does not exists -RUN mkdir -p /app -WORKDIR /app +RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html -# Install PHP -RUN set -eux; \ - install-php-extensions \ - @composer \ - apcu \ - intl \ - opcache \ - zip \ - pdo_mysql \ - pdo_sqlite \ - gd \ - bcmath \ - xsl \ - ; +# Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile) +# generically convert lines like +# export APACHE_RUN_USER=www-data +# into +# : ${APACHE_RUN_USER:=www-data} +# export APACHE_RUN_USER +# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") +RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ + set -eux; . "$APACHE_ENVVARS"; \ + # delete the "index.html" that installing Apache drops in here + rm -rvf /var/www/html/*; \ + \ + # logs should go to stdout / stderr + ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ + ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ + chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"; -# Copy config files for php and caddy -COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ -COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint -COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile -COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ -COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile -ENV FRANKENPHP_CONFIG="import worker.Caddyfile" +# Enable php-fpm +RUN a2enmod proxy_fcgi setenvif && a2enconf php8.1-fpm -RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" +# Configure php-fpm to log to stdout of the container (stdout of PID 1) +# We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint) +# We also disable the clear_env option to allow the use of environment variables in php-fpm +RUN { \ + echo '[global]'; \ + echo 'error_log = /proc/1/fd/1'; \ + echo; \ + echo '[www]'; \ + echo 'access.log = /proc/1/fd/1'; \ + echo 'catch_workers_output = yes'; \ + echo 'decorate_workers_output = no'; \ + echo 'clear_env = no'; \ + } | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf" + +# PHP files should be handled by PHP, and should be preferred over any other file type +RUN { \ + echo ''; \ + echo '\tSetHandler application/x-httpd-php'; \ + echo ''; \ + echo; \ + echo 'DirectoryIndex disabled'; \ + echo 'DirectoryIndex index.php index.html'; \ + echo; \ + echo ''; \ + echo '\tOptions -Indexes'; \ + echo '\tAllowOverride All'; \ + echo ''; \ + } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ + && a2enconf docker-php + +# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html) +RUN \ + { \ + echo 'opcache.memory_consumption=256'; \ + echo 'opcache.max_accelerated_files=20000'; \ + echo 'opcache.validate_timestamp=0'; \ + # Configure Realpath cache for performance + echo 'realpath_cache_size=4096K'; \ + echo 'realpath_cache_ttl=600'; \ + } > /etc/php/8.1/fpm/conf.d/symfony-recommended.ini + +# Increase upload limit and enable preloading +RUN \ + { \ + echo 'upload_max_filesize=256M'; \ + echo 'post_max_size=300M'; \ + echo 'opcache.preload_user=www-data'; \ + echo 'opcache.preload=/var/www/html/config/preload.php'; \ + } > /etc/php/8.1/fpm/conf.d/partdb.ini # Install node and yarn RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -RUN curl -sL https://deb.nodesource.com/setup_20.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* +RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* # Install composer -ENV COMPOSER_ALLOW_SUPERUSER=1 -#COPY --from=composer:latest /usr/bin/composer /usr/bin/composer +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer -# prevent the reinstallation of vendors at every changes in the source code -COPY --link composer.* symfony.* ./ -RUN set -eux; \ - composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress -# copy sources -COPY --link . ./ +# Set working dir +WORKDIR /var/www/html +COPY --chown=www-data:www-data . . + +# Setup apache2 +RUN a2dissite 000-default.conf +COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf +RUN a2ensite symfony.conf +RUN a2enmod rewrite # Install composer and yarn dependencies for Part-DB -RUN set -eux; \ - mkdir -p var/cache var/log; \ - composer dump-autoload --classmap-authoritative --no-dev; \ - composer dump-env prod; \ - composer run-script --no-dev post-install-cmd; \ - chmod +x bin/console; sync; - +USER www-data +RUN composer install -a --no-dev && composer clear-cache RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ # Use docker env to output logs to stdout @@ -65,21 +119,15 @@ ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" USER root -ENTRYPOINT ["docker-entrypoint"] -CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] +# Copy entrypoint to /usr/local/bin and make it executable +RUN cp ./.docker/partdb-entrypoint.sh /usr/local/bin/partdb-entrypoint.sh && chmod +x /usr/local/bin/partdb-entrypoint.sh +# Copy apache2-foreground to /usr/local/bin and make it executable +RUN cp ./.docker/apache2-foreground /usr/local/bin/apache2-foreground && chmod +x /usr/local/bin/apache2-foreground +ENTRYPOINT ["partdb-entrypoint.sh"] +CMD ["apache2-foreground"] # https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop STOPSIGNAL SIGWINCH -VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] - -HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 - -# See https://caddyserver.com/docs/conventions#file-locations for details -ENV XDG_CONFIG_HOME /config -ENV XDG_DATA_HOME /data - EXPOSE 80 -EXPOSE 443 -EXPOSE 443/udp -EXPOSE 2019 \ No newline at end of file +VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] \ No newline at end of file diff --git a/Dockerfile-frankenphp b/Dockerfile-frankenphp new file mode 100644 index 00000000..a42cd1ed --- /dev/null +++ b/Dockerfile-frankenphp @@ -0,0 +1,85 @@ +FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream + +RUN apt-get update && apt-get -y install curl zip mariadb-client file acl git gettext ca-certificates gnupg \ + && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; + +# Create workdir and set permissions if directory does not exists +RUN mkdir -p /app +WORKDIR /app + +# Install PHP +RUN set -eux; \ + install-php-extensions \ + @composer \ + apcu \ + intl \ + opcache \ + zip \ + pdo_mysql \ + pdo_sqlite \ + gd \ + bcmath \ + xsl \ + ; + +# Copy config files for php and caddy +COPY --link .docker/frankenphp/conf.d/app.ini $PHP_INI_DIR/conf.d/ +COPY --chmod=755 .docker/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint +COPY --link .docker/frankenphp/Caddyfile /etc/caddy/Caddyfile +COPY --link .docker/frankenphp/conf.d/app.prod.ini $PHP_INI_DIR/conf.d/ +COPY --link .docker/frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile +ENV FRANKENPHP_CONFIG="import worker.Caddyfile" + +RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" + +# Install node and yarn +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - +RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list +RUN curl -sL https://deb.nodesource.com/setup_20.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* + +# Install composer +ENV COMPOSER_ALLOW_SUPERUSER=1 +#COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +# prevent the reinstallation of vendors at every changes in the source code +COPY --link composer.* symfony.* ./ +RUN set -eux; \ + composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress + +# copy sources +COPY --link . ./ + +# Install composer and yarn dependencies for Part-DB +RUN set -eux; \ + mkdir -p var/cache var/log; \ + composer dump-autoload --classmap-authoritative --no-dev; \ + composer dump-env prod; \ + composer run-script --no-dev post-install-cmd; \ + chmod +x bin/console; sync; + +RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ + +# Use docker env to output logs to stdout +ENV APP_ENV=docker +ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" + +USER root + +ENTRYPOINT ["docker-entrypoint"] +CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"] + +# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop +STOPSIGNAL SIGWINCH + +VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] + +HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1 + +# See https://caddyserver.com/docs/conventions#file-locations for details +ENV XDG_CONFIG_HOME /config +ENV XDG_DATA_HOME /data + +EXPOSE 80 +EXPOSE 443 +EXPOSE 443/udp +EXPOSE 2019 \ No newline at end of file diff --git a/Dockerfile.old b/Dockerfile.old deleted file mode 100644 index 85536666..00000000 --- a/Dockerfile.old +++ /dev/null @@ -1,133 +0,0 @@ -FROM debian:bullseye-slim - -# Install needed dependencies for PHP build -#RUN apt-get update && apt-get install -y pkg-config curl libcurl4-openssl-dev libicu-dev \ -# libpng-dev libjpeg-dev libfreetype6-dev gnupg zip libzip-dev libjpeg62-turbo-dev libonig-dev libxslt-dev libwebp-dev vim \ -# && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* - -RUN apt-get update && apt-get -y install apt-transport-https lsb-release ca-certificates curl zip mariadb-client \ - && curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg \ - && sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' \ - && apt-get update && apt-get upgrade -y \ - && apt-get install -y apache2 php8.1 php8.1-fpm php8.1-opcache php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-bcmath php8.1-intl php8.1-zip php8.1-xsl php8.1-sqlite3 php8.1-mysql gpg \ - && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/*; - -ENV APACHE_CONFDIR /etc/apache2 -ENV APACHE_ENVVARS $APACHE_CONFDIR/envvars - -# Create workdir and set permissions if directory does not exists -RUN mkdir -p /var/www/html && chown -R www-data:www-data /var/www/html - -# Configure apache 2 (taken from https://github.com/docker-library/php/blob/master/8.2/bullseye/apache/Dockerfile) -# generically convert lines like -# export APACHE_RUN_USER=www-data -# into -# : ${APACHE_RUN_USER:=www-data} -# export APACHE_RUN_USER -# so that they can be overridden at runtime ("-e APACHE_RUN_USER=...") -RUN sed -ri 's/^export ([^=]+)=(.*)$/: ${\1:=\2}\nexport \1/' "$APACHE_ENVVARS"; \ - set -eux; . "$APACHE_ENVVARS"; \ - # delete the "index.html" that installing Apache drops in here - rm -rvf /var/www/html/*; \ - \ - # logs should go to stdout / stderr - ln -sfT /dev/stderr "$APACHE_LOG_DIR/error.log"; \ - ln -sfT /dev/stdout "$APACHE_LOG_DIR/access.log"; \ - ln -sfT /dev/stdout "$APACHE_LOG_DIR/other_vhosts_access.log"; \ - chown -R --no-dereference "$APACHE_RUN_USER:$APACHE_RUN_GROUP" "$APACHE_LOG_DIR"; - -# Enable php-fpm -RUN a2enmod proxy_fcgi setenvif && a2enconf php8.1-fpm - -# Configure php-fpm to log to stdout of the container (stdout of PID 1) -# We have to use /proc/1/fd/1 because /dev/stdout or /proc/self/fd/1 does not point to the container stdout (because we use apache as entrypoint) -# We also disable the clear_env option to allow the use of environment variables in php-fpm -RUN { \ - echo '[global]'; \ - echo 'error_log = /proc/1/fd/1'; \ - echo; \ - echo '[www]'; \ - echo 'access.log = /proc/1/fd/1'; \ - echo 'catch_workers_output = yes'; \ - echo 'decorate_workers_output = no'; \ - echo 'clear_env = no'; \ - } | tee "/etc/php/8.1/fpm/pool.d/zz-docker.conf" - -# PHP files should be handled by PHP, and should be preferred over any other file type -RUN { \ - echo ''; \ - echo '\tSetHandler application/x-httpd-php'; \ - echo ''; \ - echo; \ - echo 'DirectoryIndex disabled'; \ - echo 'DirectoryIndex index.php index.html'; \ - echo; \ - echo ''; \ - echo '\tOptions -Indexes'; \ - echo '\tAllowOverride All'; \ - echo ''; \ - } | tee "$APACHE_CONFDIR/conf-available/docker-php.conf" \ - && a2enconf docker-php - -# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html) -RUN \ - { \ - echo 'opcache.memory_consumption=256'; \ - echo 'opcache.max_accelerated_files=20000'; \ - echo 'opcache.validate_timestamp=0'; \ - # Configure Realpath cache for performance - echo 'realpath_cache_size=4096K'; \ - echo 'realpath_cache_ttl=600'; \ - } > /etc/php/8.1/fpm/conf.d/symfony-recommended.ini - -# Increase upload limit and enable preloading -RUN \ - { \ - echo 'upload_max_filesize=256M'; \ - echo 'post_max_size=300M'; \ - echo 'opcache.preload_user=www-data'; \ - echo 'opcache.preload=/var/www/html/config/preload.php'; \ - } > /etc/php/8.1/fpm/conf.d/partdb.ini - -# Install node and yarn -RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && apt-get update && apt-get install -y nodejs yarn && apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* - -# Install composer -COPY --from=composer:latest /usr/bin/composer /usr/bin/composer - - -# Set working dir -WORKDIR /var/www/html -COPY --chown=www-data:www-data . . - -# Setup apache2 -RUN a2dissite 000-default.conf -COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf -RUN a2ensite symfony.conf -RUN a2enmod rewrite - -# Install composer and yarn dependencies for Part-DB -USER www-data -RUN composer install -a --no-dev && composer clear-cache -RUN yarn install --network-timeout 600000 && yarn build && yarn cache clean && rm -rf node_modules/ - -# Use docker env to output logs to stdout -ENV APP_ENV=docker -ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db" - -USER root - -# Copy entrypoint to /usr/local/bin and make it executable -RUN cp ./.docker/partdb-entrypoint.sh /usr/local/bin/partdb-entrypoint.sh && chmod +x /usr/local/bin/partdb-entrypoint.sh -# Copy apache2-foreground to /usr/local/bin and make it executable -RUN cp ./.docker/apache2-foreground /usr/local/bin/apache2-foreground && chmod +x /usr/local/bin/apache2-foreground -ENTRYPOINT ["partdb-entrypoint.sh"] -CMD ["apache2-foreground"] - -# https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop -STOPSIGNAL SIGWINCH - -EXPOSE 80 -VOLUME ["/var/www/html/uploads", "/var/www/html/public/media"] \ No newline at end of file