The compose stack reads .env in the repository root (start from
.env.example). Courses are configured in the database via Course settings;
see Course configuration. Exercise
templates are fetched lazily from course module archives.
| Variable |
Default |
Meaning |
APLUS_BASE_URL |
https://plus.cs.aalto.fi/api/v2/ |
The one A+ instance this deployment talks to. For the local A+ profile: http://plus:8000/api/v2/. |
APLUS_URL |
backend-advertised origin |
Browser-facing A+ origin for links and download-only previews. The local A+ profile uses http://localhost:8000. |
APLUS_CONNECT_TIMEOUT_SECONDS |
5 |
A+ TCP connection timeout (1-30). |
APLUS_SOCKET_TIMEOUT_SECONDS |
60 |
A+ socket timeout (1-300). |
APLUS_REQUEST_TIMEOUT_SECONDS |
120 |
Whole A+ request timeout (1-600). |
APLUS_MAX_REDIRECTS |
3 |
Explicit same-origin redirect limit (0-3). |
APLUS_ERROR_BODY_BYTES |
4096 |
Maximum A+ write-error diagnostic body retained for server logs (256-65536). |
APLUS_RESPONSE_BODY_BYTES |
26214400 |
Maximum decoded JSON bytes accepted from one A+ response (1048576-104857600). |
APLUS_PAGINATION_BODY_BYTES |
104857600 |
Maximum decoded JSON bytes accepted across one paginated A+ request (APLUS_RESPONSE_BODY_BYTES-1073741824). |
APLUS_EXERCISE_FORM_CONCURRENCY |
16 |
Maximum concurrent exercise-form reads while building a cold course structure snapshot (1-64). |
| Variable |
Default |
Meaning |
POSTGRES_USER |
hanami |
Database user. |
POSTGRES_PASSWORD |
- |
Required. No default: docker compose up fails fast while empty, and the backend refuses weak/empty passwords against a real Postgres. |
POSTGRES_POOL_SIZE |
10 |
Maximum backend JDBC connection pool size (1-100). |
POSTGRES_DB |
hanami |
Database name. |
POSTGRES_PORT |
5432 |
Loopback-only port for local debugging (psql -h localhost), not a public listener. |
POSTGRES_URL |
set by compose |
JDBC URL the backend connects to. Required unless native development explicitly enables ephemeral H2. |
ALLOW_IN_MEMORY_DATABASE |
false |
Set to true only for native development without POSTGRES_URL; data vanishes on restart. It cannot be combined with POSTGRES_URL. |
POSTGRES_HEALTHCHECK_INTERVAL |
10s |
Compose interval for the Postgres readiness probe. |
| Variable |
Default |
Meaning |
BACKEND_PORT |
8088 |
Published backend port. |
FRONTEND_PORT |
3000 |
Published frontend port. |
FRONTEND_BIND |
127.0.0.1 |
Host address for the published frontend port. Set 0.0.0.0 only for intentional remote access and protect the port with a firewall. |
DOCS_PORT |
3001 |
Published documentation site port. |
FRONTEND_ORIGIN |
http://localhost:3000 |
Public origin the frontend is served from (SvelteKit CSRF / same-origin checks). Set to the public https:// URL in production. |
PROTOCOL_HEADER / HOST_HEADER |
- |
Behind a TLS-terminating proxy forwarding plain HTTP, set to x-forwarded-proto / x-forwarded-host so SvelteKit sees the real scheme and host. |
ADDRESS_HEADER / XFF_DEPTH |
- / 1 |
With the bundled Caddy edge, set these to x-forwarded-for / 1 so SvelteKit uses the client address added by the single trusted proxy. |
BACKEND_HEALTHCHECK_INTERVAL |
10s |
Compose interval for the backend readiness probe. |
The optional edge Compose profile runs Caddy in front of the frontend.
| Variable |
Default |
Meaning |
HANAMI_HOST |
- |
Required for the edge profile. Public DNS hostname served by Caddy. |
HTTP_PORT |
80 |
Published TCP port for HTTP and automatic HTTPS redirects. |
HTTPS_PORT |
443 |
Published TCP and UDP port for HTTPS over HTTP/2 and HTTP/3. |
| Variable |
Default |
Meaning |
GITHUB_URL |
https://github.com/jaakkonakaza/hanami |
Source repository linked from the frontend footer. |
DOCS_URL |
unset |
Deployed documentation origin linked from the frontend footer. Local development uses http://localhost:3001. |
LICENSE_URL |
{GITHUB_URL}/blob/main/LICENSE |
License page linked from the frontend footer. |
HANAMI_VERSION |
package version |
Optional deployment override for the application version shown in the footer. Releases normally use the version embedded in the package. |
See the security model before changing these values.
| Variable |
Meaning |
COOKIE_SECURE=true |
Force the session cookie’s Secure flag even when SvelteKit computed an http:// origin. |
ALLOW_INSECURE_HTTP=true |
Allow non-loopback HTTP session cookies for disposable local development. Never use this in production. |
ALLOW_WEAK_DB_PASSWORD=true |
Throwaway local dev only: let the backend connect to Postgres with a weak/empty password. |
ALLOW_PRIVATE_COURSE_CONFIG_URL=true |
Throwaway local Compose or native-backend dev only: allow a courseConfigUrl on a private/loopback host. Never set in production. |
LTI_ALLOW_WEAK_SECRET=true |
Local A+ dev only: accept LTI launches signed with the well-known dev secret. |
FRONTEND_SESSION_ENCRYPTION_KEY and FRONTEND_SERVICE_SECRET are required. Supply both through deployment secrets, not image layers or the database.
| Variable |
Default |
Meaning |
FRONTEND_SESSION_ENCRYPTION_KEY |
required |
Base64 encoding of exactly 32 random bytes used for new A+ token ciphertext |
FRONTEND_SESSION_KEY_VERSION |
v1 |
Version stored with sessions created by the active encryption key |
FRONTEND_SESSION_PREVIOUS_ENCRYPTION_KEYS |
empty |
Comma-separated version=base64 keys retained while sessions from a routine rotation expire |
FRONTEND_SERVICE_SECRET |
required |
Shared SvelteKit-to-Ktor credential with at least 32 visible ASCII characters |
FRONTEND_SESSION_STUDENT_IDLE_DAYS |
7 |
Student idle timeout, from 1 to 30 days |
FRONTEND_SESSION_STUDENT_ABSOLUTE_DAYS |
90 |
Student absolute timeout, from 7 to 365 days |
FRONTEND_SESSION_STAFF_IDLE_DAYS |
1 |
Teacher and assistant idle timeout, from 1 to 7 days |
FRONTEND_SESSION_STAFF_ABSOLUTE_DAYS |
30 |
Teacher and assistant absolute timeout, from 1 to 90 days |
FRONTEND_SESSION_TOUCH_SECONDS |
3600 |
Minimum interval between last-use database writes |
FRONTEND_SESSION_CLEANUP_SECONDS |
300 |
Background cleanup interval |
FRONTEND_SESSION_CLEANUP_BATCH_SIZE |
500 |
Maximum expired or revoked rows deleted per cleanup pass |
FRONTEND_SESSION_MAX_PER_USER |
20 |
Maximum active sessions retained per A+ user |
FRONTEND_SESSION_CREATION_ENABLED |
true |
Set to false to stop new sign-ins during incident response |
Optional; see Sign-in and LTI.
| Variable |
Meaning |
LTI_CONSUMER_KEY / LTI_CONSUMER_SECRET |
Key and secret of the LTI 1.1 service configured in the A+ site admin. Leave empty to disable and keep only the manual token gate. |
LTI_LAUNCH_URL |
Override the launch URL used to verify the OAuth1 signature, only if the origin SvelteKit sees differs from what A+ signs (e.g. behind a proxy). |
LTI_MENU_LABEL |
Backend-side A+ course-menu label used to discover each course’s LTI launch URL. Defaults to Hanami. |
Fresh values are returned immediately. Values between their fresh and maximum
ages are returned immediately while one deduplicated refresh runs in the
background. Values beyond the maximum age are loaded before the request returns.
| Variable |
Default |
AUTH_CACHE_FRESH_SECONDS |
300 |
AUTH_CACHE_MAX_AGE_SECONDS |
900 |
AUTH_NEGATIVE_CACHE_TTL_SECONDS |
30 |
AUTH_CACHE_MAX_ENTRIES |
10000 |
SNAPSHOT_CACHE_FRESH_SECONDS |
21600 |
SNAPSHOT_CACHE_MAX_AGE_SECONDS |
86400 |
ROSTER_CACHE_FRESH_SECONDS |
900 |
ROSTER_CACHE_MAX_AGE_SECONDS |
3600 |
PROGRESS_CACHE_FRESH_SECONDS |
300 |
PROGRESS_CACHE_MAX_AGE_SECONDS |
1800 |
METADATA_CACHE_FRESH_SECONDS |
3600 |
METADATA_CACHE_MAX_AGE_SECONDS |
86400 |
COURSE_CACHE_MAX_ENTRIES_PER_KIND |
10000 |
AVAILABILITY_CACHE_FRESH_SECONDS |
900 |
AVAILABILITY_CACHE_MAX_AGE_SECONDS |
3600 |
AVAILABILITY_FAILURE_TTL_SECONDS |
15 |
AVAILABILITY_CACHE_MAX_ENTRIES |
10000 |
SUBMISSION_FILE_CACHE_BYTES |
268435456 |
SUBMISSION_FILE_CACHE_ENTRY_BYTES |
2097152 |
SUBMISSION_FILE_CACHE_TTL_SECONDS |
86400 |
ACTIVE_GRADING_CACHE_FRESH_SECONDS |
10 |
ACTIVE_GRADING_CACHE_MAX_AGE_SECONDS |
30 |
GRADING_SUBMISSION_MAX_COUNT |
10000 |
GRADING_SUBMISSION_CACHE_MAX_RECORDS |
20000 |
SUBMISSION_LOAD_MAX_ACTIVE |
8 |
SUBMISSION_LOAD_MAX_QUEUED |
32 |
SUBMISSION_DOWNLOAD_CONCURRENCY |
4 |
TEMPLATE_CATALOG_FRESH_SECONDS |
21600 |
TEMPLATE_CATALOG_MAX_AGE_SECONDS |
86400 |
TEMPLATE_DOWNLOAD_TIMEOUT_SECONDS |
30 |
TEMPLATE_FAILURE_TTL_SECONDS |
300 |
Unset SMTP_HOST disables sending. Local dev with the aplus profile:
SMTP_HOST=mailpit, SMTP_PORT=1025, then read mail at
http://localhost:8025.
| Variable |
Default |
SMTP_HOST |
- (disabled) |
SMTP_PORT |
25 |
SMTP_FROM |
hanami@localhost |
SMTP_USER / SMTP_PASSWORD |
- |
SMTP_STARTTLS |
false |
Leave both secrets unset to disable deferred manual grading. Use independent,
random values in a deployment; both secrets must contain at least 32 UTF-8
bytes.
| Variable |
Default |
Meaning |
MANUAL_GRADING_ENCRYPTION_KEY |
- |
Encrypts A+ callback capabilities at rest. |
MANUAL_GRADING_REGISTRATION_SECRET |
- |
Authenticates intake-grader registration and fixture reset requests. |
MANUAL_GRADING_CALLBACK_ORIGINS |
http://grader:8080,http://plus:8000 |
Comma-separated callback origins accepted during registration. |
MANUAL_GRADING_CONNECT_TIMEOUT_SECONDS |
5 |
Callback connection timeout (1-30). |
MANUAL_GRADING_REQUEST_TIMEOUT_SECONDS |
30 |
Whole callback request timeout (1-120). |
MANUAL_GRADING_SOCKET_TIMEOUT_SECONDS |
30 |
Callback socket timeout (1-120). |
MANUAL_GRADING_ERROR_BODY_BYTES |
4096 |
Maximum callback error response read before it is discarded (256-65536). |
MANUAL_GRADING_COMPLETED_RETENTION_DAYS |
90 |
Days to retain completed capability rows before deleting their encrypted callback credential (1-3650). |
| Variable |
Default |
Meaning |
APLUS_PORT |
8000 |
Published A+ front port. |
GRADER_PORT |
8080 |
Published grader port. |
APLUS_COURSE_DIR |
./aplus/aplus-manual |
Host course directory mounted into the local A+ and grader containers. |
APLUS_LOCAL_SETTINGS |
- |
Optional settings module mounted into the local A+ container. |
COMPOSE_NETWORK_NAME |
hanami_default |
Concrete Compose network name used by services. |
GRADER_RUNNER_MODULE_NETWORK |
hanami_default |
Network attached to grader-runner containers; set it to the same value as COMPOSE_NETWORK_NAME. |
GRADER_RUNNER_NAMESPACE |
hanami |
Namespace for staged grader-runner copies under /tmp/aplus. |
MAILPIT_UI_PORT |
8025 |
Published Mailpit web UI port. |
MAILPIT_SMTP_PORT |
1025 |
Published Mailpit SMTP port. |
Read from frontend/.env.local (start from frontend/.env.example), or set
by scripts/dev-frontend.sh; see
Getting started.
| Variable |
Meaning |
BACKEND_URL |
Backend to proxy API calls to (default http://localhost:8088). |
APLUS_URL |
Browser-facing A+ origin for external links and runtime LTI origin validation. Native development uses the published port, such as http://localhost:8000. |
DOCS_URL |
Documentation origin for the footer (default http://localhost:3001 in the development helpers). |
GITHUB_URL |
Source repository for the footer. |
FRONTEND_SERVICE_SECRET |
Must match the Ktor service secret. Native scripts provide a local development value. |
These are set by repository scripts and test tooling rather than by a normal
deployment:
| Variable |
Purpose |
DOCKER_DEV |
Enables Vite’s Docker HMR settings in docker-compose.dev.yml. |
SVELTE_KIT_OUT_DIR |
Keeps svelte-check output separate from the live development build. |
VITEST |
Selects the isolated SvelteKit output directory used by Vitest. |
HANAMI_FIXTURE_BACKEND_ORIGINS |
Exact comma-separated origins that local fixture provisioning may contact in addition to loopback development URLs. |