Installation

Quick Start

git clone https://github.com/Wachhund/S3-image-gallery.git
cd S3-image-gallery

cp .env.example .env
# Optional: .env anpassen (Ports, Credentials, OTP)

docker compose up --build -d

Load Test Data

# Bucket scannen und Bilder katalogisieren
docker compose exec php php bin/scan.php

# Thumbnails erzeugen
docker compose exec php php bin/thumbs.php

Set Up Passkey

  1. Set a one-time password at.env

:S3G_REGISTRATION_OTP=mein-geheimes-passwort

  1. Recreate the container:docker compose up -d --force-recreate php

  2. Create the passkey using the OTP at/register

  3. Log in with the passkey at/login

Docker Services

Service Base Port Description
nginx Alpine 8080 Reverse proxy, security headers, Gzip
php PHP 8.4 FPM Application (GD, EXIF, PDO)
db MariaDB 11 3306 Database (persistent volume)
storage RustFS 9001 (Console) S3-compatible object storage
storage-init AWS CLI Bucket creation (one-time)
battle-php PHP 8.4 FPM FotoBattle application
battle-nginx Alpine 8081 FotoBattle frontend

Enable FotoBattle

FotoBattle must be located as a sibling directory next to the Gallery:

├── S3-image-gallery/
└── photo_battles/
# FotoBattle-Container starten
docker compose up -d --build battle-php battle-nginx

First admin account:

  1. Register athttp://localhost:8081/register

  2. In the database:UPDATE users SET role='admin' WHERE email='...'

Environment Variables

Gallery

Variable Default Description
PHP_VERSION

| 8.5 | Docker image tag | |DB_HOST

| db | MariaDB hostname | |DB_NAME

| s3gallery | Database name | |DB_USER

| s3gallery | DB user | |DB_PASSWORD

| changeme | DB password | |S3_ENDPOINT

| http://storage:9000 | RustFS API endpoint | |S3_ACCESS_KEY

| rustfsadmin | RustFS credentials | |S3_SECRET_KEY

| rustfsadmin | RustFS credentials | |S3_BUCKET

| gallery | S3 bucket name | |NGINX_PORT

| 8080 | Host port for Gallery | |RUSTFS_CONSOLE_PORT

| 9001 | Host port for RustFS console | |APP_DEBUG

| false | Show error details | |APP_SECURE_COOKIES

| true | HTTPS-only session cookies | |S3G_REGISTRATION_OTP

| (empty) | One-time password for Passkey registration | |S3G_RP_ID

| localhost | WebAuthn Relying Party ID |

FotoBattle

Variable Default Description
BATTLE_PORT

| 8081 | Host port for FotoBattle | |BATTLE_URL

| http://localhost:8081 | FotoBattle base URL | |BATTLE_SUBMIT_SECRET

| changeme | Shared HMAC secret (min. 32 characters) |

DB and S3 variables are shared by the Gallery.

Quality Gates

# Tests
docker compose exec php composer test

# Statische Analyse (PHPStan Level 6)
docker compose exec php composer analyse

# Code Style
docker compose exec php composer cs-check

Constraints

  • Demo Project — Not intended for production
  • Single Node — Docker Compose, no Kubernetes
  • No CDN — Images served directly from RustFS via PHP proxy
  • No WebSocket — No live battle feed
  • Synchronous Projections — No message broker in the MVP