Compare commits

...

3 commits

6 changed files with 56 additions and 6 deletions

6
.env
View file

@ -14,6 +14,12 @@
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
###> docker / compose (not used by the Symfony app) ###
# Single source of truth for the npm version baked into the frontend + e2e dev
# images. Passed to their Dockerfiles via compose build args. Bump here only.
NPM_VERSION=11.17.0
###< docker / compose ###
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=

View file

@ -34,7 +34,12 @@ services:
# Standalone React/Vite SPA (dev only — not in compose.prod.yaml; see #33/#35).
frontend:
image: node:22-alpine
# Custom dev image = node:22-alpine with npm pinned (see frontend/Dockerfile.dev).
build:
context: ./frontend
dockerfile: Dockerfile.dev
args:
NPM_VERSION: ${NPM_VERSION}
working_dir: /app
volumes:
- ./frontend:/app
@ -49,6 +54,15 @@ services:
environment:
# Reliable file-watching under the bind-mount.
CHOKIDAR_USEPOLLING: "true"
# Marks the service healthy only once Vite is actually serving — the e2e
# runner waits on this (condition: service_healthy) to avoid racing startup.
# start_period covers the slow first boot (global npm install + npm install).
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:5173/"]
interval: 5s
timeout: 3s
retries: 5
start_period: 90s
tty: true
# Playwright e2e runner (browsers + libs preinstalled). On-demand only — opt
@ -57,7 +71,12 @@ services:
# browsers are needed (NixOS host can't run Chromium natively). Image tag is
# pinned to the @playwright/test version in e2e/package.json — keep in sync.
playwright:
image: mcr.microsoft.com/playwright:v1.49.0-jammy
# Custom image = the Playwright image with npm pinned (see e2e/Dockerfile).
build:
context: ./e2e
dockerfile: Dockerfile
args:
NPM_VERSION: ${NPM_VERSION}
profiles: [e2e]
working_dir: /e2e
volumes:
@ -67,8 +86,10 @@ services:
# Target the SPA by compose service name, not localhost.
E2E_BASE_URL: "http://frontend:5173"
depends_on:
- frontend
# Install deps then run the suite; the image already has the browsers.
# Wait until Vite is actually serving, not just the container started.
frontend:
condition: service_healthy
# npm is pinned in the image (e2e/Dockerfile); just install deps + run.
command: sh -c "npm install && npm test"
###> symfony/mercure-bundle ###

12
e2e/Dockerfile Normal file
View file

@ -0,0 +1,12 @@
# E2E runner: the official Playwright image (browsers + libs preinstalled) with
# npm pinned to a specific version baked in, so it's not re-fetched per run and
# doesn't drift with whatever npm the base image happens to ship.
#
# The base image tag MUST match @playwright/test in package.json (browsers must
# match the runner). NPM_VERSION is the single source of truth in the root .env
# (passed via compose build args) — bump it there, not here.
FROM mcr.microsoft.com/playwright:v1.49.0-jammy
ARG NPM_VERSION
RUN npm install -g "npm@${NPM_VERSION}"
ENV NPM_CONFIG_UPDATE_NOTIFIER=false

11
frontend/Dockerfile.dev Normal file
View file

@ -0,0 +1,11 @@
# Dev image for the Vite SPA: node:22-alpine with npm pinned to a specific
# version baked in, so it's not re-installed on every container start and
# doesn't drift with whatever npm the base image happens to ship.
#
# NPM_VERSION is the single source of truth in the root .env (passed via compose
# build args). Bump it there, not here.
FROM node:22-alpine
ARG NPM_VERSION
RUN npm install -g "npm@${NPM_VERSION}"
ENV NPM_CONFIG_UPDATE_NOTIFIER=false

View file

@ -40,7 +40,7 @@ export default function LoginPage() {
return (
<AppLayout>
<Panel className="mx-auto max-w-sm space-y-4">
<Panel className="mx-auto max-w-sm space-y-4 mt-32">
<h2 className="text-primary font-bold uppercase tracking-wider">
Log In
</h2>

View file

@ -43,7 +43,7 @@ export default function RegisterPage() {
return (
<AppLayout>
<Panel className="mx-auto max-w-sm space-y-4">
<Panel className="mx-auto max-w-sm space-y-4 mt-32">
<h2 className="text-primary font-bold uppercase tracking-wider">
Register
</h2>