feat: fix dockerfile
CI / 🧪 Tests Laravel (push) Successful in 1m55s
CI / 🐳 Build & Push Image (push) Failing after 6s

This commit is contained in:
2026-07-16 15:44:03 +02:00
parent 5cf0510aa5
commit edb7f6d2a1
4 changed files with 208 additions and 63 deletions
+80
View File
@@ -0,0 +1,80 @@
APP_NAME=Bowly
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://bemeal.leonmorival.com
APP_MOBILE_SCHEME=bowly
APP_LOCALE=fr
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=fr_FR
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=warning
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_SECURE_COOKIE=true
SESSION_SAME_SITE=lax
CACHE_STORE=redis
QUEUE_CONNECTION=redis
REDIS_CLIENT=predis
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
FILESYSTEM_DISK=s3
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=eu-north-1
AWS_BUCKET=bowli
AWS_URL=
AWS_ENDPOINT=
AWS_USE_PATH_STYLE_ENDPOINT=false
MAIL_MAILER=resend
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME="${APP_NAME}"
RESEND_API_KEY=
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://meilisearch:7700
MEILISEARCH_KEY=
GEMINI_API_KEY=
AI_MEAL_USER_NAME="Daily Meal AI"
AI_MEAL_USER_EMAIL=ai@daily-meal.local
AI_MEAL_IMAGE_PATH=meal-posts/ai-generated
AI_MEAL_IMAGE_QUALITY=medium
AI_MEAL_TEXT_TIMEOUT=90
AI_MEAL_IMAGE_TIMEOUT=120
EXPO_ACCESS_TOKEN=
STRAVA_CLIENT_ID=
STRAVA_CLIENT_SECRET=
STRAVA_SCOPE=read,activity:read
STRIPE_KEY=
STRIPE_SECRET=
STRIPE_WEBHOOK_SECRET=
CASHIER_CURRENCY=eur
HEALTH_SECRET_TOKEN=
HORIZON_HEARTBEAT_URL=
SCHEDULE_HEARTBEAT_URL=
IMAGE_TAG=latest
ADMINER_PORT=8080
+3 -3
View File
@@ -35,12 +35,12 @@ jobs:
cd /data/stacks/daily-meal-api
echo "Pull nouvelle image"
docker compose pull
docker compose -f docker-compose.prod.yml pull
echo "Redémarrage"
docker compose up -d
docker compose -f docker-compose.prod.yml up -d
echo "Migration Laravel"
docker compose exec -T app php artisan migrate --force
docker compose -f docker-compose.prod.yml exec -T app php artisan migrate --force
EOF
+30 -48
View File
@@ -1,61 +1,43 @@
# --- Étape de Build (Composer) ---
FROM composer:2 AS composer-bin
FROM dunglas/frankenphp:php8.4-alpine
FROM dunglas/frankenphp:1.3-php8.4-alpine AS composer-build
WORKDIR /app
WORKDIR /var/www/html
COPY --from=composer-bin /usr/bin/composer /usr/bin/composer
RUN install-php-extensions intl zip bcmath pdo_pgsql pcntl redis
COPY . .
RUN composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
# --- Étape de Build (Node) ---
FROM node:20-alpine AS node-build
WORKDIR /var/www/html
COPY package*.json ./
RUN npm ci
COPY --from=composer-build /var/www/html/vendor ./vendor
COPY . .
RUN npm run build
# --- Étape Finale (Production) ---
FROM dunglas/frankenphp:1.3-php8.4-alpine
# On installe les extensions pour le fonctionnement de l'app en prod
RUN apk add --no-cache \
libpq-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
icu-dev
RUN install-php-extensions \
intl \
pdo_pgsql \
gd \
zip \
opcache \
pcntl \
redis
zip \
intl
WORKDIR /var/www/html
COPY --from=composer-build /var/www/html /var/www/html
COPY --from=node-build /var/www/html/public/build /var/www/html/public/build
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# Permissions (crucial pour Laravel)
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
ENV APP_ENV=production
ENV APP_RUNTIME=Laravel\FrankenPHP\Runtime
COPY composer.json composer.lock ./
HEALTHCHECK NONE
RUN composer install \
--no-dev \
--no-interaction \
--prefer-dist \
--optimize-autoloader \
--no-scripts
CMD ["sh", "-c", "php artisan migrate --force && php artisan storage:link && php artisan optimize && php artisan view:cache && php artisan event:cache && frankenphp run --config /etc/caddy/Caddyfile"]
COPY . .
RUN composer dump-autoload --optimize
RUN chown -R www-data:www-data storage bootstrap/cache
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 8002
ENTRYPOINT ["/entrypoint.sh"]
+95 -12
View File
@@ -1,17 +1,78 @@
name: bemeal
name: daily-meal-api
x-app-image: &app-image git.leonmorival.xyz/leonm/daily-meal-api:${IMAGE_TAG:-latest}
x-app-environment: &app-environment
APP_ENV: production
APP_DEBUG: "false"
APP_RUNTIME: "Laravel\\FrankenPHP\\Runtime"
SERVER_NAME: ":80"
DB_CONNECTION: pgsql
DB_HOST: postgres
DB_PORT: "5432"
REDIS_HOST: redis
REDIS_CLIENT: predis
QUEUE_CONNECTION: redis
SCOUT_DRIVER: meilisearch
MEILISEARCH_HOST: http://meilisearch:7700
x-app-volumes: &app-volumes
- storage-data:/var/www/html/storage/app
- storage-public-data:/var/www/html/storage/app/public
x-app-service: &app-service
image: *app-image
restart: unless-stopped
env_file:
- .env
environment: *app-environment
volumes: *app-volumes
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
meilisearch:
condition: service_started
networks:
- internal
services:
pgsql:
app:
<<: *app-service
container_name: daily-meal-api
networks:
- proxy
- internal
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/api/health >/dev/null 2>&1"]
start_period: 30s
interval: 10s
timeout: 5s
retries: 12
horizon:
<<: *app-service
container_name: daily-meal-api-horizon
command: ["php", "artisan", "horizon"]
scheduler:
<<: *app-service
container_name: daily-meal-api-scheduler
command: ["php", "artisan", "schedule:work"]
postgres:
image: postgres:15-alpine
container_name: bemeal-pgsql
container_name: daily-meal-api-postgres
restart: unless-stopped
environment:
POSTGRES_DB: "${DB_DATABASE:?DB_DATABASE is required}"
POSTGRES_USER: "${DB_USERNAME:?DB_USERNAME is required}"
POSTGRES_PASSWORD: "${DB_PASSWORD:?DB_PASSWORD is required}"
volumes:
- pgsql-data:/var/lib/postgresql/data
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 5432"]
test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -p 5432 -U $$POSTGRES_USER -d $$POSTGRES_DB"]
start_period: 30s
interval: 5s
timeout: 5s
@@ -21,36 +82,58 @@ services:
redis:
image: redis:alpine
container_name: bemeal-redis
container_name: daily-meal-api-redis
restart: unless-stopped
volumes:
- redis-data:/data
networks:
- internal
meilisearch:
image: getmeili/meilisearch:latest
container_name: daily-meal-api-meilisearch
restart: unless-stopped
environment:
MEILI_NO_ANALYTICS: "true"
MEILI_MASTER_KEY: "${MEILISEARCH_KEY:?MEILISEARCH_KEY is required}"
volumes:
- meilisearch-data:/meili_data
networks:
- internal
adminer:
image: adminer:latest
container_name: bemeal-adminer
container_name: daily-meal-api-adminer
restart: unless-stopped
profiles:
- debug
ports:
- "127.0.0.1:${ADMINER_PORT:-8080}:8080"
environment:
ADMINER_DEFAULT_SERVER: bemeal-pgsql
ADMINER_DEFAULT_SERVER: postgres
networks:
- internal
volumes:
pgsql-data:
postgres-data:
external: true
name: bemeal_pgsql_data
redis-data:
name: bemeal_redis_data
meilisearch-data:
name: bemeal_meilisearch_data
storage-data:
name: bemeal_storage_data
storage-public-data:
name: bemeal_storage_public_data
networks:
internal:
proxy:
external: true
name: bemeal_internal
internal:
driver: bridge