chore: update environment configuration and build outputs
- Added new output path for build artifacts in turbo.json to include "build/**". - Updated .env.example to include required environment variables for database and Redis connections, enhancing clarity for setup. - Refined self-hosting documentation to ensure accurate configuration for public server URLs and object storage options.
This commit is contained in:
+36
-33
@@ -1,40 +1,43 @@
|
|||||||
DATABASE_URL=
|
# Required
|
||||||
|
DATABASE_URL=""
|
||||||
|
REDIS_URL=""
|
||||||
|
PUBLIC_SERVER_URL=""
|
||||||
|
|
||||||
## Object storage - choose one option below
|
TRUSTED_ORIGINS=""
|
||||||
|
BETTER_AUTH_SECRET=""
|
||||||
|
|
||||||
# Option A: Cloudflare R2 (legacy)
|
AUTH_BEARER_TOKEN=""
|
||||||
# CLOUDFLARE_BUCKET_DOMAIN=https://cdn.example.com
|
AUTH_COOKIE_DOMAIN=""
|
||||||
# CLOUDFLARE_ACCESS_KEY=
|
|
||||||
# CLOUDFLARE_SECRET_ACCESS_KEY=
|
|
||||||
# CLOUDFLARE_ACCOUNT_ID=
|
|
||||||
# CLOUDFLARE_IMAGE_BUCKET_DOMAIN=https://media.example.com
|
|
||||||
|
|
||||||
# Option B: MinIO or other S3-compatible storage (on-premise, data residency)
|
SMTP_HOST=""
|
||||||
# When API runs locally: use localhost. When API runs in Docker: use http://minio:9000
|
SMTP_PORT=""
|
||||||
# OBJECT_STORAGE_ENDPOINT=http://localhost:9000
|
SMTP_USER=""
|
||||||
# OBJECT_STORAGE_PUBLIC_ENDPOINT=http://localhost:9000
|
SMTP_SENDER=""
|
||||||
# OBJECT_STORAGE_ACCESS_KEY_ID=minioadmin
|
SMTP_PASSWORD=""
|
||||||
# OBJECT_STORAGE_SECRET_ACCESS_KEY=minioadmin
|
|
||||||
# OBJECT_STORAGE_FORCE_PATH_STYLE=true
|
|
||||||
# OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=http://localhost:9000/media
|
|
||||||
|
|
||||||
# Email
|
# Optional - MinIO (S3-compatible, for Docker / on-premise self-hosting)
|
||||||
SMTP_HOST=
|
# When API runs in Docker: use http://minio:9000. For local API: use http://localhost:9000
|
||||||
SMTP_USER=
|
MINIO_ROOT_USER=""
|
||||||
SMTP_PASSWORD=
|
MINIO_ROOT_PASSWORD=""
|
||||||
SMTP_PORT=
|
OBJECT_STORAGE_ENDPOINT=""
|
||||||
SMTP_SENDER=
|
OBJECT_STORAGE_PUBLIC_ENDPOINT=""
|
||||||
|
OBJECT_STORAGE_ACCESS_KEY_ID=""
|
||||||
|
OBJECT_STORAGE_SECRET_ACCESS_KEY=""
|
||||||
|
OBJECT_STORAGE_FORCE_PATH_STYLE=""
|
||||||
|
OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=""
|
||||||
|
|
||||||
# Enterprise features (optional for self-hosted deployments)
|
# Optional - Cloudflare R2 (for hosted deployments)
|
||||||
# Request a key from ClassroomIO. Leave empty if you do not use Enterprise-only features.
|
CLOUDFLARE_BUCKET_ID=""
|
||||||
LICENSE_KEY=
|
CLOUDFLARE_ACCESS_KEY=""
|
||||||
|
CLOUDFLARE_ACCOUNT_ID=""
|
||||||
|
CLOUDFLARE_BUCKET_DOMAIN=""
|
||||||
|
CLOUDFLARE_SECRET_ACCESS_KEY=""
|
||||||
|
SENTRY_DNS=""
|
||||||
|
|
||||||
# Sentry DNS
|
# Enterprise (Optional)
|
||||||
SENTRY_DNS=
|
# Required only when using Enterprise-only features (SSO, token-auth, no-tracking)
|
||||||
|
LICENSE_KEY=""
|
||||||
|
|
||||||
OPENAPI_URL=
|
# SSO (Optional)
|
||||||
|
# For enterprise SSO with SAML (future support)
|
||||||
PRIVATE_SERVER_KEY=
|
# SSO_ENCRYPTION_KEY="your-32-character-secret-key"
|
||||||
|
|
||||||
# Public API URL (used for absolute URLs in emails, redirects, etc.)
|
|
||||||
PUBLIC_SERVER_URL=
|
|
||||||
@@ -3,9 +3,9 @@ import 'dotenv/config';
|
|||||||
import { API_PORT } from '@api/constants';
|
import { API_PORT } from '@api/constants';
|
||||||
import { app } from '@api/app';
|
import { app } from '@api/app';
|
||||||
import { configureOpenAPI } from '@api/utils/openapi';
|
import { configureOpenAPI } from '@api/utils/openapi';
|
||||||
|
import { connectRedis } from '@api/utils/redis/redis';
|
||||||
import { serve } from '@hono/node-server';
|
import { serve } from '@hono/node-server';
|
||||||
import { showRoutes } from 'hono/dev';
|
import { showRoutes } from 'hono/dev';
|
||||||
import { connectRedis } from '@api/utils/redis/redis';
|
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
async function startServer() {
|
async function startServer() {
|
||||||
|
|||||||
@@ -150,8 +150,8 @@ For Enterprise SSO support, you need to configure the following:
|
|||||||
TRUSTED_ORIGINS="https://app.classroomio.com,https://your-org.okta.com,https://accounts.google.com"
|
TRUSTED_ORIGINS="https://app.classroomio.com,https://your-org.okta.com,https://accounts.google.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Callback URLs**: Ensure your `SERVER_URL` and `PUBLIC_SERVER_URL` are correctly set. SSO callbacks will be:
|
3. **Callback URLs**: Ensure your `PUBLIC_SERVER_URL` is correctly set. SSO callbacks will be:
|
||||||
- `{SERVER_URL}/api/auth/sso/callback/{providerId}`
|
- `{PUBLIC_SERVER_URL}/api/auth/sso/callback/{providerId}`
|
||||||
|
|
||||||
4. **License Check**: The system will verify your Enterprise license before allowing SSO configuration. Without a valid license, the SSO settings page will show an upgrade prompt.
|
4. **License Check**: The system will verify your Enterprise license before allowing SSO configuration. Without a valid license, the SSO settings page will show an upgrade prompt.
|
||||||
|
|
||||||
@@ -170,20 +170,31 @@ Go ahead and click this button to get started.
|
|||||||
```zsh title="env"
|
```zsh title="env"
|
||||||
# Required
|
# Required
|
||||||
DATABASE_URL=""
|
DATABASE_URL=""
|
||||||
PRIVATE_DATABASE_URL=""
|
|
||||||
REDIS_URL=""
|
REDIS_URL=""
|
||||||
SERVER_URL=""
|
PUBLIC_SERVER_URL=""
|
||||||
TRUSTED_ORIGINS=""
|
TRUSTED_ORIGINS=""
|
||||||
BETTER_AUTH_SECRET=""
|
BETTER_AUTH_SECRET=""
|
||||||
AUTH_BEARER_TOKEN=""
|
AUTH_BEARER_TOKEN=""
|
||||||
AUTH_COOKIE_DOMAIN=""
|
AUTH_COOKIE_DOMAIN=""
|
||||||
|
PRIVATE_SERVER_KEY=""
|
||||||
SMTP_HOST=""
|
SMTP_HOST=""
|
||||||
SMTP_PORT=""
|
SMTP_PORT=""
|
||||||
SMTP_USER=""
|
SMTP_USER=""
|
||||||
SMTP_SENDER=""
|
SMTP_SENDER=""
|
||||||
SMTP_PASSWORD=""
|
SMTP_PASSWORD=""
|
||||||
|
|
||||||
# Optional
|
# Optional - MinIO (S3-compatible, for Docker / on-premise self-hosting)
|
||||||
|
# When API runs in Docker: use minio service name. For local API: use http://localhost:9000
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
OBJECT_STORAGE_ENDPOINT=http://minio:9000
|
||||||
|
OBJECT_STORAGE_PUBLIC_ENDPOINT=http://localhost:9000
|
||||||
|
OBJECT_STORAGE_ACCESS_KEY_ID=minioadmin
|
||||||
|
OBJECT_STORAGE_SECRET_ACCESS_KEY=minioadmin
|
||||||
|
OBJECT_STORAGE_FORCE_PATH_STYLE=true
|
||||||
|
OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=http://localhost:9000/media
|
||||||
|
|
||||||
|
# Optional - Cloudflare R2 (for hosted deployments)
|
||||||
CLOUDFLARE_BUCKET_ID=""
|
CLOUDFLARE_BUCKET_ID=""
|
||||||
CLOUDFLARE_ACCESS_KEY=""
|
CLOUDFLARE_ACCESS_KEY=""
|
||||||
CLOUDFLARE_ACCOUNT_ID=""
|
CLOUDFLARE_ACCOUNT_ID=""
|
||||||
@@ -327,11 +338,20 @@ PRIVATE_SERVER_KEY=
|
|||||||
# Required only for Enterprise-only features (SSO, token-auth, no-tracking)
|
# Required only for Enterprise-only features (SSO, token-auth, no-tracking)
|
||||||
LICENSE_KEY=
|
LICENSE_KEY=
|
||||||
|
|
||||||
SERVER_URL=
|
|
||||||
PUBLIC_SERVER_URL=
|
PUBLIC_SERVER_URL=
|
||||||
PRIVATE_SERVER_URL=
|
PRIVATE_SERVER_URL=
|
||||||
TRUSTED_ORIGINS=
|
TRUSTED_ORIGINS=
|
||||||
AUTH_COOKIE_DOMAIN=
|
AUTH_COOKIE_DOMAIN=
|
||||||
|
|
||||||
|
# MinIO (object storage, when using ./run-docker-full-stack.sh with MinIO)
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
OBJECT_STORAGE_ENDPOINT=http://minio:9000
|
||||||
|
OBJECT_STORAGE_PUBLIC_ENDPOINT=http://localhost:9000
|
||||||
|
OBJECT_STORAGE_ACCESS_KEY_ID=minioadmin
|
||||||
|
OBJECT_STORAGE_SECRET_ACCESS_KEY=minioadmin
|
||||||
|
OBJECT_STORAGE_FORCE_PATH_STYLE=true
|
||||||
|
OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL=http://localhost:9000/media
|
||||||
```
|
```
|
||||||
|
|
||||||
<Callout title="Important">
|
<Callout title="Important">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ POSTGRES_USER=postgres
|
|||||||
POSTGRES_PASSWORD=postgres
|
POSTGRES_PASSWORD=postgres
|
||||||
|
|
||||||
# API runtime
|
# API runtime
|
||||||
SERVER_URL=https://api.domain.com
|
PUBLIC_SERVER_URL=https://api.domain.com
|
||||||
TRUSTED_ORIGINS=https://app.domain.com
|
TRUSTED_ORIGINS=https://app.domain.com
|
||||||
# Optional: cookie domain for Better Auth cross-subdomain cookies.
|
# Optional: cookie domain for Better Auth cross-subdomain cookies.
|
||||||
# Use either .domain.com (shared across subdomains) or your API host.
|
# Use either .domain.com (shared across subdomains) or your API host.
|
||||||
|
|||||||
+26
-8
@@ -34,12 +34,30 @@ Now when I am ready to deploy the feature, I can use [option 2](https://orm.driz
|
|||||||
|
|
||||||
I can make changes directly to the schema file and run `pnpm db push` to push the changes to the source db.
|
I can make changes directly to the schema file and run `pnpm db push` to push the changes to the source db.
|
||||||
|
|
||||||
## Change email flow
|
## Setting up a new DB on Railway
|
||||||
|
|
||||||
1. User changes email on dashboard to new email
|
Once you setup a Postgres DB on Railway, you should copyt the `DATABASE_PUBLIC_URL` and paste into your `.env`. In the `.env` we expect `DATABASE_URL`:
|
||||||
2. We send an email verification to the current, permitting the change
|
|
||||||
3. Meanwhile the frontend reverts to the previous email.
|
```.env
|
||||||
4. User clicks approve link in email
|
DATABASE_URL=what-you-copied-from-railway
|
||||||
5. User is redirected to settings page with message that another email has been sent to the new email
|
```
|
||||||
6. User goes to new email inbox and clicks approve link in email
|
|
||||||
7. User is taken to the settings page with new email address.
|
### Commands
|
||||||
|
|
||||||
|
#### db:setup
|
||||||
|
|
||||||
|
Prepares the database so the application can run. Run this for new databases or after provisioning Postgres.
|
||||||
|
|
||||||
|
```
|
||||||
|
pnpm db:setup
|
||||||
|
```
|
||||||
|
|
||||||
|
It performs three steps in order:
|
||||||
|
|
||||||
|
1. **Schema sync** – Runs `drizzle-kit push` to apply the TypeScript schema to the database (creates/updates tables, enums, etc.).
|
||||||
|
2. **PostgreSQL roles** – Creates the `authenticated` and `anon` roles if missing (used by RLS policies).
|
||||||
|
3. **Essential seed data** – Inserts required reference data: roles (ADMIN, TUTOR, STUDENT), submission statuses, and question types.
|
||||||
|
|
||||||
|
**Optional:** Add `--seed` (or `-s`) to run the full seed, including demo users, organizations, courses, and other example data.
|
||||||
|
|
||||||
|
Requires `DATABASE_URL` or `PRIVATE_DATABASE_URL` in the environment.
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"dependsOn": ["^build"],
|
"dependsOn": ["^build"],
|
||||||
"outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**", ".vercel/**", "dist/**"]
|
"outputs": [".next/**", "!.next/cache/**", ".svelte-kit/**", ".vercel/**", "dist/**", "build/**"]
|
||||||
},
|
},
|
||||||
"start": {
|
"start": {
|
||||||
"cache": false,
|
"cache": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user