mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-02-19 16:22:48 +01:00
* Initial plan * Refactor Dockerfiles to use Node.js multistage builds Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Fix node-builder stage with stub translations file Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Improve stub translations file creation using heredoc Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Build real translations in node-builder stage via cache warmup Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Improve error handling for cache warmup fallback Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Use native build platform for node-builder stage Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> * Do not include fallback for case that translations not exist * Use newer format for dockerfile-frankenphp * Dockfile added caching to package managers * Fixed frankenphp build * Fixed complain about missing symfony runtime * Use caching for frankenphp dockerfile * add target arch to dockerfile caches, to avoid problems * add targetarch arg * moved targetarch argument to correct position --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jbtronics <5410681+jbtronics@users.noreply.github.com> Co-authored-by: Jan Böhmer <mail@jan-boehmer.de>
230 lines
7.7 KiB
Docker
230 lines
7.7 KiB
Docker
# syntax=docker/dockerfile:1
|
|
ARG BASE_IMAGE=debian:bookworm-slim
|
|
ARG PHP_VERSION=8.4
|
|
ARG NODE_VERSION=22
|
|
# Node.js build stage for building frontend assets
|
|
# Use native platform for build stage as it's platform-independent
|
|
FROM --platform=$BUILDPLATFORM node:${NODE_VERSION}-bookworm-slim AS node-builder
|
|
ARG TARGETARCH
|
|
WORKDIR /app
|
|
|
|
# Install composer and minimal PHP for running Symfony commands
|
|
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
|
|
|
# Use BuildKit cache mounts for apt in builder stage
|
|
RUN --mount=type=cache,id=apt-cache-node-$TARGETARCH,target=/var/cache/apt \
|
|
--mount=type=cache,id=apt-lists-node-$TARGETARCH,target=/var/lib/apt/lists \
|
|
apt-get update && apt-get install -y --no-install-recommends \
|
|
php-cli \
|
|
php-xml \
|
|
php-mbstring \
|
|
unzip \
|
|
git \
|
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy composer files and install dependencies (needed for Symfony UX assets)
|
|
COPY composer.json composer.lock symfony.lock ./
|
|
|
|
# Use BuildKit cache for Composer downloads
|
|
RUN --mount=type=cache,id=composer-cache,target=/root/.cache/composer \
|
|
composer install --no-scripts --no-autoloader --no-dev --prefer-dist --ignore-platform-reqs
|
|
|
|
# Copy all application files needed for cache warmup and webpack build
|
|
COPY .env* ./
|
|
COPY bin ./bin
|
|
COPY config ./config
|
|
COPY src ./src
|
|
COPY translations ./translations
|
|
COPY public ./public
|
|
COPY assets ./assets
|
|
COPY webpack.config.js ./
|
|
|
|
# Generate autoloader
|
|
RUN composer dump-autoload
|
|
|
|
# Create required directories for cache warmup
|
|
RUN mkdir -p var/cache var/log uploads public/media
|
|
|
|
# Dump translations, which we need for cache warmup
|
|
RUN php bin/console cache:warmup -n --env=prod 2>&1
|
|
|
|
# Copy package files and install node dependencies
|
|
COPY package.json yarn.lock ./
|
|
# Use BuildKit cache for yarn/npm
|
|
RUN --mount=type=cache,id=yarn-cache,target=/root/.cache/yarn \
|
|
--mount=type=cache,id=npm-cache,target=/root/.npm \
|
|
yarn install --network-timeout 600000
|
|
|
|
# Build the assets
|
|
RUN yarn build
|
|
|
|
# Clean up
|
|
RUN yarn cache clean && rm -rf node_modules/
|
|
|
|
# Base stage for PHP
|
|
FROM ${BASE_IMAGE} AS base
|
|
ARG PHP_VERSION
|
|
ARG TARGETARCH
|
|
|
|
# Use BuildKit cache mounts for apt in base stage
|
|
RUN --mount=type=cache,id=apt-cache-$TARGETARCH,target=/var/cache/apt \
|
|
--mount=type=cache,id=apt-lists-$TARGETARCH,target=/var/lib/apt/lists \
|
|
apt-get update && apt-get -y install \
|
|
apt-transport-https \
|
|
lsb-release \
|
|
ca-certificates \
|
|
curl \
|
|
zip \
|
|
mariadb-client \
|
|
postgresql-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 \
|
|
php${PHP_VERSION} \
|
|
php${PHP_VERSION}-fpm \
|
|
php${PHP_VERSION}-opcache \
|
|
php${PHP_VERSION}-curl \
|
|
php${PHP_VERSION}-gd \
|
|
php${PHP_VERSION}-mbstring \
|
|
php${PHP_VERSION}-xml \
|
|
php${PHP_VERSION}-bcmath \
|
|
php${PHP_VERSION}-intl \
|
|
php${PHP_VERSION}-zip \
|
|
php${PHP_VERSION}-xsl \
|
|
php${PHP_VERSION}-sqlite3 \
|
|
php${PHP_VERSION}-mysql \
|
|
php${PHP_VERSION}-pgsql \
|
|
gpg \
|
|
sudo \
|
|
&& apt-get -y autoremove && apt-get clean autoclean && rm -rf /var/lib/apt/lists/* \
|
|
&& mkdir -p /var/www/html \
|
|
&& chown -R www-data:www-data /var/www/html \
|
|
&& rm -rvf /var/www/html/*
|
|
|
|
# Install composer
|
|
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
|
|
|
ENV APACHE_CONFDIR=/etc/apache2
|
|
ENV APACHE_ENVVARS=$APACHE_CONFDIR/envvars
|
|
|
|
# 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" && \
|
|
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"
|
|
|
|
# ---
|
|
|
|
FROM scratch AS apache-config
|
|
ARG PHP_VERSION
|
|
# 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
|
|
COPY <<EOF /etc/php/${PHP_VERSION}/fpm/pool.d/zz-docker.conf
|
|
[global]
|
|
error_log = /proc/1/fd/1
|
|
|
|
[www]
|
|
access.log = /proc/1/fd/1
|
|
catch_workers_output = yes
|
|
decorate_workers_output = no
|
|
clear_env = no
|
|
EOF
|
|
|
|
# PHP files should be handled by PHP, and should be preferred over any other file type
|
|
COPY <<EOF /etc/apache2/conf-available/docker-php.conf
|
|
<FilesMatch \\.php$>
|
|
SetHandler application/x-httpd-php
|
|
</FilesMatch>
|
|
|
|
DirectoryIndex disabled
|
|
DirectoryIndex index.php index.html
|
|
|
|
<Directory /var/www/>
|
|
Options -Indexes
|
|
AllowOverride All
|
|
</Directory>
|
|
EOF
|
|
|
|
# Enable opcache and configure it recommended for symfony (see https://symfony.com/doc/current/performance.html)
|
|
COPY <<EOF /etc/php/${PHP_VERSION}/fpm/conf.d/symfony-recommended.ini
|
|
opcache.memory_consumption=256
|
|
opcache.max_accelerated_files=20000
|
|
opcache.validate_timestamp=0
|
|
# Configure Realpath cache for performance
|
|
realpath_cache_size=4096K
|
|
realpath_cache_ttl=600
|
|
EOF
|
|
|
|
# Increase upload limit and enable preloading (disabled for now, as it does not seem to work properly, and require prod env anyway)
|
|
COPY <<EOF /etc/php/${PHP_VERSION}/fpm/conf.d/partdb.ini
|
|
upload_max_filesize=256M
|
|
post_max_size=300M
|
|
;opcache.preload_user=www-data
|
|
;opcache.preload=/var/www/html/config/preload.php
|
|
log_limit=8096
|
|
EOF
|
|
|
|
COPY ./.docker/symfony.conf /etc/apache2/sites-available/symfony.conf
|
|
|
|
# ---
|
|
|
|
FROM base
|
|
ARG PHP_VERSION
|
|
|
|
# Set working dir
|
|
WORKDIR /var/www/html
|
|
COPY --from=apache-config / /
|
|
COPY --chown=www-data:www-data . .
|
|
|
|
# Setup apache2
|
|
RUN a2dissite 000-default.conf && \
|
|
a2ensite symfony.conf && \
|
|
a2enmod proxy_fcgi setenvif && \
|
|
a2enconf php${PHP_VERSION}-fpm && \
|
|
a2enconf docker-php && \
|
|
a2enmod rewrite
|
|
|
|
# Install composer and yarn dependencies for Part-DB
|
|
USER www-data
|
|
# Use BuildKit cache for Composer when running as www-data by setting COMPOSER_CACHE_DIR
|
|
RUN --mount=type=cache,id=composer-cache,target=/tmp/.composer-cache \
|
|
COMPOSER_CACHE_DIR=/tmp/.composer-cache composer install -a --no-dev && \
|
|
composer clear-cache
|
|
|
|
# Copy built frontend assets from node-builder stage
|
|
COPY --from=node-builder --chown=www-data:www-data /app/public/build ./public/build
|
|
|
|
# Use docker env to output logs to stdout
|
|
ENV APP_ENV=docker
|
|
ENV DATABASE_URL="sqlite:///%kernel.project_dir%/uploads/app.db"
|
|
|
|
USER root
|
|
|
|
# Replace the php version placeholder in the entry point, with our php version
|
|
RUN sed -i "s/PHP_VERSION/${PHP_VERSION}/g" ./.docker/partdb-entrypoint.sh
|
|
|
|
# Copy entrypoint and apache2-foreground to /usr/local/bin and make it executable
|
|
# Convert CRLF -> LF and install entrypoint scripts with executable mode
|
|
RUN sed -i 's/\r$//' ./.docker/partdb-entrypoint.sh ./.docker/apache2-foreground && \
|
|
install -m 0755 ./.docker/partdb-entrypoint.sh /usr/local/bin/ && \
|
|
install -m 0755 ./.docker/apache2-foreground /usr/local/bin/
|
|
ENTRYPOINT ["partdb-entrypoint.sh"]
|
|
CMD ["/usr/local/bin/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"]
|