# syntax=docker/dockerfile:1 # See https://hub.docker.com/r/docker/dockerfile ####################################################### # Configuration ####################################################### # See: https://github.com/mlocati/docker-php-extension-installer ARG DOCKER_PHP_EXTENSION_INSTALLER_VERSION="2.1.80" # See: https://github.com/composer/composer ARG COMPOSER_VERSION="2.6" # See: https://nginx.org/ ARG NGINX_VERSION="1.25.3" # See: https://github.com/ddollar/forego ARG FOREGO_VERSION="0.17.2" # See: https://github.com/hairyhenderson/gomplate ARG GOMPLATE_VERSION="v3.11.6" # See: https://github.com/jippi/dottie ARG DOTTIE_VERSION="v0.9.5" ### # PHP base configuration ### # See: https://hub.docker.com/_/php/tags ARG PHP_VERSION="8.1" # See: https://github.com/docker-library/docs/blob/master/php/README.md#image-variants ARG PHP_BASE_TYPE="apache" ARG PHP_DEBIAN_RELEASE="bullseye" ARG RUNTIME_UID=33 # often called 'www-data' ARG RUNTIME_GID=33 # often called 'www-data' # APT extra packages ARG APT_PACKAGES_EXTRA= # Extensions installed via [pecl install] # ! NOTE: imagick is installed from [master] branch on GitHub due to 8.3 bug on ARM that haven't # ! been released yet (after +10 months)! # ! See: https://github.com/Imagick/imagick/pull/641 ARG PHP_PECL_EXTENSIONS="redis https://codeload.github.com/Imagick/imagick/tar.gz/28f27044e435a2b203e32675e942eb8de620ee58" ARG PHP_PECL_EXTENSIONS_EXTRA= # Extensions installed via [docker-php-ext-install] ARG PHP_EXTENSIONS="intl bcmath zip pcntl exif curl gd" ARG PHP_EXTENSIONS_EXTRA="" ARG PHP_EXTENSIONS_DATABASE="pdo_pgsql pdo_mysql pdo_sqlite" # GPG key for nginx apt repository ARG NGINX_GPGKEY="573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62" # GPP key path for nginx apt repository ARG NGINX_GPGKEY_PATH="/usr/share/keyrings/nginx-archive-keyring.gpg" ####################################################### # Docker "copy from" images ####################################################### # Composer docker image from Docker Hub # # NOTE: Docker will *not* pull this image unless it's referenced (via build target) FROM composer:${COMPOSER_VERSION} AS composer-image # php-extension-installer image from Docker Hub # # NOTE: Docker will *not* pull this image unless it's referenced (via build target) FROM mlocati/php-extension-installer:${DOCKER_PHP_EXTENSION_INSTALLER_VERSION} AS php-extension-installer # nginx webserver from Docker Hub. # Used to copy some docker-entrypoint files for [nginx-runtime] # # NOTE: Docker will *not* pull this image unless it's referenced (via build target) FROM nginx:${NGINX_VERSION} AS nginx-image # Forego is a Procfile "runner" that makes it trival to run multiple # processes under a simple init / PID 1 process. # # NOTE: Docker will *not* pull this image unless it's referenced (via build target) # # See: https://github.com/nginx-proxy/forego FROM nginxproxy/forego:${FOREGO_VERSION}-debian AS forego-image # Dottie makes working with .env files easier and safer # # NOTE: Docker will *not* pull this image unless it's referenced (via build target) # # See: https://github.com/jippi/dottie FROM ghcr.io/jippi/dottie:${DOTTIE_VERSION} AS dottie-image # gomplate-image grabs the gomplate binary from GitHub releases # # It's in its own layer so it can be fetched in parallel with other build steps FROM php:${PHP_VERSION}-${PHP_BASE_TYPE}-${PHP_DEBIAN_RELEASE} AS gomplate-image ARG TARGETARCH ARG TARGETOS ARG GOMPLATE_VERSION RUN set -ex \ && curl \ --silent \ --show-error \ --location \ --output /usr/local/bin/gomplate \ https://github.com/hairyhenderson/gomplate/releases/download/${GOMPLATE_VERSION}/gomplate_${TARGETOS}-${TARGETARCH} \ && chmod +x /usr/local/bin/gomplate \ && /usr/local/bin/gomplate --version ####################################################### # Base image ####################################################### FROM php:${PHP_VERSION}-${PHP_BASE_TYPE}-${PHP_DEBIAN_RELEASE} AS base ARG BUILDKIT_SBOM_SCAN_STAGE="true" ARG APT_PACKAGES_EXTRA ARG PHP_DEBIAN_RELEASE ARG PHP_VERSION ARG RUNTIME_GID ARG RUNTIME_UID ARG TARGETPLATFORM ENV DEBIAN_FRONTEND="noninteractive" # Ensure we run all scripts through 'bash' rather than 'sh' SHELL ["/bin/bash", "-c"] # Set www-data to be RUNTIME_UID/RUNTIME_GID RUN groupmod --gid ${RUNTIME_GID} www-data \ && usermod --uid ${RUNTIME_UID} --gid ${RUNTIME_GID} www-data RUN set -ex \ && mkdir -pv /var/www/ \ && chown -R ${RUNTIME_UID}:${RUNTIME_GID} /var/www WORKDIR /var/www/ ENV APT_PACKAGES_EXTRA=${APT_PACKAGES_EXTRA} # Install and configure base layer COPY docker/shared/root/docker/install/base.sh /docker/install/base.sh RUN --mount=type=cache,id=pixelfed-apt-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/lib/apt \ --mount=type=cache,id=pixelfed-apt-cache-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/cache/apt \ /docker/install/base.sh ####################################################### # PHP: extensions ####################################################### FROM base AS php-extensions ARG PHP_DEBIAN_RELEASE ARG PHP_EXTENSIONS ARG PHP_EXTENSIONS_DATABASE ARG PHP_EXTENSIONS_EXTRA ARG PHP_PECL_EXTENSIONS ARG PHP_PECL_EXTENSIONS_EXTRA ARG PHP_VERSION ARG TARGETPLATFORM COPY --from=php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ COPY docker/shared/root/docker/install/php-extensions.sh /docker/install/php-extensions.sh RUN --mount=type=cache,id=pixelfed-pear-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/tmp/pear \ --mount=type=cache,id=pixelfed-apt-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/lib/apt \ --mount=type=cache,id=pixelfed-apt-cache-${PHP_VERSION}-${PHP_DEBIAN_RELEASE}-${TARGETPLATFORM},sharing=locked,target=/var/cache/apt \ PHP_EXTENSIONS=${PHP_EXTENSIONS} \ PHP_EXTENSIONS_DATABASE=${PHP_EXTENSIONS_DATABASE} \ PHP_EXTENSIONS_EXTRA=${PHP_EXTENSIONS_EXTRA} \ PHP_PECL_EXTENSIONS=${PHP_PECL_EXTENSIONS} \ PHP_PECL_EXTENSIONS_EXTRA=${PHP_PECL_EXTENSIONS_EXTRA} \ /docker/install/php-extensions.sh ####################################################### # Node: Build frontend ####################################################### # NOTE: Since the nodejs build is CPU architecture agnostic, # we only want to build once and cache it for other architectures. # We force the (CPU) [--platform] here to be architecture # of the "builder"/"server" and not the *target* CPU architecture # (e.g.) building the ARM version of Pixelfed on AMD64. FROM --platform=${BUILDARCH} node:lts AS frontend-build ARG BUILDARCH ARG BUILD_FRONTEND=0 ARG RUNTIME_UID ARG RUNTIME_GID ARG NODE_ENV=production ENV NODE_ENV=$NODE_ENV WORKDIR /var/www/ SHELL [ "/usr/bin/bash", "-c" ] # Install NPM dependencies RUN --mount=type=cache,id=pixelfed-node-${BUILDARCH},sharing=locked,target=/tmp/cache \ --mount=type=bind,source=package.json,target=/var/www/package.json \ --mount=type=bind,source=package-lock.json,target=/var/www/package-lock.json \ < "$NGINX_GPGKEY_PATH" \ && echo "deb [signed-by=${NGINX_GPGKEY_PATH}] https://nginx.org/packages/mainline/debian/ ${PHP_DEBIAN_RELEASE} nginx" >> /etc/apt/sources.list.d/nginx.list \ && apt-get update \ && apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}* # copy docker entrypoints from the *real* nginx image directly COPY --link --from=nginx-image /docker-entrypoint.d /docker/entrypoint.d/ COPY docker/nginx/root / COPY docker/nginx/Procfile . STOPSIGNAL SIGQUIT CMD ["forego", "start", "-r"]