docs improvements
This commit is contained in:
+2
-1
@@ -82,7 +82,8 @@ OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=http://localhost:9000/media
|
|||||||
GOOGLE_CLIENT_ID=
|
GOOGLE_CLIENT_ID=
|
||||||
GOOGLE_CLIENT_SECRET=
|
GOOGLE_CLIENT_SECRET=
|
||||||
|
|
||||||
# Cookie domain for cross-subdomain auth (e.g. .yourdomain.com)
|
# Cookie domain for auth. Optional for Docker (falls back to DASHBOARD_ORIGIN).
|
||||||
|
# For Railway: set to your dashboard domain (e.g. app.yourdomain.com) when API and dashboard use different subdomains.
|
||||||
AUTH_COOKIE_DOMAIN=
|
AUTH_COOKIE_DOMAIN=
|
||||||
|
|
||||||
# Dashboard domain routing
|
# Dashboard domain routing
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ Use `./run-docker-full-stack.sh --no-minio` to exclude MinIO if you do not need
|
|||||||
| Variable | Description |
|
| Variable | Description |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth |
|
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google OAuth |
|
||||||
| `AUTH_COOKIE_DOMAIN` | Cross-subdomain cookies (e.g. `.yourdomain.com`) |
|
| `AUTH_COOKIE_DOMAIN` | Railway: dashboard domain when API/dashboard use different subdomains. Docker: optional (falls back to `DASHBOARD_ORIGIN`) |
|
||||||
| `PRIVATE_APP_HOST`, `PRIVATE_APP_SUBDOMAINS` | Multi-subdomain routing |
|
| `PRIVATE_APP_HOST`, `PRIVATE_APP_SUBDOMAINS` | Multi-subdomain routing |
|
||||||
| `UNSPLASH_API_KEY` | Unsplash image search |
|
| `UNSPLASH_API_KEY` | Unsplash image search |
|
||||||
| `LICENSE_KEY` | Enterprise features (SSO, token-auth, no-tracking) |
|
| `LICENSE_KEY` | Enterprise features (SSO, token-auth, no-tracking) |
|
||||||
@@ -188,10 +188,12 @@ PUBLIC_SERVER_URL="https://api.yourdomain.com"
|
|||||||
TRUSTED_ORIGINS="https://api.yourdomain.com,https://app.yourdomain.com"
|
TRUSTED_ORIGINS="https://api.yourdomain.com,https://app.yourdomain.com"
|
||||||
BETTER_AUTH_SECRET="random-secure-key"
|
BETTER_AUTH_SECRET="random-secure-key"
|
||||||
AUTH_BEARER_TOKEN="some-key"
|
AUTH_BEARER_TOKEN="some-key"
|
||||||
AUTH_COOKIE_DOMAIN="yourdomain.com"
|
|
||||||
PRIVATE_SERVER_KEY="same-key-for-api-and-dashboard"
|
PRIVATE_SERVER_KEY="same-key-for-api-and-dashboard"
|
||||||
PUBLIC_IS_SELFHOSTED="true"
|
PUBLIC_IS_SELFHOSTED="true"
|
||||||
|
|
||||||
|
# Required for auth cookies when API and dashboard use different subdomains — set to your dashboard domain, e.g. app.yourdomain.com
|
||||||
|
AUTH_COOKIE_DOMAIN="app.yourdomain.com"
|
||||||
|
|
||||||
# Email (configure one)
|
# Email (configure one)
|
||||||
SMTP_HOST=
|
SMTP_HOST=
|
||||||
SMTP_PORT=
|
SMTP_PORT=
|
||||||
@@ -207,6 +209,10 @@ CLOUDFLARE_BUCKET_DOMAIN=
|
|||||||
CLOUDFLARE_IMAGE_BUCKET_DOMAIN=
|
CLOUDFLARE_IMAGE_BUCKET_DOMAIN=
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<Callout type="warn" title="AUTH_COOKIE_DOMAIN (Railway)">
|
||||||
|
When API and dashboard use different subdomains, set `AUTH_COOKIE_DOMAIN` to your dashboard domain (e.g. `app.yourdomain.com`). Without it, Better Auth cookies will not be set and login will fail. Docker self-hosting falls back to `DASHBOARD_ORIGIN` when this is absent.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
Optional: add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` for OAuth, `UNSPLASH_API_KEY` for image search, or `LICENSE_KEY` for enterprise features.
|
Optional: add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` for OAuth, `UNSPLASH_API_KEY` for image search, or `LICENSE_KEY` for enterprise features.
|
||||||
|
|
||||||
### cio-dashboard
|
### cio-dashboard
|
||||||
|
|||||||
@@ -107,8 +107,9 @@ services:
|
|||||||
NODE_ENV: production
|
NODE_ENV: production
|
||||||
PORT: 3081
|
PORT: 3081
|
||||||
PUBLIC_SERVER_URL: ${PUBLIC_SERVER_URL:-http://localhost:3081}
|
PUBLIC_SERVER_URL: ${PUBLIC_SERVER_URL:-http://localhost:3081}
|
||||||
TRUSTED_ORIGINS: ${TRUSTED_ORIGINS:-http://localhost:3082,http://localhost:5173}
|
TRUSTED_ORIGINS: ${TRUSTED_ORIGINS:-http://localhost:3082}
|
||||||
AUTH_COOKIE_DOMAIN: ${AUTH_COOKIE_DOMAIN:-}
|
AUTH_COOKIE_DOMAIN: ${AUTH_COOKIE_DOMAIN:-}
|
||||||
|
DASHBOARD_ORIGIN: ${DASHBOARD_ORIGIN:-http://localhost:3082}
|
||||||
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
|
DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
|
||||||
PRIVATE_DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
|
PRIVATE_DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres}@postgres:5432/${POSTGRES_DB:-classroomio}
|
||||||
REDIS_URL: redis://redis:6379
|
REDIS_URL: redis://redis:6379
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ All Docker services read from a single root `.env` file. See [`.env.example`](..
|
|||||||
Key points:
|
Key points:
|
||||||
|
|
||||||
- **Required:** `PUBLIC_SERVER_URL`, `TRUSTED_ORIGINS`, `BETTER_AUTH_SECRET`, `PUBLIC_IS_SELFHOSTED=true`, `ALLOWED_EXTERNAL_DOMAINS`, `DASHBOARD_ORIGIN`.
|
- **Required:** `PUBLIC_SERVER_URL`, `TRUSTED_ORIGINS`, `BETTER_AUTH_SECRET`, `PUBLIC_IS_SELFHOSTED=true`, `ALLOWED_EXTERNAL_DOMAINS`, `DASHBOARD_ORIGIN`.
|
||||||
|
- **Auth cookies:** When `AUTH_COOKIE_DOMAIN` is absent, the API falls back to `DASHBOARD_ORIGIN` (hostname).
|
||||||
- **Auto-generated:** `AUTH_BEARER_TOKEN`, `PRIVATE_SERVER_KEY` (by `./run-docker-full-stack.sh`).
|
- **Auto-generated:** `AUTH_BEARER_TOKEN`, `PRIVATE_SERVER_KEY` (by `./run-docker-full-stack.sh`).
|
||||||
- **Auto-configured:** All `MINIO_*` / `OBJECT_STORAGE_*` vars (by the startup script).
|
- **Auto-configured:** All `MINIO_*` / `OBJECT_STORAGE_*` vars (by the startup script).
|
||||||
- **Optional:** Email (SMTP or Zoho), Google OAuth, Unsplash, `LICENSE_KEY` (enterprise).
|
- **Optional:** Email (SMTP or Zoho), Google OAuth, Unsplash, `LICENSE_KEY` (enterprise).
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
const {
|
const {
|
||||||
TRUSTED_ORIGINS: TRUSTED_ORIGINS_STRING,
|
TRUSTED_ORIGINS: TRUSTED_ORIGINS_STRING,
|
||||||
PUBLIC_SERVER_URL,
|
PUBLIC_SERVER_URL,
|
||||||
AUTH_COOKIE_DOMAIN: AUTH_COOKIE_DOMAIN_STRING
|
AUTH_COOKIE_DOMAIN: AUTH_COOKIE_DOMAIN_STRING,
|
||||||
|
DASHBOARD_ORIGIN: DASHBOARD_ORIGIN_STRING
|
||||||
} = process.env;
|
} = process.env;
|
||||||
|
|
||||||
const DEFAULT_TRUSTED_ORIGINS = [
|
const DEFAULT_TRUSTED_ORIGINS = [
|
||||||
@@ -30,4 +31,18 @@ export const TRUSTED_ORIGINS = TRUSTED_ORIGINS_STRING
|
|||||||
|
|
||||||
export const BASE_URL = PUBLIC_SERVER_URL || 'http://localhost:3002';
|
export const BASE_URL = PUBLIC_SERVER_URL || 'http://localhost:3002';
|
||||||
|
|
||||||
export const AUTH_COOKIE_DOMAIN = AUTH_COOKIE_DOMAIN_STRING?.trim() || undefined;
|
function getAuthCookieDomain(): string | undefined {
|
||||||
|
const explicit = AUTH_COOKIE_DOMAIN_STRING?.trim();
|
||||||
|
if (explicit) return explicit;
|
||||||
|
|
||||||
|
if (!DASHBOARD_ORIGIN_STRING?.trim()) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL(DASHBOARD_ORIGIN_STRING.trim());
|
||||||
|
return url.hostname || undefined;
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AUTH_COOKIE_DOMAIN = getAuthCookieDomain();
|
||||||
|
|||||||
Reference in New Issue
Block a user