Repository navigation
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
103 lines (99 loc) · 4.93 KB
/
Copy pathdocker-compose.yml
File metadata and controls
103 lines (99 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# Learning Platform — full self-host stack ("the full implementation").
#
# `docker compose up` brings up the whole product on a real database:
# • course platform → http://localhost:8080 (the React SPA, both personas)
# • Adminium admin → http://localhost:4600 (auto-generated from the DB schema)
# • Postgres (lms-db) (seeded courses, lessons, cohorts)
#
# On first boot, lms-db applies db/schema.sql then db/seed.sql, and Adminium
# connects ADMINIUM_SOURCE_URL, introspects the schema, and generates the back
# office. Create your admin account in the ~1-minute first-run wizard at
# http://localhost:4600 — the seeded academy DB is already connected. The
# classroom and the dashboard serve the SAME academy: a submission a student
# makes on :8080 is the submission an instructor grades on :4600.
#
# Copy .env.example to .env and set a real ADMINIUM_SECRET before any real use.
services:
# --- PostgreSQL: the real database backing the academy ------------------
lms-db:
image: postgres:16
environment:
POSTGRES_USER: adminium
POSTGRES_PASSWORD: adminium
POSTGRES_DB: academy
# Load db/seed.sql on first boot? Set DEMO_DATA=0 in .env for an empty
# database with the same schema. `npm run demo:import` loads it later.
DEMO_DATA: ${DEMO_DATA:-1}
volumes:
- lms-db-data:/var/lib/postgresql/data
# Auto-applied in name order on an empty data volume:
- ./db/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
- ./db/demo-toolkit.sql:/docker-entrypoint-initdb.d/02-demo-toolkit.sql:ro
- ./db/init-demo.sh:/docker-entrypoint-initdb.d/03-demo-seed.sh:ro
# Deliberately NOT in initdb.d: 03-demo-seed.sh decides whether to load
# it (DEMO_DATA) and records what it inserted, so the demo rows can be
# removed later without touching the schema or anything you added.
- ./db/seed.sql:/demo/seed.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U adminium -d academy"]
interval: 5s
timeout: 5s
retries: 10
restart: unless-stopped
# --- Adminium: auto-generates the back office from the DB schema --------
adminium:
image: ghcr.io/mosofi/adminium:latest
depends_on:
lms-db:
condition: service_healthy
environment:
# !!! PRODUCTION MUST SET A REAL 32-BYTE HEX SECRET: `openssl rand -hex 32`.
# The fallback below is a throwaway for the LOCAL DEMO ONLY — never ship it.
ADMINIUM_SECRET: ${ADMINIUM_SECRET:-devsecret-change-me-0000000000000000000000000000000000000000000000000000}
# Your database — the one the dashboard is generated FROM. On the first
# boot Adminium connects it, introspects the schema, and generates the
# pages; a bad DSN is reported and retried on the next boot instead of
# stopping it. It runs ONCE: a connection you delete later is not rebuilt.
ADMINIUM_SOURCE_URL: postgres://adminium:adminium@lms-db:5432/academy
# Embedded SQLite meta store (settings, users) lives here — fine for the demo.
ADMINIUM_DATA_DIR: /data
# Safe ONLY because this service publishes no ports (see below): every
# request arrives through this stack's own Caddy, so the forwarded client
# address is one Caddy wrote. Turn this on while 4600 is directly
# reachable and any caller can forge their source IP — out of the audit
# log and out of every per-IP limit.
ADMINIUM_TRUST_PROXY: "1"
volumes:
- adminium-data:/data
# No `ports:` — 4600 is NOT published from this service. It is reachable
# only on the compose network, through the `web` container's Caddy, and
# that is the precondition for the ADMINIUM_TRUST_PROXY set above.
restart: unless-stopped
# --- Course platform: the static SPA built from this repo's Dockerfile --
web:
build:
context: .
dockerfile: Dockerfile
# Connected mode. Unset — which is the default — builds the demo
# exactly as before; Vite inlines these, so they are build args and not
# `environment:`, and changing either needs `--build` to take effect.
# Mint the key in Studio -> Public API against a scope covering these refs:
# instructors, courses, modules, lessons, cohorts, exams,
# examQuestions, announcements and liveSessions — plus students,
# enrollments, assignments, submissions and comments on a STAFF-side
# key only. Never expose examQuestions.answer.
args:
VITE_ADMINIUM_API_BASE_URL: ${VITE_ADMINIUM_API_BASE_URL:-}
VITE_ADMINIUM_PUBLISHABLE_KEY: ${VITE_ADMINIUM_PUBLISHABLE_KEY:-}
depends_on:
- adminium
ports:
- "8080:80"
# Adminium's back office, proxied by this container's Caddy (see
# ./Caddyfile). Upgrading an existing checkout? `docker compose up
# --build` — this port is served by an image built from that file.
- "4600:4600"
restart: unless-stopped
volumes:
lms-db-data:
adminium-data: