- Served the guest PWA at /g/{token} and introduced a mobile-friendly gallery page with lazy-loaded thumbnails, themed colors, lightbox, and download links plus new gallery data client (resources/js/guest/pages/PublicGalleryPage.tsx:1, resources/js/guest/services/galleryApi.ts:1, resources/js/guest/router.tsx:1). Added i18n strings for the public gallery experience (resources/js/guest/i18n/messages.ts:1).
- Ensured checkout step changes snap back to the progress bar on mobile via smooth scroll anchoring (resources/ js/pages/marketing/checkout/CheckoutWizard.tsx:1).
- Enabled tenant admins to export all approved event photos through a new download action that streams a ZIP archive, with translations and routing in place (app/Http/Controllers/Tenant/EventPhotoArchiveController.php:1, app/Filament/Resources/EventResource.php:1, routes/web.php:1, resources/lang/de/admin.php:1, resources/lang/en/admin.php:1).
4.2 KiB
Docker Deployment Guide
This guide describes the recommended, repeatable way to run the Fotospiel platform in Docker for production or high-fidelity staging environments. It pairs a multi-stage build (PHP-FPM + asset pipeline) with a Compose stack that includes Nginx, worker processes, Redis, and MySQL.
1. Prerequisites
- Docker Engine 24+ and Docker Compose v2.
- A
.envfile for the application (see step 4). - Optional: an external MySQL/Redis if you do not want to run the bundled containers.
2. Build the application image
docker compose build app
The build performs the following steps:
- Installs Node dependencies and runs
npm run buildto produce production assets. - Installs PHP dependencies with Composer (
--no-dev --no-scripts). - Creates a PHP 8.3 FPM image with required extensions (GD, intl, Redis, etc.).
- Stores the compiled application under
/opt/app; the runtime entrypoint syncs it into the shared volume when a container starts.
3. Configure environment
Copy the sample Docker environment file and edit the secrets:
cp docker/.env.docker docker/.env.docker.local
Set (at minimum):
APP_KEY— generate withdocker compose run --rm app php artisan key:generate --show.- Database credentials (
DB_*). The provided MySQL service defaults tofotospiel/secret. STORAGE_ALERT_EMAIL— recipient for upload failure alerts (optional).
Point docker-compose.yml to the file you created by either renaming it to docker/.env.docker or adjusting the env_file entries.
4. Boot the stack
docker compose up -d
Services started:
app: PHP-FPM container serving the Laravel application.web: Nginx proxy forwarding requests to PHP-FPM on port8080by default (APP_HTTP_PORT).queue&media-storage-worker: queue consumers (default + media archival).scheduler: runsphp artisan schedule:work.horizon(optional, disabled unless--profile horizonis supplied).redis&mysql.
Migrations & seeds
Run once after the first boot or when deploying new schema changes:
docker compose exec app php artisan migrate --force
docker compose exec app php artisan db:seed --class=MediaStorageTargetSeeder --force
If you already have data, skip the seeder or seed only new records.
5. Queue & Horizon management
Worker entrypoints live in docs/queue-supervisor/. The Compose services mount the same application volume so code stays in sync. Adjust concurrency by scaling services:
docker compose up -d --scale queue=2 --scale media-storage-worker=2
To enable Horizon (dashboard, smart balancing):
docker compose --profile horizon up -d horizon
The dashboard becomes available at /horizon and is protected by the Filament super-admin auth guard.
6. Persistent data & volumes
app-code— contains the synced application, including thestoragedirectory and generated assets.mysql-data— MySQL data files.redis-data— Redis persistence (disabled by default; change the Redis command if you want AOF snapshots).
Back up the volumes before upgrades to maintain tenant media and database state.
7. Updating the stack
git pullthe repository (or deploy your release branch).docker compose build app.docker compose up -d.- Run migrations + seeders if required.
- Check logs:
docker compose logs -f app queue media-storage-worker.
Because the app image keeps the authoritative copy of the code, each container restart rsyncs fresh sources into the shared volume ensuring reliable updates without lingering artefacts.
8. Production hardening
- Terminate TLS with a dedicated reverse proxy (Traefik, Caddy, AWS ALB, etc.) in front of the
webcontainer. - Point
APP_URLto your public domain and enable trusted proxies. - Externalize MySQL/Redis to managed services for better resilience.
- Configure backups for the
storagedirectories and database dumps. - Hook into your observability stack (e.g., ship container logs to Loki or ELK).
With the provided configuration you can bootstrap a consistent Docker-based deployment across environments while keeping queue workers, migrations, and asset builds manageable. Adjust service definitions as needed for staging vs. production.