# TEMPLATE — image de production de l'API d'une coquille.
#
# Dépendances installées depuis le registre Composer public de Forgejo
# (clauzier/cms-core) : AUCUN token requis ni embarqué. Copier dans
# <coquille>/api/Dockerfile tel quel.

FROM php:8.5-cli-alpine

RUN apk add --no-cache git unzip bash sqlite-dev pkgconfig fcgi

# pdo_sqlite pour la base embarquée.
RUN docker-php-ext-install pdo_sqlite

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app

# Dépendances d'abord (cache layer). Retry ×3 : les dists pointent
# api.github.com, parfois capricieux depuis les petits VPS.
COPY composer.json composer.lock ./
RUN COMPOSER_ALLOW_SUPERUSER=1 composer install \
    --prefer-dist --no-dev --no-interaction --no-progress --no-scripts \
 || { sleep 8; COMPOSER_ALLOW_SUPERUSER=1 composer install \
    --prefer-dist --no-dev --no-interaction --no-progress --no-scripts; } \
 || { sleep 20; COMPOSER_ALLOW_SUPERUSER=1 composer install \
    --prefer-dist --no-dev --no-interaction --no-progress --no-scripts; }

# Code applicatif. .dockerignore DOIT contenir vendor/ (sinon il écrase
# l'install --no-dev), node_modules, .git, .env.
COPY . .

ENV COMPOSER_ALLOW_SUPERUSER=1

# Sans .env le boot API Platform casse (métadonnées corrompues) et
# package:discover exige une base existante : fichier sqlite créé ici,
# valeurs réelles fournies par l'environnement Coolify au run.
#
# Sans le lien public/storage, chaque média téléversé est servi en 404.
RUN cp -n .env.example .env \
    && mkdir -p data storage/framework/cache/data storage/framework/sessions \
       storage/framework/views storage/logs storage/app/public bootstrap/cache \
    && touch data/database.sqlite \
    && ln -sfn ../storage/app/public public/storage \
    && php artisan key:generate --force \
    && chown -R www-data:www-data storage data bootstrap/cache

# La base vit dans `data/` et non dans `database/`, et c'est tout l'intérêt :
# un volume monté sur `database/` masque les migrations et les seeders de
# l'image, si bien qu'une migration nouvellement publiée n'est jamais jouée et
# que la table manque en production — 500 « no such table » avec une CI verte
# et un déploiement réussi. Posée ici et pas seulement dans le compose :
# l'image doit pointer la base persistée même si un orchestrateur oublie la
# variable, sinon le fichier vide de l'image prend silencieusement le relais.
ENV DB_DATABASE=/app/data/database.sqlite

# Les médias vivent hors de l'image : sans ce volume ils disparaissent au
# redéploiement suivant.
VOLUME ["/app/data", "/app/storage/app/public"]

# Purger TOUS les stores au boot (le cache métadonnées API Platform vit
# sur le store 'file'), migrations idempotentes, serveur.
EXPOSE 8000
CMD ["sh", "-c", "php artisan optimize:clear >/dev/null 2>&1 || true; php artisan cache:clear --store=file >/dev/null 2>&1 || true; php artisan migrate --force && exec php artisan serve --host=0.0.0.0 --port=8000"]
