mirror of
https://github.com/FOSSBilling/FOSSBilling.git
synced 2026-10-23 03:37:01 +09:00
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
172 lines
7.3 KiB
Docker
172 lines
7.3 KiB
Docker
# syntax=docker/dockerfile:1.28@sha256:bb22d9815c728170f72750f4e5b0d672e06176142e1d602c7e66c050100b7e5b
|
|
|
|
ARG PHP_VERSION=8.5
|
|
ARG NODE_VERSION=24
|
|
|
|
FROM php:${PHP_VERSION}-apache AS php-base
|
|
|
|
RUN set -eux; \
|
|
savedAptMark="$(apt-mark showmanual)"; \
|
|
apt-get update; \
|
|
apt-get install -y --no-install-recommends \
|
|
ca-certificates \
|
|
cron \
|
|
curl \
|
|
libbz2-dev \
|
|
libfreetype6-dev \
|
|
libicu-dev \
|
|
libjpeg62-turbo-dev \
|
|
libpng-dev \
|
|
libzip-dev \
|
|
unzip \
|
|
zlib1g-dev; \
|
|
docker-php-ext-configure gd --with-freetype --with-jpeg; \
|
|
docker-php-ext-install -j"$(nproc)" bz2 gd intl pdo_mysql zip; \
|
|
a2enmod rewrite; \
|
|
apt-mark auto '.*' > /dev/null; \
|
|
apt-mark manual \
|
|
${savedAptMark} \
|
|
ca-certificates \
|
|
cron \
|
|
curl \
|
|
unzip; \
|
|
find /usr/local -type f \( -perm /0111 -o -name '*.so' \) -exec sh -c 'ldd "$@" 2>/dev/null' sh '{}' + \
|
|
| awk 'NF == 4 && $2 == "=>" { print $3 } NF == 2 && $1 ~ /^\// { print $1 }' \
|
|
| sort -u \
|
|
| while read -r library; do \
|
|
library="$(readlink -e "${library}")"; \
|
|
dpkg-query --search "${library}" 2>/dev/null | grep -v '^diversion ' | head -n1 | cut -d: -f1; \
|
|
done \
|
|
| sort -u \
|
|
| xargs -r apt-mark manual; \
|
|
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
|
|
apt-get clean; \
|
|
rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
|
|
|
FROM php-base AS composer-base
|
|
|
|
WORKDIR /app
|
|
|
|
COPY --from=composer:2@sha256:af98f42dfff7c68ba8d53c2164fd9fde1087b7d449514baa38c418b1f6bc4bac /usr/bin/composer /usr/bin/composer
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends git \
|
|
&& apt-get clean \
|
|
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
|
|
|
FROM composer-base AS php-vendor
|
|
|
|
COPY composer.json composer.lock ./
|
|
COPY src/library ./src/library
|
|
COPY src/modules ./src/modules
|
|
|
|
RUN --mount=type=cache,target=/tmp/composer-cache,id=composer-prod \
|
|
set -eux; \
|
|
find ./src/modules -type d -name tests -prune -exec rm -rf {} +; \
|
|
COMPOSER_CACHE_DIR=/tmp/composer-cache \
|
|
composer install --prefer-dist --no-dev --optimize-autoloader --no-interaction --no-progress
|
|
|
|
FROM composer-base AS php-dev-vendor
|
|
COPY composer.json composer.lock ./
|
|
COPY src/library ./src/library
|
|
COPY src/modules ./src/modules
|
|
|
|
RUN --mount=type=cache,target=/tmp/composer-cache,id=composer-dev \
|
|
COMPOSER_CACHE_DIR=/tmp/composer-cache \
|
|
composer install --prefer-dist --optimize-autoloader --no-interaction --no-progress
|
|
|
|
FROM node:${NODE_VERSION}-bookworm-slim AS frontend-assets
|
|
|
|
WORKDIR /app
|
|
|
|
COPY package.json package-lock.json ./
|
|
COPY src/themes/default/admin/package.json src/themes/default/admin/package.json
|
|
COPY src/themes/default/client/package.json src/themes/default/client/package.json
|
|
|
|
RUN --mount=type=cache,target=/root/.npm npm ci
|
|
|
|
COPY tsconfig.json ./
|
|
COPY src/themes/default/admin ./src/themes/default/admin
|
|
COPY src/themes/default/client ./src/themes/default/client
|
|
COPY src/modules ./src/modules
|
|
COPY frontend ./frontend
|
|
|
|
RUN NODE_ENV=production npm run build
|
|
|
|
FROM php-base AS release-tree
|
|
|
|
WORKDIR /app
|
|
|
|
ARG FOSSBILLING_VERSION=0.0.1
|
|
ARG FOSSBILLING_VERSION_TRUNCATE=0
|
|
ARG SENTRY_DSN=
|
|
ARG INSTALL_TRANSLATIONS=true
|
|
ARG TRANSLATIONS_URL=https://github.com/FOSSBilling/locale/releases/latest/download/translations.zip
|
|
ARG TRANSLATIONS_SHA256=
|
|
|
|
COPY --from=composer:2@sha256:af98f42dfff7c68ba8d53c2164fd9fde1087b7d449514baa38c418b1f6bc4bac /usr/bin/composer /usr/bin/composer
|
|
COPY composer.json ./composer.json
|
|
COPY src ./src
|
|
COPY README.md LICENSE ./src/
|
|
COPY --from=php-vendor /app/src/vendor ./src/vendor
|
|
COPY --from=frontend-assets /app/src/public/assets ./src/public/assets
|
|
COPY --from=frontend-assets /app/src/themes/default/admin/assets/build ./src/themes/default/admin/assets/build
|
|
COPY --from=frontend-assets /app/src/themes/default/client/assets/build ./src/themes/default/client/assets/build
|
|
|
|
RUN set -eux; \
|
|
find ./src/modules -type d -name tests -prune -exec rm -rf {} +; \
|
|
mkdir -p ./src/locale; \
|
|
if [ "${INSTALL_TRANSLATIONS}" = "true" ]; then \
|
|
curl -fsSL "${TRANSLATIONS_URL}" -o /tmp/translations.zip; \
|
|
if [ -n "${TRANSLATIONS_SHA256}" ]; then \
|
|
echo "${TRANSLATIONS_SHA256} /tmp/translations.zip" | sha256sum -c -; \
|
|
fi; \
|
|
unzip -oq /tmp/translations.zip -d ./src/locale; \
|
|
rm /tmp/translations.zip; \
|
|
fi; \
|
|
FOSSBILLING_VERSION="${FOSSBILLING_VERSION}" \
|
|
FOSSBILLING_VERSION_TRUNCATE="${FOSSBILLING_VERSION_TRUNCATE}" \
|
|
SENTRY_DSN="${SENTRY_DSN}" \
|
|
php -r '$version = getenv("FOSSBILLING_VERSION") ?: "0.0.1"; $truncate = (int) (getenv("FOSSBILLING_VERSION_TRUNCATE") ?: 0); if ($truncate > 0) { $version = substr($version, 0, $truncate); } $versionFile = "./src/library/FOSSBilling/Version.php"; $contents = file_get_contents($versionFile); $quote = chr(39); $pattern = "/public const string VERSION = " . $quote . "[^" . $quote . "]+" . $quote . ";/"; $replacement = "public const string VERSION = " . var_export($version, true) . ";"; $contents = preg_replace($pattern, $replacement, $contents, 1, $count); if ($contents === null || $count !== 1) { fwrite(STDERR, "Failed to replace FOSSBilling version.\n"); exit(1); } file_put_contents($versionFile, $contents); $dsn = getenv("SENTRY_DSN"); if ($dsn !== false && $dsn !== "") { $sentryFile = "./src/library/FOSSBilling/SentryHelper.php"; file_put_contents($sentryFile, str_replace("--replace--this--during--release--process--", $dsn, file_get_contents($sentryFile))); }'; \
|
|
php -r '$composer = json_decode(file_get_contents("./composer.json"), true, 512, JSON_THROW_ON_ERROR); $composer["autoload"]["psr-4"]["FOSSBilling\\"] = "library/FOSSBilling/"; $composer["autoload"]["psr-4"]["Box\\Mod\\"] = "modules/"; $composer["autoload"]["classmap"] = ["library/"]; $composer["config"]["vendor-dir"] = "vendor"; file_put_contents("./src/composer.json", json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR) . PHP_EOL);'; \
|
|
composer --no-plugins dump-autoload --working-dir=./src --no-dev --optimize --no-interaction; \
|
|
php -r '$class = "FOSSBilling\\Cache\\CacheFactory"; require "./src/vendor/autoload.php"; if (!class_exists($class)) { fwrite(STDERR, "Release Composer autoloader is missing {$class}.\n"); exit(1); }'; \
|
|
rm ./composer.json ./src/composer.json; \
|
|
chmod -R u=rwX,go=rX ./src
|
|
|
|
FROM scratch AS release-artifact
|
|
|
|
COPY --from=release-tree /app/src /
|
|
|
|
FROM php-base AS runtime
|
|
|
|
WORKDIR /var/www/html
|
|
|
|
COPY --from=release-tree --chown=www-data:www-data /app/src/ ./
|
|
|
|
RUN set -eux; \
|
|
mkdir -p data/cache data/log data/uploads; \
|
|
touch /var/log/cron.log; \
|
|
chown -R www-data:www-data data /var/log/cron.log; \
|
|
echo '*/5 * * * * /usr/local/bin/php /var/www/html/cron.php >> /var/log/cron.log 2>&1' > /tmp/www-data.cron; \
|
|
crontab -u www-data /tmp/www-data.cron; \
|
|
rm /tmp/www-data.cron
|
|
|
|
CMD ["sh", "-c", "cron & exec apache2-foreground"]
|
|
|
|
FROM runtime AS test
|
|
|
|
WORKDIR /workspace
|
|
|
|
COPY --from=release-tree /app/src ./src
|
|
COPY src/modules ./src/modules
|
|
COPY --from=php-dev-vendor /app/src/vendor ./src/vendor
|
|
COPY composer.json composer.lock phpstan.neon phpunit.xml.dist ./
|
|
COPY tests ./tests
|
|
COPY tools ./tools
|
|
|
|
RUN set -eux; \
|
|
php -r '$config = require "./src/config-sample.php"; file_put_contents("./src/config.php", "<?php\nreturn " . var_export($config, true) . ";\n");'; \
|
|
mkdir -p ./src/data/cache ./src/data/log ./src/data/uploads; \
|
|
chown -R www-data:www-data ./src/data ./src/config.php
|