|
@@ -1,10 +1,12 @@
|
|
|
<!-- --------------------------------------------------------------------------- -->
|
|
<!-- --------------------------------------------------------------------------- -->
|
|
|
|
|
|
|
|
-<!-- Folder: Docs -->
|
|
|
|
|
|
|
+<!-- --------------------------------------------------------------------------- -->
|
|
|
|
|
+
|
|
|
|
|
+<!-- Ordner: Docs -->
|
|
|
|
|
|
|
|
-<!-- File: runbook.md -->
|
|
|
|
|
|
|
+<!-- Datei: runbook.md -->
|
|
|
|
|
|
|
|
-<!-- Relative Path: Docs/runbook.md -->
|
|
|
|
|
|
|
+<!-- Relativer Pfad: Docs/runbook.md -->
|
|
|
|
|
|
|
|
<!-- --------------------------------------------------------------------------- -->
|
|
<!-- --------------------------------------------------------------------------- -->
|
|
|
|
|
|
|
@@ -268,6 +270,9 @@ SESSION_COOKIE_SECURE=false
|
|
|
|
|
|
|
|
This is required because most clients will not send `Secure` cookies over HTTP.
|
|
This is required because most clients will not send `Secure` cookies over HTTP.
|
|
|
|
|
|
|
|
|
|
+> If the application is served over **plain HTTP** (no TLS), many clients will not send `Secure` cookies back.
|
|
|
|
|
+> In that case, logins will appear to “work” (Set-Cookie is present), but subsequent requests will still be unauthenticated.
|
|
|
|
|
+
|
|
|
### 3.4 Start the stack on the server
|
|
### 3.4 Start the stack on the server
|
|
|
|
|
|
|
|
Use the base compose file only (no local override):
|
|
Use the base compose file only (no local override):
|
|
@@ -282,6 +287,12 @@ ENV_FILE=.env.server docker compose -f docker-compose.yml up -d --build
|
|
|
> docker compose up -d --build
|
|
> docker compose up -d --build
|
|
|
> ```
|
|
> ```
|
|
|
|
|
|
|
|
|
|
+Optional (recommended): validate env inside the container after updating env files:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+docker compose exec app node scripts/validate-env.mjs
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
### 3.4.1 Optional: Persist ENV_FILE selection via `.env`
|
|
### 3.4.1 Optional: Persist ENV_FILE selection via `.env`
|
|
|
|
|
|
|
|
If you want a simpler startup command (and to avoid forgetting `ENV_FILE=...`), you can create a small `.env` file **on the server only** that defines which env file Compose should use.
|
|
If you want a simpler startup command (and to avoid forgetting `ENV_FILE=...`), you can create a small `.env` file **on the server only** that defines which env file Compose should use.
|
|
@@ -362,14 +373,95 @@ docker compose exec app node scripts/manual-api-client-flow.mjs \
|
|
|
|
|
|
|
|
### 3.7 Logs and troubleshooting
|
|
### 3.7 Logs and troubleshooting
|
|
|
|
|
|
|
|
|
|
+Tail app logs:
|
|
|
|
|
+
|
|
|
```bash
|
|
```bash
|
|
|
docker compose -f docker-compose.yml logs --tail=200 app
|
|
docker compose -f docker-compose.yml logs --tail=200 app
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+Check container status:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+docker compose ps
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+Common healthy state:
|
|
|
|
|
+
|
|
|
|
|
+- `app` is `Up`
|
|
|
|
|
+- `db` is `Up (healthy)`
|
|
|
|
|
+
|
|
|
|
|
+> If you see the Node warning `MODULE_TYPELESS_PACKAGE_JSON`, it is currently expected and does not break runtime.
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 4. HTTPS Note (Future)
|
|
## 4. HTTPS Note (Future)
|
|
|
|
|
|
|
|
-For real users, the application should be served over HTTPS (reverse proxy / TLS termination).
|
|
|
|
|
|
|
+For real users, the application should be served over **HTTPS** (reverse proxy / TLS termination).
|
|
|
|
|
+
|
|
|
|
|
+### 4.1 Why HTTPS matters here
|
|
|
|
|
+
|
|
|
|
|
+- The session cookie (`auth_session`) is typically `Secure` in production.
|
|
|
|
|
+- Browsers and many clients will **not send Secure cookies over HTTP**.
|
|
|
|
|
+- Without HTTPS you may see:
|
|
|
|
|
+
|
|
|
|
|
+ - Login response returns `200` and `Set-Cookie` appears
|
|
|
|
|
+ - But subsequent API calls act unauthenticated (`/api/auth/me` returns `{ user: null }`)
|
|
|
|
|
+
|
|
|
|
|
+### 4.2 Recommended setup
|
|
|
|
|
+
|
|
|
|
|
+Run the Next.js container behind a reverse proxy that terminates TLS.
|
|
|
|
|
+
|
|
|
|
|
+Common internal options:
|
|
|
|
|
+
|
|
|
|
|
+- Nginx
|
|
|
|
|
+- Caddy
|
|
|
|
|
+- Traefik
|
|
|
|
|
+
|
|
|
|
|
+Key requirements:
|
|
|
|
|
+
|
|
|
|
|
+- External URL is HTTPS
|
|
|
|
|
+- Proxy forwards requests to the app container (typically `http://127.0.0.1:3000`)
|
|
|
|
|
|
|
|
-If HTTPS is enabl
|
|
|
|
|
|
|
+### 4.3 Cookie configuration rules
|
|
|
|
|
+
|
|
|
|
|
+- Preferred production behavior:
|
|
|
|
|
+
|
|
|
|
|
+ - `NODE_ENV=production`
|
|
|
|
|
+ - `SESSION_COOKIE_SECURE` unset (or `true`)
|
|
|
|
|
+
|
|
|
|
|
+- Temporary plain HTTP (not recommended):
|
|
|
|
|
+
|
|
|
|
|
+ - set `SESSION_COOKIE_SECURE=false`
|
|
|
|
|
+
|
|
|
|
|
+> Security note: Disabling Secure cookies on real networks is a risk.
|
|
|
|
|
+> Use it only as a temporary workaround while HTTPS is being introduced.
|
|
|
|
|
+
|
|
|
|
|
+### 4.4 Operational tip: host consistency for cookies
|
|
|
|
|
+
|
|
|
|
|
+Cookies are scoped to the **host**.
|
|
|
|
|
+
|
|
|
|
|
+- If you authenticate against `http://localhost:3000`, open links (including PDFs) on `http://localhost:3000`.
|
|
|
|
|
+- If you authenticate against `http://127.0.0.1:3000`, also use that host.
|
|
|
|
|
+
|
|
|
|
|
+Mixing hosts can look like “random 401s” because the browser will not send the cookie to a different host.
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+## 5. Appendix: Quick smoke checklist
|
|
|
|
|
+
|
|
|
|
|
+### 5.1 Local
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build
|
|
|
|
|
+curl -s http://localhost:3000/api/health
|
|
|
|
|
+npx vitest run
|
|
|
|
|
+npm run build
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5.2 Server
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+docker compose up -d --build
|
|
|
|
|
+curl -s http://127.0.0.1:3000/api/health
|
|
|
|
|
+docker compose exec app node scripts/validate-env.mjs
|
|
|
|
|
+```
|