diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..7a94c0e --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,91 @@ +# Deployment (Dokploy) + +Guide for deploying Space Booking to production via Dokploy. The app ships as a +Docker Compose stack (`docker-compose.yml`): a `backend` (FastAPI/SQLite) and a +`frontend` (Vue, served behind Traefik). + +## Security model (read first) + +- **No demo accounts in production.** The demo seed (`backend/seed_db.py`) only + runs when `RUN_SEED=1` is set — never set it in production. +- **First user becomes admin.** The first account to register on a fresh + database is automatically made `superadmin` and is activated immediately (no + email verification needed). **Register your own account first, right after the + first deploy.** +- **SECRET_KEY is enforced.** With `DEBUG=false` (the production default) the + backend refuses to start unless `SECRET_KEY` is a strong, random value + (≥ 32 chars, not a known placeholder). Tokens are forgeable with a weak key. +- **CORS** is restricted to `FRONTEND_URL` in production; `localhost` is allowed + only in dev (`DEBUG=true`). + +## Required environment variables (Dokploy → service → Environment) + +``` +SECRET_KEY= +FRONTEND_URL=https://space.roa.romfast.ro +DOMAIN=space.roa.romfast.ro +``` + +Do **not** set `DEBUG` (defaults to `false` = production) and do **not** set +`RUN_SEED`. + +Optional (email/SMTP — needed so non-admin users can verify their accounts): + +``` +SMTP_ENABLED=true +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_USER=user@example.com +SMTP_PASSWORD=... +SMTP_FROM_ADDRESS=rezervari@romfast.ro +``` + +> Without SMTP, only the first user (the admin, auto-activated) can log in; +> other registrations stay inactive until email verification. + +## First deploy + +1. Push the latest code to the git remote that Dokploy tracks (`master`). +2. In Dokploy, set the environment variables above. +3. **Deploy / Redeploy.** Tables are created automatically on boot. +4. Open the site → **Register** with your own email → you become `superadmin`. + +## Resetting the database (start clean) + +The production DB lives in the Docker volume `backend_data`, mounted at +`/data/space_booking.db`. + +> ⚠️ Deleting the DB file while the container is running has no immediate +> effect — the app holds the file open and keeps using it. You **must restart** +> the container afterwards so it creates a fresh, empty database. + +```bash +# 1. Find the backend container +docker ps | grep backend +# e.g. constanta-space-booking-mnsx1b-backend-1 + +# 2. Delete the database file +docker exec -it rm -f /data/space_booking.db + +# 3. Restart so the app recreates an empty DB +docker restart + +# 4. Verify it is empty (should print: users: []) +docker exec -it \ + python3 -c "import sqlite3; c=sqlite3.connect('/data/space_booking.db'); print('users:', list(c.execute('select id,email,role,is_active from users')))" +``` + +Then go to the site and register your admin account again. + +## Inspecting users in production + +```bash +docker exec -it \ + python3 -c "import sqlite3; c=sqlite3.connect('/data/space_booking.db'); [print(r) for r in c.execute('select id,email,role,is_active from users')]" +``` + +## Local development + +For local dev with demo data, set `DEBUG=true` and `RUN_SEED=1`. The seed reads +account passwords from `ADMIN_PASSWORD` / `MANAGER_PASSWORD` / `USER_PASSWORD` +(weak defaults if unset). See `backend/.env.example`. diff --git a/README.md b/README.md index 6b8dc92..f8d5c48 100644 --- a/README.md +++ b/README.md @@ -64,9 +64,12 @@ npm run dev Frontend will be available at: http://localhost:5173 -## Demo Accounts +## Demo Accounts (local dev only) -After seeding the database (runs automatically on container start): +Demo accounts are **not** created in production. They are seeded only for local +development, and only when `RUN_SEED=1` is set (see `backend/.env.example`). +In production, the first user to register becomes the `superadmin` — see +[DEPLOYMENT.md](DEPLOYMENT.md). | Email | Password | Role | |-------|----------|------| @@ -74,6 +77,9 @@ After seeding the database (runs automatically on container start): | manager@example.com | managerpassword | Manager | | user@example.com | userpassword | User | +> Passwords are overridable via `ADMIN_PASSWORD` / `MANAGER_PASSWORD` / +> `USER_PASSWORD`. Defaults are weak and for local use only. + ## Docker Compose (local) ```bash @@ -90,29 +96,20 @@ Backend API: http://localhost:8000/docs ## Deploy (Dokploy) -``` -Dokploy UI → New Service → Docker Compose → Git: space-booking repo -``` +See **[DEPLOYMENT.md](DEPLOYMENT.md)** for the full production guide (security +model, environment variables, first-deploy steps, and how to reset the +database). -### Environment Variables (Dokploy → Environment tab) +Quick version: -| Variable | Required | Example | -|----------|----------|---------| -| `SECRET_KEY` | **Yes** | `python -c "import secrets; print(secrets.token_hex(32))"` | -| `FRONTEND_URL` | **Yes** | `https://space.roa.romfast.ro` | -| `SMTP_ENABLED` | No | `true` | -| `SMTP_HOST` | No* | `smtp.example.com` | -| `SMTP_PORT` | No* | `587` | -| `SMTP_USER` | No* | `user@example.com` | -| `SMTP_PASSWORD` | No* | `secret` | -| `SMTP_FROM_ADDRESS` | No* | `rezervari@romfast.ro` | +1. `Dokploy UI → New Service → Docker Compose → Git: space-booking repo` +2. Set environment variables (`SECRET_KEY`, `FRONTEND_URL`, `DOMAIN`). +3. Deploy. Tables are auto-created on boot; **no demo data** is seeded. +4. Open the site → **Register your own account first** → you become + `superadmin`. -*Required only if `SMTP_ENABLED=true` - -### Auto-seed - -`entrypoint.sh` runs `seed_db.py` automatically on every container start. -The script is idempotent — skips if data already exists. +> The backend refuses to start in production unless `SECRET_KEY` is a strong, +> random value. Do not set `RUN_SEED` in production. ## Development Commands