5.3 KiB
5.3 KiB
Tonehaus — Music Ratings
Discover albums from Spotify, read and write reviews, and manage your account. Built with Symfony 7, Twig, Doctrine, and Bootstrap.
Quick start
- Start the stack
docker compose up -d --build
- Create the database schema
docker compose exec php php bin/console doctrine:database:create --if-not-exists
docker compose exec php php bin/console doctrine:migrations:diff --no-interaction
docker compose exec php php bin/console doctrine:migrations:migrate --no-interaction
- Promote an admin (to access Site Settings)
docker compose exec php php bin/console app:promote-admin you@example.com
- Configure Spotify API credentials (admin only)
- Open
http://localhost:8000/admin/settingsand enter your Spotify Client ID/Secret. - Alternatively, set env vars for the PHP container:
SPOTIFY_CLIENT_ID,SPOTIFY_CLIENT_SECRET.
-
Visit
http://localhost:8000to search for albums. -
(Optional) Seed demo data
docker compose exec php php bin/console app:seed-demo-users --count=50
docker compose exec php php bin/console app:seed-demo-albums --count=40 --attach-users
docker compose exec php php bin/console app:seed-demo-reviews --cover-percent=70 --max-per-album=8
Production container (immutable)
The repository ships with a single-container production target that bundles PHP-FPM, Nginx, your code, and a self-contained SQLite database. The build bakes in the APP_ENV=prod flag so production-only Symfony config is used automatically, and no bind mounts are required at runtime.
- Build the image (uses
docker/php/Dockerfile'sprodstage):
docker build \
--target=prod \
-t tonehaus-app:latest \
-f docker/php/Dockerfile \
.
- Run the container (listens on port 8080 inside the container):
docker run -d \
--name tonehaus \
-p 8080:8080 \
-e APP_ENV=prod \
-e APP_SECRET=change_me \
-e SPOTIFY_CLIENT_ID=your_client_id \
-e SPOTIFY_CLIENT_SECRET=your_client_secret \
tonehaus-app:latest
- The runtime defaults to
DATABASE_DRIVER=sqliteand stores the database file inside the image atvar/data/database.sqlite. On each boot the entrypoint runs Doctrine migrations (safe to re-run) so the schema stays current while the container filesystem remains immutable from the host's perspective. - To point at Postgres (or any external database), override
DATABASE_DRIVERandDATABASE_URLatdocker runtime and optionally disable auto-migration withRUN_MIGRATIONS_ON_START=0. - Health endpoint:
GET /healthzon the published port (example:curl http://localhost:8080/healthz). - The entrypoint now also performs Symfony cache clear/warmup on startup, which requires
APP_SECRETto be set; the container exits with an error if it is missing so misconfigured deployments are caught immediately.
- Rebuild/redeploy by re-running the
docker buildcommand; no manual steps or bind mounts are involved.
Continuous integration
.github/workflows/ci.ymlruns on pushes and pull requests targetingmainorprod.- Job 1 installs Composer deps, prepares a SQLite database, runs Doctrine migrations, and executes the PHPUnit suite under PHP 8.2 so functional regressions are caught early.
- Job 2 builds the production Docker image (
docker/php/Dockerfileprod stage), checks that key Symfony artifacts (e.g.,public/index.php,bin/console) are present, ensuresAPP_ENV=prodis baked in, and smoke-tests the/entrypoint.shstartup path. - The resulting artifact mirrors the immutable container described above, so a green CI run guarantees the repo can be deployed anywhere via
docker run. - Self-hosted runners can use
.gitea/workflows/ci.yml, which mirrors the GitHub workflow but also supports optional registry pushes after the image passes the same verification steps.
Database driver
- Set
DATABASE_DRIVER=postgres(default) to keep using the Postgres 16 container defined indocker-compose.yml. - Set
DATABASE_DRIVER=sqliteto run against a self-contained SQLite file stored atvar/data/database.sqlite. - When
DATABASE_DRIVER=sqlite, theDATABASE_URLenv var is ignored. Doctrine will automatically create and use the SQLite file; override the default location withDATABASE_SQLITE_PATHif needed.
Features
- Spotify search with Advanced filters (album, artist, year range) and per-album aggregates (avg/count)
- Album page with details, reviews list, and inline new review (logged in)
- Auth modal (Login/Sign up) with remember-me cookie, no separate pages
- Role-based access: authors manage their own reviews, admins can manage any
- Admin Site Settings to manage Spotify credentials in DB
- User Dashboard to update profile and change password (requires current password)
- Light/Dark theme toggle in Settings (cookie-backed)
- Bootstrap UI
Rate limiting & caching
- Server-side Client Credentials; access tokens are cached.
Docs
See /docs for how-tos and deeper notes:
- Setup and configuration:
docs/01-setup.md - Features and UX:
docs/02-features.md - Authentication and users:
docs/03-auth-and-users.md - Spotify integration:
docs/04-spotify-integration.md - Reviews and albums:
docs/05-reviews-and-albums.md - Admin & site settings:
docs/06-admin-and-settings.md - Troubleshooting:
docs/07-troubleshooting.md
License
MIT