Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ ENCRYPTION_KEY=change-me
# TZ=Europe/Berlin


# Object storage for uploaded files. Default is local disk (the uploads volume
# above). For large multi-GB modules or multi-node setups, use S3 or any
# S3-compatible service (AWS S3, MinIO, Cloudflare R2). See docs/self-hosting.md.
# STORAGE_DRIVER=s3
# S3_BUCKET=study-helper
# S3_REGION=eu-central-1
# S3_ENDPOINT=https://s3.example.com # only for S3-compatible services (MinIO/R2)
# S3_FORCE_PATH_STYLE=true # required by MinIO / some endpoints
# S3_KEY_PREFIX=study-helper # optional object key prefix
# Credentials via the standard AWS chain:
# AWS_ACCESS_KEY_ID=...
# AWS_SECRET_ACCESS_KEY=...


# Demo data on startup: creates admin@example.com / admin-test-1234 (admin)
# and user@example.com / user-test-1234, each with sample study content.
# Runs once (skipped if the accounts exist). Never enable in production.
Expand Down
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,20 @@ services:
# the web tier, set WORKERS_IN_PROCESS: "false" here and run the worker
# service below. By default (unset) the app runs workers in-process — no
# extra service needed.
#
# To store uploaded files in S3 / S3-compatible object storage instead of the
# local uploads volume (recommended for large multi-GB modules or multi-node
# deployments), set STORAGE_DRIVER: "s3" and the S3_* / AWS_* vars below.
# See docs/self-hosting.md → "Object storage (S3)".
# environment:
# WORKERS_IN_PROCESS: "false"
# STORAGE_DRIVER: "s3"
# S3_BUCKET: "study-helper"
# S3_REGION: "eu-central-1"
# S3_ENDPOINT: "https://s3.example.com" # only for S3-compatible services
# S3_FORCE_PATH_STYLE: "true" # required by MinIO / some endpoints
# AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
# AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"

# Optional dedicated job worker. Runs `npm run worker`, which uses tsx — so it
# needs an image that includes the TS sources + devDependencies (a source
Expand Down
37 changes: 31 additions & 6 deletions docs/self-hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ first (see Backup below), or set it correctly before the first

Everything else is configured in **Admin → Settings**:

| Area | What |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Sign-in & SSO | open/closed registration, GitHub/Google login, generic OIDC (Keycloak, Authentik, Zitadel, Authelia, …) |
| AI | providers (Anthropic, OpenAI, Google, Mistral, Groq, Ollama, OpenAI-compatible), models, default + embedding model (enables RAG), monthly token limits |
| Email | SMTP for password resets and reminders, test email |
| Branding | app name, max upload size |
| Area | What |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sign-in & SSO | open/closed registration, GitHub/Google login, generic OIDC (Keycloak, Authentik, Zitadel, Authelia, …) |
| AI | providers (Anthropic, OpenAI, Google, Mistral, Groq, Ollama, OpenAI-compatible), models, default + embedding model (enables RAG), monthly token limits, optional Batch API for cheaper async complete-generation (Anthropic/OpenAI) |
| Email | SMTP for password resets and reminders, test email |
| Branding | app name, max upload size |

A small dot next to the version number in the sidebar (visible to admins)
shows when a newer release is available on GitHub — checked once a day —
Expand All @@ -88,10 +88,35 @@ and links to the release. Installing it is a manual
| `STUDYHELPER_VERSION` | no | Image tag to run (default `latest`); pin e.g. `1.0.0` for reproducible deploys |
| `DATA_DIR` | no | Host directory for the database + uploads volumes (default `./data`, next to `docker-compose.yml`) — see [Where data is stored](#where-data-is-stored) |
| `UPLOAD_DIR` | no | Upload path **inside the container** (default `/data/uploads`) — only relevant for non-Docker deployments; Docker users should set `DATA_DIR` instead |
| `STORAGE_DRIVER` | no | Where uploaded files live: `local` (default, disk under `UPLOAD_DIR`) or `s3` (S3 / S3-compatible object storage) — see [Object storage (S3)](#object-storage-s3) |
| `WORKERS_IN_PROCESS` | no | `false` runs background jobs only in a separate worker process (`npm run worker`) instead of the web tier (default `true` — in-process) |
| `SEED_TEST_DATA` | no | `true` seeds demo accounts (admin@example.com / admin-test-1234, user@example.com / user-test-1234) with sample study content on startup — for evaluation only, never in production |

**Do not lose `ENCRYPTION_KEY`** — encrypted settings (AI keys, SMTP, OIDC secrets) become unreadable without it.

## Object storage (S3)

By default uploaded files are stored on disk (`STORAGE_DRIVER=local`, under
`UPLOAD_DIR` / the `uploads` volume). For large multi-GB modules or multi-node
deployments you can store them in S3 or any S3-compatible service (AWS S3,
MinIO, Cloudflare R2, Hetzner Object Storage) instead:

| Variable | Required | Description |
| --------------------- | --------------- | ----------------------------------------------------------------------------------- |
| `STORAGE_DRIVER` | set to `s3` | Enables the S3 driver |
| `S3_BUCKET` | yes (with `s3`) | Target bucket name |
| `S3_REGION` | no | Bucket region (falls back to `AWS_REGION`, then `us-east-1`) |
| `S3_ENDPOINT` | no | Custom endpoint URL for S3-compatible services (e.g. MinIO/R2); omit for AWS S3 |
| `S3_FORCE_PATH_STYLE` | no | `true` for path-style addressing (needed by MinIO and some S3-compatible endpoints) |
| `S3_KEY_PREFIX` | no | Optional key prefix (folder) for all objects, e.g. `study-helper` |

Credentials come from the standard AWS credential chain — set
`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` (and `AWS_SESSION_TOKEN` if
applicable), or run on infrastructure with an attached IAM role. The value
stored in the database is a backend-agnostic key, so nothing schema-wise
changes; switching drivers does **not** migrate existing files, so pick a
driver before uploading (or copy the objects yourself when migrating).

## Reverse proxy example (Caddy)

```
Expand Down
2 changes: 2 additions & 0 deletions drizzle/0034_old_ben_parker.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE "generation_job" ADD COLUMN "batch_ref" text;--> statement-breakpoint
ALTER TABLE "generation_job" ADD COLUMN "batch_model" text;
Loading
Loading