Config backup, a Docker dev/prod split, and a Gitea-built release image.
Added
- /settings -> General -> "Configuration backup": JSON export/import of the
panel's general settings + attribute definitions
(App\Services\ConfigBackupService); audited as config.export / config.import.
Export can leave out the attribute-encryption key. No AD data included.
- docker/compose.dev.yaml: live-reload dev stack that bind-mounts the working
tree. docker/php/Dockerfile is now multi-stage (base -> dev / prod).
- .github/workflows/release.yml: on every vX.Y.Z tag, builds the prod image and
pushes gitea.kzbikowski.pl/kzbkowski/adconsole:{X.Y.Z,X.Y,latest}.
Changed
- docker/compose.yaml: self-contained prod image (app code + composer install
--no-dev baked in via COPY); persistent state in docker/data/{app_storage,db};
defaults to the released image (ADCONSOLE_VERSION pins a tag, ADCONSOLE_IMAGE
replaces the ref). Apache now honours public/.htaccess (AllowOverride All).
Run from the repo root with --env-file .env.
- Repo root now holds only README.md; CHANGELOG / CONTRIBUTING / SECURITY /
CODE_OF_CONDUCT moved under docs/.
Upgrade notes: docs/upgrading.md#v110--docker-layout. Full log: docs/CHANGELOG.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JKT9p3bfP8RZesExdYCS52
105 lines
4.3 KiB
Docker
105 lines
4.3 KiB
Docker
# syntax=docker/dockerfile:1
|
|
# =============================================================================
|
|
# ADconsole container image — PHP 8.4 + Apache. Multi-stage:
|
|
#
|
|
# base : PHP + extensions + Apache (docroot = public/) + Composer + entrypoint
|
|
# dev : base only. The repo is bind-mounted at runtime (compose.dev.yaml);
|
|
# the entrypoint installs deps + generates APP_KEY on first boot and
|
|
# opcache re-checks files on every request, so edits are live.
|
|
# prod : base + the application COPYed in and `composer install --no-dev`
|
|
# run at build time → a self-contained image (docker/compose.yaml, or
|
|
# `docker build`) that you can tag and push straight from the repo;
|
|
# only .env and docker/data/ are mounted at runtime.
|
|
#
|
|
# Build context is the repo root. Default target is `prod` (last stage):
|
|
# docker build -f docker/php/Dockerfile -t adconsole:local .
|
|
# =============================================================================
|
|
|
|
FROM php:8.4-apache AS base
|
|
|
|
# --- System packages + PHP extensions -------------------------------------
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl \
|
|
libcurl4-openssl-dev \
|
|
libonig-dev \
|
|
libzip-dev \
|
|
libldap2-dev \
|
|
unzip \
|
|
git \
|
|
&& docker-php-ext-install -j"$(nproc)" curl mbstring zip pdo pdo_mysql ldap opcache \
|
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
|
|
# Apache: enable rewrite + serve from public/ + honour Laravel's public/.htaccess.
|
|
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
|
|
RUN a2enmod rewrite headers \
|
|
&& sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
|
|
&& sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \
|
|
&& printf '<Directory ${APACHE_DOCUMENT_ROOT}>\n\tAllowOverride All\n\tRequire all granted\n</Directory>\n' \
|
|
> /etc/apache2/conf-available/adconsole.conf \
|
|
&& a2enconf adconsole
|
|
|
|
# Composer (from the official image, no network installer).
|
|
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
|
|
|
COPY docker/php/entrypoint.sh /usr/local/bin/adconsole-entrypoint
|
|
RUN chmod +x /usr/local/bin/adconsole-entrypoint
|
|
|
|
ENV COMPOSER_ALLOW_SUPERUSER=1
|
|
WORKDIR /var/www/html
|
|
|
|
ENTRYPOINT ["adconsole-entrypoint"]
|
|
CMD ["apache2-foreground"]
|
|
|
|
|
|
# =============================================================================
|
|
# dev — no app code baked in; compose.dev.yaml bind-mounts the repo over
|
|
# /var/www/html. opcache revalidates on every hit so changes show immediately.
|
|
# =============================================================================
|
|
FROM base AS dev
|
|
|
|
ENV ADCONSOLE_ENV=dev
|
|
|
|
RUN { \
|
|
echo 'opcache.enable=1'; \
|
|
echo 'opcache.enable_cli=0'; \
|
|
echo 'opcache.validate_timestamps=1'; \
|
|
echo 'opcache.revalidate_freq=0'; \
|
|
} > /usr/local/etc/php/conf.d/opcache.ini
|
|
|
|
|
|
# =============================================================================
|
|
# prod (default) — self-contained image. The build context is trimmed by
|
|
# .dockerignore (no vendor/, node_modules/, tests/, docs/, .env, ./data …).
|
|
# =============================================================================
|
|
FROM base AS prod
|
|
|
|
ENV ADCONSOLE_ENV=prod
|
|
|
|
# Aggressive opcache: the code in the image never changes at runtime.
|
|
RUN { \
|
|
echo 'opcache.enable=1'; \
|
|
echo 'opcache.enable_cli=0'; \
|
|
echo 'opcache.memory_consumption=128'; \
|
|
echo 'opcache.max_accelerated_files=20000'; \
|
|
echo 'opcache.validate_timestamps=0'; \
|
|
} > /usr/local/etc/php/conf.d/opcache.ini
|
|
|
|
# 1. Dependencies — manifests first so this layer survives code-only edits.
|
|
COPY composer.json composer.lock ./
|
|
RUN composer install --no-dev --no-interaction --prefer-dist --no-scripts --no-autoloader
|
|
|
|
# 2. Application code.
|
|
COPY . .
|
|
|
|
# 3. Optimised autoloader + package discovery, then the writable runtime tree.
|
|
RUN composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader \
|
|
&& mkdir -p \
|
|
storage/framework/cache/data \
|
|
storage/framework/sessions \
|
|
storage/framework/views \
|
|
storage/logs \
|
|
storage/app/public \
|
|
storage/app/private \
|
|
bootstrap/cache \
|
|
&& chown -R www-data:www-data storage bootstrap/cache
|