# 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 1) Start the stack ```bash docker compose up -d --build ``` 2) Create the database schema ```bash 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 ``` 3) Promote an admin (to access Site Settings) ```bash docker compose exec php php bin/console app:promote-admin you@example.com ``` 4) Configure Spotify API credentials (admin only) - Open `http://localhost:8000/admin/settings` and enter your Spotify Client ID/Secret. - Alternatively, set env vars for the PHP container: `SPOTIFY_CLIENT_ID`, `SPOTIFY_CLIENT_SECRET`. 5) Visit `http://localhost:8000` to search for albums. 6) (Optional) Seed demo data ```bash 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. 1. Build the image (uses `docker/php/Dockerfile`'s `prod` stage): ```bash docker build \ --target=prod \ -t tonehaus-app:latest \ -f docker/php/Dockerfile \ . ``` 2. Run the container (listens on port 8080 inside the container): ```bash 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=sqlite` and stores the database file inside the image at `var/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_DRIVER` and `DATABASE_URL` at `docker run` time and optionally disable auto-migration with `RUN_MIGRATIONS_ON_START=0`. - Health endpoint: `GET /healthz` on the published port (example: `curl http://localhost:8080/healthz`). 3. Rebuild/redeploy by re-running the `docker build` command; no manual steps or bind mounts are involved. ## Continuous integration - `.github/workflows/ci.yml` runs on pushes and pull requests targeting `main` or `prod`. - 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/Dockerfile` prod stage), checks that key Symfony artifacts (e.g., `public/index.php`, `bin/console`) are present, ensures `APP_ENV=prod` is baked in, and smoke-tests the `/entrypoint.sh` startup 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 in `docker-compose.yml`. - Set `DATABASE_DRIVER=sqlite` to run against a self-contained SQLite file stored at `var/data/database.sqlite`. - When `DATABASE_DRIVER=sqlite`, the `DATABASE_URL` env var is ignored. Doctrine will automatically create and use the SQLite file; override the default location with `DATABASE_SQLITE_PATH` if 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