From 9896f0926fb514277c4771f3c7172f712473474a Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 20 Oct 2024 22:03:49 +0200 Subject: [PATCH] ci: add a docker fpm flavor (#7416) --- .github/workflows/docker.yml | 17 +++- scripts/docker/Dockerfile | 2 +- scripts/docker/Dockerfile-fpm | 173 ++++++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 scripts/docker/Dockerfile-fpm diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 59e480a5a09..bff15e01f80 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -26,6 +26,16 @@ jobs: strategy: fail-fast: false + matrix: + flavor: + - name: apache + file: scripts/docker/Dockerfile + tag: main + suffix: + - name: fpm + file: scripts/docker/Dockerfile-fpm + tag: main-fpm + suffix: -fpm permissions: contents: read @@ -54,6 +64,9 @@ jobs: org.opencontainers.image.description="This is MonicaHQ, your personal memory! MonicaHQ is like a CRM but for the friends, family, and acquaintances around you." org.opencontainers.image.title="MonicaHQ, the Personal Relationship Manager" org.opencontainers.image.vendor="Monica" + flavor: | + latest=${{ matrix.flavor.tag == 'main' && 'auto' || 'false' }} + suffix=${{ matrix.flavor.suffix }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -76,9 +89,9 @@ jobs: with: push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.docker_meta.outputs.tags }} - cache-from: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.package-name }}:main + cache-from: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.package-name }}:${{ matrix.flavor.tag }} labels: ${{ steps.docker_meta.outputs.labels }} - file: scripts/docker/Dockerfile + file: ${{ matrix.flavor.file }} context: . platforms: ${{ (github.event_name != 'pull_request') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=This is MonicaHQ your personal memory! MonicaHQ is like a CRM but for the friends family and acquaintances around you. diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile index 2b38ae2149b..ee51a9527df 100644 --- a/scripts/docker/Dockerfile +++ b/scripts/docker/Dockerfile @@ -18,7 +18,7 @@ RUN set -ex; \ ## Image -FROM php:8.2-apache +FROM php:8.3-apache # entrypoint.sh dependencies RUN set -ex; \ diff --git a/scripts/docker/Dockerfile-fpm b/scripts/docker/Dockerfile-fpm new file mode 100644 index 00000000000..4567125e64d --- /dev/null +++ b/scripts/docker/Dockerfile-fpm @@ -0,0 +1,173 @@ +### +### ~ Monica dev Dockerfile +### +### This file is used for dev purpose. +### The standard monica image definition will be found here: https://github.com/monicahq/docker +### This file is based on the `fpm` variant in the above mentioned repo +### + +## Build assets +FROM node:18 AS yarn + +WORKDIR /var/www/html +COPY . ./ +RUN set -ex; \ + \ + yarn install --immutable; \ + yarn run build + + +## Image +FROM php:8.3-fpm + +# entrypoint.sh dependencies +RUN set -ex; \ + \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + bash \ + busybox-static \ + unzip \ + ; \ + rm -rf /var/lib/apt/lists/* + +# Install required PHP extensions +RUN set -ex; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + libicu-dev \ + zlib1g-dev \ + libzip-dev \ + libpng-dev \ + libpq-dev \ + libxml2-dev \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libgmp-dev \ + libmemcached-dev \ + libssl-dev \ + libwebp-dev \ + libcurl4-openssl-dev \ + ; \ + \ + debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \ + if [ ! -e /usr/include/gmp.h ]; then ln -s /usr/include/$debMultiarch/gmp.h /usr/include/gmp.h; fi;\ + docker-php-ext-configure intl; \ + docker-php-ext-configure gd --with-jpeg --with-freetype --with-webp; \ + docker-php-ext-configure gmp; \ + docker-php-ext-install -j$(nproc) \ + intl \ + zip \ + bcmath \ + gd \ + gmp \ + pdo_mysql \ + mysqli \ + pdo_pgsql \ + soap \ + ; \ + \ +# pecl will claim success even if one install fails, so we need to perform each install separately + pecl install APCu; \ + pecl install memcached; \ + pecl install redis; \ + \ + docker-php-ext-enable \ + apcu \ + memcached \ + redis \ + ; \ + \ +# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark; \ + ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \ + | awk '/=>/ { so = $(NF-1); if (index(so, "/usr/local/") == 1) { next }; gsub("^/(usr/)?", "", so); print so }' \ + | sort -u \ + | xargs -r dpkg-query -S \ + | cut -d: -f1 \ + | sort -u \ + | xargs -rt apt-mark manual; \ + \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + rm -rf /var/lib/apt/lists/* + +# Set crontab for schedules +RUN set -ex; \ + \ + mkdir -p /var/spool/cron/crontabs; \ + rm -f /var/spool/cron/crontabs/root; \ + echo '* * * * * php /var/www/html/artisan schedule:run -v' > /var/spool/cron/crontabs/www-data + +# Opcache +ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS="0" \ + PHP_OPCACHE_MAX_ACCELERATED_FILES="20000" \ + PHP_OPCACHE_MEMORY_CONSUMPTION="192" \ + PHP_OPCACHE_MAX_WASTED_PERCENTAGE="10" +# Limits +ENV PHP_MEMORY_LIMIT="512M" \ + PHP_UPLOAD_LIMIT="512M" +RUN set -ex; \ + \ + docker-php-ext-enable opcache; \ + { \ + echo '[opcache]'; \ + echo 'opcache.enable=1'; \ + echo 'opcache.revalidate_freq=0'; \ + echo 'opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS}'; \ + echo 'opcache.max_accelerated_files=${PHP_OPCACHE_MAX_ACCELERATED_FILES}'; \ + echo 'opcache.memory_consumption=${PHP_OPCACHE_MEMORY_CONSUMPTION}'; \ + echo 'opcache.max_wasted_percentage=${PHP_OPCACHE_MAX_WASTED_PERCENTAGE}'; \ + echo 'opcache.interned_strings_buffer=16'; \ + echo 'opcache.fast_shutdown=1'; \ + } > $PHP_INI_DIR/conf.d/opcache-recommended.ini; \ + \ + echo 'apc.enable_cli=1' >> $PHP_INI_DIR/conf.d/docker-php-ext-apcu.ini; \ + \ + { \ + echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \ + echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \ + echo 'post_max_size=${PHP_UPLOAD_LIMIT}'; \ + } > $PHP_INI_DIR/conf.d/limits.ini; + +WORKDIR /var/www/html + +# Copy the local (outside Docker) source into the working directory, +# copy system files into their proper homes, and set file ownership +# correctly +COPY --chown=www-data:www-data . ./ + +RUN set -ex; \ + \ + mkdir -p bootstrap/cache; \ + mkdir -p storage; \ + chown -R www-data:www-data bootstrap/cache storage; \ + chmod -R g+w bootstrap/cache storage + +# Composer installation +COPY scripts/docker/install-composer.sh /usr/local/sbin/ +RUN install-composer.sh + +# Install composer dependencies +RUN set -ex; \ + \ + mkdir -p storage/framework/views; \ + composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader --no-dev; \ + composer clear-cache; \ + rm -rf .composer + +# Install assets +COPY --from=yarn --chown=www-data:www-data /var/www/html/public/build ./public/build + +COPY --chown=www-data:www-data scripts/docker/.env.production .env +COPY scripts/docker/entrypoint.sh \ + scripts/docker/entrypoint-unittests.sh \ + scripts/docker/cron.sh \ + scripts/docker/queue.sh \ + /usr/local/bin/ + +ENTRYPOINT ["entrypoint.sh"] +CMD ["php-fpm"]