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] 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