Appearance
Production Deployment
Container Images
Images are published to the Forgejo container registry via manual workflow dispatch.
Registry: git.lan.raz.wtf/raz/libris
| Image | Port | Description |
|---|---|---|
git.lan.raz.wtf/raz/libris/api | 3000 | Nitro API server |
git.lan.raz.wtf/raz/libris/web | 3100 | Nuxt frontend (SSR) |
Tags:
v<version>— version from package.json (e.g.,v1.2.0)latest— most recent build
Building images
Trigger the Publish Images workflow from the Forgejo UI: Actions > Publish Images > Run workflow. It builds both images from the Dockerfile.api and Dockerfile.web at the current HEAD.
Pulling images
bash
docker login git.lan.raz.wtf
docker pull git.lan.raz.wtf/raz/libris/api:latest
docker pull git.lan.raz.wtf/raz/libris/web:latestEnvironment Variables
API service (required)
| Variable | Purpose |
|---|---|
NITRO_DATABASE_URL | PostgreSQL connection string (e.g., postgresql://user:pass@host:5432/libris) |
NITRO_REDIS_URL | Redis connection string (e.g., redis://host:6379) |
NITRO_INBOX_PATH | Writable directory for uploaded book files |
NITRO_LIBRARY_PATH | Writable directory for organized book storage |
NITRO_API_SECRET_KEY | Token encryption secret — minimum 32 characters |
API service (optional)
| Variable | Purpose |
|---|---|
NITRO_CORS_ORIGIN | Allowed CORS origins (comma-separated or *) |
NITRO_KOSYNC_USERNAME | KoReader sync username |
NITRO_KOSYNC_PASSWORD_HASH | bcrypt hash of KoSync password |
Web service (required)
| Variable | Purpose |
|---|---|
NUXT_SESSION_PASSWORD | Session cookie encryption — minimum 32 characters |
Web service (optional)
| Variable | Default | Purpose |
|---|---|---|
NUXT_API_BASE_URL | http://localhost:3000 | Internal URL from web to API (use Docker service name, e.g., http://api:3000) |
NUXT_PUBLIC_API_PUBLIC_URL | — | Public-facing API URL shown in settings page for OPDS/KoSync endpoints |
NODE_ENV=production is baked into both images.
Both services validate environment variables on startup and will fail immediately with a clear error if required variables are missing or invalid.
Volumes
The API container needs persistent, writable storage for two paths:
| Mount target | Purpose |
|---|---|
Value of NITRO_INBOX_PATH | Incoming book files (watched for ingestion) |
Value of NITRO_LIBRARY_PATH | Organized book library |
Example Docker Compose
yaml
services:
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: libris
POSTGRES_PASSWORD: changeme
POSTGRES_DB: libris
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U libris"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
api:
image: git.lan.raz.wtf/raz/libris/api:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
environment:
NITRO_DATABASE_URL: postgresql://libris:changeme@db:5432/libris
NITRO_REDIS_URL: redis://redis:6379
NITRO_INBOX_PATH: /data/inbox
NITRO_LIBRARY_PATH: /data/library
NITRO_API_SECRET_KEY: # openssl rand -hex 32
volumes:
- inbox:/data/inbox
- library:/data/library
ports:
- "3000:3000"
web:
image: git.lan.raz.wtf/raz/libris/web:latest
restart: unless-stopped
depends_on:
- api
environment:
NUXT_SESSION_PASSWORD: # openssl rand -hex 32
NUXT_API_BASE_URL: http://api:3000
ports:
- "3100:3100"
volumes:
db_data:
inbox:
library:Database Migrations
Migrations apply automatically on API startup via the 0.migrate.ts server plugin. No manual migration step is needed when deploying a new image.