Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
fb47d87
cleanup
makomweb Apr 9, 2026
3d51930
prepare redesign of login
makomweb Apr 9, 2026
87a7961
Unify login: session-based SPA with form authentication
makomweb Apr 9, 2026
b5d2950
cleanup
makomweb Apr 9, 2026
84bfb5e
update NPM package lock
makomweb Apr 9, 2026
2413e98
use npm ci instead
makomweb Apr 9, 2026
3926b38
Fix: Remove unsupported priority key from routes.yaml
makomweb Apr 9, 2026
9415850
Fix: Protect SpaController with firewall and handle unauthenticated R…
makomweb Apr 9, 2026
e269077
Fix: Redirect to backend login URL in development environment
makomweb Apr 9, 2026
51eec55
Implement post-login redirect to original destination (Symfony _targe…
makomweb Apr 9, 2026
4ca1bd0
Fix: Use relative SPA path for post-login redirect instead of absolut…
makomweb Apr 9, 2026
2255651
Fix: Read _target_path from POST request instead of session
makomweb Apr 9, 2026
e6d876f
wip: make redirect succeed
makomweb Apr 9, 2026
83d8575
Fix SpaController redirect and logout flow
makomweb Apr 9, 2026
6160775
Docs: Clarify SPA entry points and update architecture documentation
makomweb Apr 9, 2026
9ad44d1
Docs: Add legacy app to System Architecture diagram
makomweb Apr 9, 2026
86085a6
update README
makomweb Apr 9, 2026
42753ff
version increment
makomweb Apr 9, 2026
c3bca60
Helm: Remove obsolete frontend service deployment
makomweb Apr 9, 2026
fb2e438
K8s: let db-initialization job wait until db-pod is ready to receive …
makomweb Apr 9, 2026
f081e52
Refactor: Clean SPA serving architecture for dev/prod
makomweb Apr 9, 2026
4d813f8
Docs: Update frontend index.html comments to reflect new SPA architec…
makomweb Apr 9, 2026
a4df51d
set Vite port to default
makomweb Apr 9, 2026
c92342a
Fix SPA asset serving
makomweb Apr 9, 2026
d500563
Fix React Router basename for SPA serving
makomweb Apr 9, 2026
90208f8
Fix post-login redirect to point to /spa instead of /game/index
makomweb Apr 9, 2026
fe0cd86
make login + logout + relogin flow work for legacy + modern app
makomweb Apr 9, 2026
af2907e
Enable HMR and fix authentication redirect flow
makomweb Apr 10, 2026
340dc27
Fix QA issues and use dev container for docker-compose
makomweb Apr 10, 2026
fcbe669
cleanup TODOs
makomweb Apr 10, 2026
db202dd
Clean up git repo: remove build artifacts and add comprehensive .giti…
makomweb Apr 10, 2026
309e870
cleanup index.html
makomweb Apr 10, 2026
0438877
remove unnecessary files
makomweb Apr 10, 2026
821b569
Add transparent and repeatable frontend build pipeline
makomweb Apr 10, 2026
4aca7b7
bring back HMR
makomweb Apr 10, 2026
4d43f20
Fix HMR: inject environment variables in Vite dev server
makomweb Apr 10, 2026
a921cdc
Remove obsolete Node Dockerfile and inject.env.cjs
makomweb Apr 10, 2026
cfd775c
Implement multistage PHP Dockerfile with dev/prod image optimization
makomweb Apr 10, 2026
8668b06
Clean up unused build configuration
makomweb Apr 10, 2026
54f02a7
update version
makomweb Apr 10, 2026
31e6525
Simplify SpaController: remove HMR redirect and env var injection
makomweb Apr 10, 2026
4705d8a
Fix asset loading: add nginx location for /assets/ path
makomweb Apr 10, 2026
c33c48a
Simplify asset serving: let Nginx handle all rewrites
makomweb Apr 10, 2026
47c57b0
fix logout button margin (legacy app)
makomweb Apr 10, 2026
66014e2
Restore vite.svg favicon
makomweb Apr 10, 2026
4ae8ee7
Fix vite.svg 500 error: add nginx location for root static files
makomweb Apr 10, 2026
256208b
Serve vite.svg from /dist/ instead of root
makomweb Apr 10, 2026
324ba80
Simplify frontend/index.html comments
makomweb Apr 10, 2026
25096ca
Document frontend build placement strategy
makomweb Apr 10, 2026
7edf1df
Consolidate Helm charts: create unified fullstack deployment
makomweb Apr 10, 2026
451150d
Restructure Helm chart: move to root level with dynamic release naming
makomweb Apr 10, 2026
9951e7d
Update root README for Helm chart consolidation
makomweb Apr 10, 2026
6bff569
Fix worker deployment: correct environment variables and init containers
makomweb Apr 10, 2026
71c9afd
Refactor: consolidate all app configuration in ConfigMap
makomweb Apr 10, 2026
d2b4e0e
Make ConfigMap values fully dynamic from values.yaml
makomweb Apr 10, 2026
81d1fc5
Fix Helm warning: move nodePort to ports array
makomweb Apr 10, 2026
a88281e
Add runtime libraries for PHP extensions in production image
makomweb Apr 10, 2026
f081a19
Update imagePullPolicy to Always for development image updates
makomweb Apr 10, 2026
a460ba1
Fix NGINX probe failures and update imagePullPolicy
makomweb Apr 10, 2026
74e6903
Fix database init job to handle empty migrations gracefully
makomweb Apr 10, 2026
872ed79
Integrate NGINX as sidecar in app pod
makomweb Apr 10, 2026
ee0a436
Add init container to copy app files to shared volume
makomweb Apr 10, 2026
13b9260
Fix init container file copy to include dotfiles
makomweb Apr 10, 2026
5e38018
Add database and schema creation to init job
makomweb Apr 10, 2026
b979b99
Update NGINX to use localhost for FastCGI in Kubernetes
makomweb Apr 10, 2026
821a886
Remove unused svc-app service
makomweb Apr 10, 2026
eab68cc
Consolidate service naming: web -> app
makomweb Apr 10, 2026
64c4522
Inject OTEL collector address into React app during build
makomweb Apr 10, 2026
01a736b
fix NGINX config
makomweb Apr 14, 2026
fa84723
load fixtures during DB init
makomweb Apr 14, 2026
42c7ab9
troubleshoot helm chart
makomweb Apr 14, 2026
813f335
refactor: use minimal resource names in Helm chart
makomweb Apr 14, 2026
98a4379
refactor: remove NodePort from services, use ClusterIP instead
makomweb Apr 14, 2026
b2523e4
refactor: rename Helm template helpers from 'fullstack.' to 'chart.'
makomweb Apr 14, 2026
4435534
improve Helm chart
makomweb Apr 15, 2026
bac0ab9
update documentation
makomweb Apr 15, 2026
00df748
fix phpstan + php-cs-fixer
makomweb Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
NGINX_IMAGE=nginx:stable-alpine3.23

# Backend
APP_IMAGE=fullstack-symfony-react-dev:0.9.1
APP_IMAGE=fullstack-symfony-react-dev:0.9.3
APP_NAME=fullstack-symfony-react
APP_VERSION=0.9.1
APP_VERSION=0.9.3
APP_ENV=dev
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=secret
Expand Down
29 changes: 28 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
# Build artifacts
project/.deptrac.cache
project/diagram.*
project/circle.svg
tempo-data/
tempo-data/

# Frontend build output
frontend/dist/
frontend/node_modules/
frontend/.env.local
frontend/.env.*.local

# Backend build output
backend/public/dist/
backend/vendor/
backend/var/
backend/.env.local
backend/.env.*.local

# IDE and OS files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db

# Environment
.env.local
.env.*.local
1 change: 1 addition & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- ✅ [Loki](https://grafana.com/oss/loki/) for logging
- ✅ [Tempo](https://grafana.com/oss/tempo/) for tracing
- ✅ [Prometheus](https://prometheus.io/) for metrics
- ✅ use LGTM all in one solution from Grafana
- ✅ [CI via Github actions](https://docs.github.com/en/actions/about-github-actions/about-continuous-integration-with-github-actions)
- ✅ PhpUnit 13
- ✅ Vitest
Expand Down
30 changes: 18 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
APP_NAME = fullstack-symfony-react
VERSION = 0.9.1
VERSION = 0.9.3

.DEFAULT_GOAL := help

.PHONY: build dev prod backend-image frontend-image grafana up down reset \
.PHONY: build dev prod backend-image grafana up down reset \
reset-worker reset-app init composer-install create-database create-schema \
load-fixtures init-test create-test-database create-test-schema composer shell \
qa sa cs test backend-test frontend-test arch clear cache-clear cache-pool-clear \
maintenance maintain show-composer-updates \
maintenance maintain show-composer-updates frontend-build \
update-composer-dependencies update-npm-dependencies coverage frontend-shell open help

## Start development environment (build images, start containers, init, open browser)
Expand All @@ -20,18 +20,14 @@ dev:
docker build . -f ./build/php/Dockerfile --target dev -t ${APP_NAME}-dev:${VERSION}

## Build production images (without Docker cache)
prod: backend-image frontend-image
prod: backend-image


## Build backend image (without Docker cache)
backend-image:
@echo "Build backend image"
docker build . -f ./build/php/Dockerfile --target prod --no-cache -t ${APP_NAME}:${VERSION}

## Build frontend image (without Docker cache)
frontend-image:
@echo "Build frontend image"
docker build . -f ./build/node/Dockerfile --target prod --no-cache -t ${APP_NAME}-web:${VERSION}

grafana:
@echo "Build grafana image"
docker build . -f ./build/grafana/Dockerfile -t ${APP_NAME}-grafana:${VERSION}
Expand All @@ -44,8 +40,8 @@ up:
down:
docker compose down

## Reset all services
reset: reset-worker reset-app
## Reset worker, app, frontend
reset: reset-worker reset-app reset-frontend

## Reset worker
reset-worker:
Expand All @@ -57,14 +53,24 @@ reset-app:
@echo "Reset app"
docker compose restart app

## Reset frontend (Vite development server)
reset-frontend:
@echo "Reset frontend"
docker compose restart frontend

## Initialize project (install dependencies, create database, schema, load fixtures)
init: composer-install create-database create-schema load-fixtures
init: composer-install frontend-build create-database create-schema load-fixtures

## Install composer dependencies
composer-install:
@echo "Install composer dependencies"
docker compose exec -it app composer install

## Build frontend assets (Vite production build)
frontend-build:
@echo "Build frontend assets to backend/public/dist"
docker compose run --rm frontend-build

## Create database
create-database:
@echo "Create database"
Expand Down
166 changes: 73 additions & 93 deletions README.md

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion backend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,7 @@ LOCK_DSN=flock
###< symfony/lock ###

ADMIN_EMAIL='admin@example.com'
ADMIN_PASSWORD='secret'
ADMIN_PASSWORD='secret'
# SPA Frontend Configuration
SPA_BACKEND_API_URL="http://localhost:8080/api"
SPA_OTEL_COLLECTOR_ADDRESS="http://localhost:4318"
2 changes: 1 addition & 1 deletion backend/config/packages/nelmio_api_doc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ nelmio_api_doc:
info:
title: Fullstack Symfony React
description: Fullstack demo application
version: 0.9.1
version: 0.9.3
areas:
default:
path_patterns: [^/api/games]
19 changes: 10 additions & 9 deletions backend/config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@ security:
main:
lazy: true
provider: app_user_provider
json_login:
login_path: api.login
check_path: api.login
username_path: email
password_path: password
entry_point: App\Security\CustomAuthenticationEntryPoint
form_login:
login_path: app.login
check_path: app.login
enable_csrf: true
success_handler: App\Security\AuthenticationSuccessHandler
# Symfony's built-in target path parameter for post-login redirects
# When login form includes _target_path, user is redirected there after successful auth
target_path_parameter: _target_path
# Default fallback if no _target_path is provided
# Users are now redirected to the modern React SPA by default
default_target_path: /spa
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
Expand All @@ -33,8 +36,7 @@ security:
name: REMEMBERME
logout:
path: app.logout
# where to redirect after logout
# target: app_any_route
target: app.login

# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
Expand All @@ -46,8 +48,7 @@ security:
# Note: Only the *first* access control that matches will be used
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
- { path: ^/login, roles: PUBLIC_ACCESS }
- { path: ^/spa, roles: ROLE_USER }
- { path: ^/game, roles: ROLE_USER }
- { path: ^/api/me, roles: PUBLIC_ACCESS }
- { path: ^/api, roles: ROLE_USER }
Expand Down
3 changes: 2 additions & 1 deletion backend/config/routes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ controllers:
namespace: App\Controller
type: attribute

# Root redirect to default route (for unauthenticated users)
# Attribute-based routes (controllers) have priority and will be checked first
root_shortcut:
path: /
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
defaults:
route: 'app.index_games'
ignoreAttributes: true
7 changes: 7 additions & 0 deletions backend/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ parameters:
app.telemetry: '%env(APP_TELEMETRY)%'
admin.email: '%env(ADMIN_EMAIL)%'
admin.password: '%env(ADMIN_PASSWORD)%'
spa.backend_api_url: '%env(string:SPA_BACKEND_API_URL)%'
spa.otel_collector_address: '%env(string:SPA_OTEL_COLLECTOR_ADDRESS)%'

services:
# default configuration for services in *this* file
Expand Down Expand Up @@ -50,3 +52,8 @@ services:
- '%kernel.project_dir%'
tags:
- { name: data_collector, template: 'profiler/architecture.html.twig', id: 'app.architecture_collector' }

App\Controller\SpaController:
arguments:
$backendApiUrl: '%spa.backend_api_url%'
$otelCollectorAddress: '%spa.otel_collector_address%'
2 changes: 1 addition & 1 deletion backend/public/css/styles.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* assets/css/styles.css */
/* public/css/styles.css */
.logout-button {
margin-right: 8px;
}
Expand Down
88 changes: 0 additions & 88 deletions backend/public/images/flower.svg

This file was deleted.

Loading
Loading