L'import manuel élève par élève est fastidieux pour les établissements qui gèrent des centaines d'élèves. Un wizard d'import en 4 étapes (upload → mapping → preview → confirmation) permet de traiter un fichier complet en une seule opération, avec détection automatique du format (Pronote, École Directe) et validation avant import. L'import est traité de manière asynchrone via Messenger pour ne pas bloquer l'interface, avec suivi de progression en temps réel et réutilisation des mappings entre imports successifs.
154 lines
5.2 KiB
Docker
154 lines
5.2 KiB
Docker
# syntax=docker/dockerfile:1
|
|
|
|
# =============================================================================
|
|
# PHP 8.5 + FrankenPHP - Backend Classeo
|
|
# =============================================================================
|
|
|
|
FROM dunglas/frankenphp:1-php8.5-alpine AS base
|
|
|
|
# Install system dependencies
|
|
RUN apk add --no-cache \
|
|
acl \
|
|
fcgi \
|
|
file \
|
|
gettext \
|
|
git \
|
|
freetype-dev \
|
|
icu-dev \
|
|
imagemagick-dev \
|
|
libjpeg-turbo-dev \
|
|
libpng-dev \
|
|
libzip-dev \
|
|
postgresql-dev \
|
|
rabbitmq-c-dev \
|
|
linux-headers \
|
|
$PHPIZE_DEPS
|
|
|
|
# Install PHP extensions (opcache is pre-installed in FrankenPHP)
|
|
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
|
|
&& docker-php-ext-install gd intl pcntl pdo_pgsql zip sockets
|
|
|
|
# Install Imagick extension for image processing (logo resize, etc.)
|
|
RUN pecl install imagick && docker-php-ext-enable imagick
|
|
|
|
# Install AMQP extension for RabbitMQ
|
|
RUN pecl install amqp && docker-php-ext-enable amqp
|
|
|
|
# Install Redis extension
|
|
RUN pecl install redis && docker-php-ext-enable redis
|
|
|
|
# Install Composer
|
|
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
|
|
|
# Set working directory
|
|
WORKDIR /app
|
|
|
|
# Configure PHP for production
|
|
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
|
|
|
|
# Custom PHP configuration
|
|
RUN echo "opcache.enable=1" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "opcache.memory_consumption=256" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "opcache.interned_strings_buffer=16" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "opcache.max_accelerated_files=20000" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "opcache.validate_timestamps=0" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "realpath_cache_size=4096K" >> "$PHP_INI_DIR/conf.d/opcache.ini" \
|
|
&& echo "realpath_cache_ttl=600" >> "$PHP_INI_DIR/conf.d/opcache.ini"
|
|
|
|
# =============================================================================
|
|
# Development stage
|
|
# =============================================================================
|
|
FROM base AS dev
|
|
|
|
# Install gosu for proper user switching
|
|
ENV GOSU_VERSION=1.17
|
|
RUN set -eux; \
|
|
apk add --no-cache --virtual .gosu-deps dpkg gnupg; \
|
|
dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
|
|
wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
|
|
chmod +x /usr/local/bin/gosu; \
|
|
gosu --version; \
|
|
gosu nobody true; \
|
|
apk del --no-network .gosu-deps
|
|
|
|
# Enable opcache revalidation for dev (zz- prefix loads last alphabetically)
|
|
RUN echo "opcache.validate_timestamps=1" >> "$PHP_INI_DIR/conf.d/zz-opcache-dev.ini"
|
|
|
|
# Enable Xdebug for development
|
|
RUN pecl install xdebug && docker-php-ext-enable xdebug
|
|
RUN echo "xdebug.mode=develop,debug,coverage" >> "$PHP_INI_DIR/conf.d/xdebug.ini" \
|
|
&& echo "xdebug.client_host=host.docker.internal" >> "$PHP_INI_DIR/conf.d/xdebug.ini" \
|
|
&& echo "xdebug.start_with_request=trigger" >> "$PHP_INI_DIR/conf.d/xdebug.ini"
|
|
|
|
# Caddy config for FrankenPHP
|
|
ENV SERVER_NAME=:8000
|
|
# In dev mode, we do NOT use worker mode to enable automatic file reloading
|
|
# Each request loads PHP fresh, so code changes are picked up immediately
|
|
# Worker mode is only used in production for performance
|
|
ENV FRANKENPHP_CONFIG=""
|
|
|
|
# Entrypoint: detect host UID/GID and run as matching user
|
|
# Uses gosu with UID:GID directly (no need to create user in Dockerfile)
|
|
COPY --chmod=755 <<'EOF' /usr/local/bin/docker-entrypoint.sh
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
# Detect UID/GID from mounted /app directory
|
|
HOST_UID=$(stat -c %u /app)
|
|
HOST_GID=$(stat -c %g /app)
|
|
|
|
# If root owns /app, run as root (CI environment or volume not mounted)
|
|
if [ "$HOST_UID" = "0" ]; then
|
|
# Install dependencies if not present
|
|
if [ ! -f /app/vendor/autoload.php ]; then
|
|
echo "Installing Composer dependencies..."
|
|
composer install --prefer-dist --no-progress --no-interaction
|
|
fi
|
|
mkdir -p /app/var/cache /app/var/log
|
|
exec "$@"
|
|
fi
|
|
|
|
# Ensure directories exist with correct ownership
|
|
mkdir -p /app/var/cache /app/var/log /data /config
|
|
chown -R "$HOST_UID:$HOST_GID" /app/var /data /config 2>/dev/null || true
|
|
|
|
# Install Composer dependencies if not present (as host user)
|
|
if [ ! -f /app/vendor/autoload.php ]; then
|
|
echo "Installing Composer dependencies..."
|
|
gosu "$HOST_UID:$HOST_GID" composer install --prefer-dist --no-progress --no-interaction
|
|
fi
|
|
|
|
# Run command as host user via gosu (using UID:GID directly)
|
|
exec gosu "$HOST_UID:$HOST_GID" "$@"
|
|
EOF
|
|
|
|
EXPOSE 8000
|
|
|
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
|
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
|
|
|
|
# =============================================================================
|
|
# Production stage
|
|
# =============================================================================
|
|
FROM base AS prod
|
|
|
|
ENV APP_ENV=prod
|
|
ENV SERVER_NAME=:8000
|
|
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
|
|
|
|
# Copy application files
|
|
COPY . /app
|
|
|
|
# Install dependencies (prod only, optimized)
|
|
RUN composer install --no-dev --prefer-dist --no-progress --no-interaction --optimize-autoloader
|
|
|
|
# Warmup cache
|
|
RUN php bin/console cache:warmup
|
|
|
|
# Ensure var directory exists with proper permissions
|
|
RUN mkdir -p var/cache var/log && chmod -R 755 var
|
|
|
|
EXPOSE 8000
|
|
|
|
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
|