Skip to content

haydenk/symfony-poly-stack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Symfony Poly Stack

A full-featured Symfony 8 example application demonstrating web authentication, a REST API, an admin panel, database fixtures, and a scheduler — all running inside a devcontainer with swappable database backends (PostgreSQL, MySQL, SQLite).

Requirements

Getting Started

Open the project in its devcontainer, then run:

mise run setup

This single command:

  1. Installs Composer dependencies (vendor/)
  2. Installs Bun (Node) dependencies (node_modules/)
  3. Generates Symfony secrets keys for the dev environment
  4. Creates the database and runs all migrations

To set up for production secrets instead:

mise run setup prod

Start the development server

mise run dev

This starts three processes via the Procfile:

Process Command Purpose
fpm php-fpm PHP FastCGI process manager
web caddy Reverse proxy + static file server on http://localhost:8000
scheduler messenger:consume scheduler_default Symfony Scheduler worker

Application Features

Route Description
/ Public home page
/register Create a new account
/login Sign in with email + password
/verify/pending Email verification reminder (shown after login if unverified)
/dashboard Authenticated user dashboard (requires verified email)
/profile View your profile
/profile/edit Edit name and email
/reset-password Forgot password flow
/logout Sign out

Email verification is required to access protected routes. After registration an email is sent with:

  • A Verify Email Address link (expires in 1 hour)
  • A cancel this registration link — clicking it immediately deletes the account (no login required)

Password reset is handled by symfonycasts/reset-password-bundle with a signed, expiring link sent to the registered email.

The API uses JWT authentication via lexik/jwt-authentication-bundle.

Obtain a token

curl -X POST http://localhost:8000/api/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"admin@example.com","password":"password"}'
{ "token": "<jwt>" }

Authenticated requests

curl http://localhost:8000/api/me \
  -H 'Authorization: Bearer <jwt>'
{
  "id": 1,
  "name": "Admin User",
  "email": "admin@example.com",
  "roles": ["ROLE_ADMIN", "ROLE_USER"],
  "emailVerified": true,
  "createdAt": "2026-01-01T00:00:00+00:00"
}

The interactive API documentation (via API Platform) is available at http://localhost:8000/api.

Requires ROLE_ADMIN. Log in with the seeded admin account:

Field Value
Email admin@example.com
Password password

The admin panel (EasyAdmin 5) provides a full CRUD interface for managing users.

Database

Default connection

PostgreSQL is the default. The connection string is set in .env:

DATABASE_URL="postgresql://symfony:secret@localhost:5432/symfony?serverVersion=17&charset=utf8"

Override locally by creating .env.local (gitignored):

DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_dev.db"

Switch database backends

mise run db:use postgres   # PostgreSQL (default)
mise run db:use mysql      # MySQL / MariaDB
mise run db:use sqlite     # SQLite (no server required)

This rewrites DATABASE_URL in .env.local, adjusts Doctrine's identity_generation_preferences, wipes existing migrations, regenerates them for the new platform, and runs them.

Pass --no-migrate to switch the URL only without touching migrations:

mise run db:use sqlite --no-migrate

Mise Tasks

All tasks are in .mise/tasks/. Run any task with mise run <task>.

Task Description
setup [env] Install dependencies + generate secrets + create DB + migrate
dev Start the development server (FPM + Caddy + Scheduler)
build Build frontend assets for production
clean Remove vendor/, node_modules/, compiled assets, and cache
console [cmd] Run a Symfony console command (mise run console cache:clear)
logs Tail the Symfony application log
test Run the PHPUnit test suite
cache:clear Clear and warm up all application caches
db:migrate Run pending database migrations
db:fresh Drop schema, re-run all migrations, reload fixtures (destructive)
db:seed Load database fixtures
db:use <driver> Switch database backend (postgres, mysql, sqlite)
messenger:consume Start a Messenger queue worker
install:compose Install Composer dependencies only
install:bun Install Bun dependencies only

Fixtures

Seed the database with demo data:

mise run db:seed

This loads:

Account Email Password Role
Admin admin@example.com password ROLE_ADMIN
Users (×10) user.{n}@example.com password ROLE_USER

To wipe the database and start fresh with fixtures:

mise run db:fresh

Testing

mise run test

Tests use a separate symfony_test database. The suite covers:

  • Unit tests — User entity logic
  • Functional tests — registration, login, dashboard access, JWT authentication

Tech Stack

Layer Package
Framework Symfony 8 / PHP 8.4
ORM Doctrine ORM + Migrations
Web auth Symfony Security (form_login) + symfonycasts/verify-email-bundle + symfonycasts/reset-password-bundle
API auth lexik/jwt-authentication-bundle
API docs API Platform
Admin EasyAdmin 5
Scheduler Symfony Scheduler (Messenger transport)
Mail Symfony Mailer (SMTP → localhost:1025)
Frontend Webpack Encore + Bootstrap 5 + Bootstrap Icons
Web server Caddy 2 + PHP-FPM (Unix socket)
Task runner mise

Project Structure

src/ExampleApp/
├── Controller/
│   ├── Admin/          # EasyAdmin dashboard + CRUD
│   ├── Api/            # JWT-protected API endpoints
│   ├── Auth/           # Login, registration, verify email, reset password
│   ├── DashboardController.php
│   ├── HomeController.php
│   └── ProfileController.php
├── DataFixtures/       # Demo data
├── Entity/             # Doctrine entities (User, ResetPasswordRequest)
├── EventSubscriber/    # Email verification gate
├── Form/               # Symfony Form types
└── Repository/         # Doctrine repositories
templates/
├── admin/
├── auth/               # Login, register, verify pending, reset password
├── dashboard/
├── emails/             # Transactional email templates
├── home/
└── profile/

About

Full-featured Symfony 8 starter with web auth, JWT API, EasyAdmin, Scheduler, and swappable DB backends — runs in a devcontainer

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages