Skip to content

Configuration

Luc Garrabos edited this page May 6, 2026 · 1 revision

Configuration

BookStorage is configured through environment variables and an optional site.json file for legal information.


Table of contents


Environment variables

Copy the example file and edit it (never commit secrets):

cp .env.example .env

On a server the .env file typically lives at /opt/bookstorage/.env. The stock systemd service includes EnvironmentFile=-/opt/bookstorage/.env.

Complete reference

Variable Description Default
BOOKSTORAGE_ENV development or production. Production enforces a strong secret key. development
BOOKSTORAGE_HOST Listen address 127.0.0.1
BOOKSTORAGE_PORT Listen port 5000
BOOKSTORAGE_DATA_DIR Base data directory (database and paths resolve under this) .
BOOKSTORAGE_DATABASE SQLite database file path (relative to data dir or absolute). Ignored when BOOKSTORAGE_POSTGRES_URL is set. database.db
BOOKSTORAGE_POSTGRES_URL PostgreSQL connection URL. When set, SQLite is not used. (empty)
BOOKSTORAGE_SECRET_KEY Session signing key. Must be at least 32 characters in production. dev-secret-change-me
BOOKSTORAGE_SUPERADMIN_USERNAME Super admin username (created on first run if no superadmin exists) superadmin
BOOKSTORAGE_SUPERADMIN_PASSWORD Super admin password (none)
BOOKSTORAGE_REQUIRE_ACCOUNT_VALIDATION true: new accounts must be approved by an admin. false: immediate login after registration. true
BOOKSTORAGE_UPLOAD_DIR Upload directory for work cover images static/images
BOOKSTORAGE_AVATAR_DIR Upload directory for user avatars static/avatars
BOOKSTORAGE_UPLOAD_URL_PATH URL prefix for uploaded images images
BOOKSTORAGE_AVATAR_URL_PATH URL prefix for avatars avatars
BOOKSTORAGE_ENABLE_HSTS Set to true or 1 to send Strict-Transport-Security. Only use behind HTTPS. (off)
BOOKSTORAGE_PUBLIC_ORIGIN Public site URL without trailing slash (e.g. https://books.example.com). Required for Google OAuth. (empty)
BOOKSTORAGE_GOOGLE_CLIENT_ID Google OAuth 2.0 Web application client ID (empty)
BOOKSTORAGE_GOOGLE_CLIENT_SECRET Google OAuth client secret (empty)
BOOKSTORAGE_TIMEZONE IANA timezone for displaying times (e.g. Europe/Paris). Auto-detected if omitted. (system)
BOOKSTORAGE_METRICS_TOKEN Bearer token to protect GET /metrics. If empty, only loopback clients may scrape. (empty)
BOOKSTORAGE_PROMETHEUS_QUERY_URL Prometheus HTTP API base URL for the admin Monitoring page. Must be loopback. http://127.0.0.1:9091
BOOKSTORAGE_TRANSLATE_URL LibreTranslate-compatible API base URL for translating AniList descriptions (empty)
BOOKSTORAGE_TRANSLATE_API_KEY API key for LibreTranslate (if the instance requires one) (empty)
BOOKSTORAGE_HTTP_READ_TIMEOUT_SEC Seconds to read the full request 15
BOOKSTORAGE_HTTP_WRITE_TIMEOUT_SEC Seconds until response must be fully written 120

Minimal production .env

BOOKSTORAGE_ENV=production
BOOKSTORAGE_HOST=0.0.0.0
BOOKSTORAGE_PORT=5000
BOOKSTORAGE_DATABASE=/opt/bookstorage/database.db
BOOKSTORAGE_SECRET_KEY=your-very-long-random-secret-key-at-least-32-chars
BOOKSTORAGE_SUPERADMIN_USERNAME=admin
BOOKSTORAGE_SUPERADMIN_PASSWORD=SecurePassword123!

Generate a strong secret key:

openssl rand -base64 48

Setting up .env

cp .env.example .env
chmod 600 .env

The .env file is loaded at startup. The binary also accepts a -c / --config flag to specify a custom path:

./bookstorage -c /etc/bookstorage/.env

PostgreSQL (alternative to SQLite)

BookStorage supports PostgreSQL as an alternative database backend via the BOOKSTORAGE_POSTGRES_URL variable.

BOOKSTORAGE_POSTGRES_URL=postgresql://bookstorage:secret@192.168.1.117:5432/bookstorage?sslmode=disable

When this variable is set, BOOKSTORAGE_DATABASE is ignored. The driver is lib/pq and accepts sslmode values: disable, require, verify-ca, verify-full (not prefer).

Migrating from SQLite to PostgreSQL

An existing SQLite database can be migrated to PostgreSQL through the admin panel:

  1. Navigate to Admin > PostgreSQL (requires superadmin)
  2. Enter the PostgreSQL connection URL
  3. Click Test to verify connectivity
  4. Click Migrate to transfer all data

The migration writes BOOKSTORAGE_POSTGRES_URL into the .env file. The process user must have write access to that file (see Troubleshooting if you get permission denied).


Google OAuth

To enable Sign in with Google:

  1. Go to Google Cloud Console and create OAuth 2.0 credentials (type Web application)
  2. Add an authorized redirect URI: {BOOKSTORAGE_PUBLIC_ORIGIN}/auth/google/callback
  3. Set the three environment variables:
BOOKSTORAGE_PUBLIC_ORIGIN=https://books.example.com
BOOKSTORAGE_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
BOOKSTORAGE_GOOGLE_CLIENT_SECRET=your-client-secret

Scopes used: openid, email, profile.

In production (BOOKSTORAGE_ENV=production), BOOKSTORAGE_PUBLIC_ORIGIN must use https.

Users can link/unlink their Google account from the Profile page. Unlinking requires having a local password set.


Session lifetime

Sessions use a sliding TTL of 2 hours and an absolute TTL of 24 hours.

  • If a user is inactive for more than 2 hours, they must log in again.
  • Regardless of activity, every session expires 24 hours after creation.

Session tokens are stored as SHA-256 hashes in the database. Cookies are set with HttpOnly, SameSite, and Secure (in production) flags.

See Authentication and Security for the full authentication and session model.


Legal notice (site.json)

To customize the /legal page:

cp config/site.json.example config/site.json

Edit config/site.json:

{
  "site_name": "BookStorage",
  "site_url": "https://your-domain.com",
  "legal": {
    "owner_name": "Your Name",
    "owner_email": "contact@example.com",
    "owner_address": "Your Address",
    "hosting_provider": "Hosting Provider Name",
    "hosting_address": "Hosting Address",
    "data_retention": "Data retention policy...",
    "data_usage": "How data is used...",
    "custom_sections": []
  }
}

Prometheus metrics

BookStorage exposes GET /metrics in Prometheus text format with counters and histograms prefixed bookstorage_http_*.

Scenario Access control
No BOOKSTORAGE_METRICS_TOKEN Only loopback clients (127.0.0.1 / ::1) may scrape /metrics
With BOOKSTORAGE_METRICS_TOKEN Send Authorization: Bearer <token> or GET /metrics?token=<token>

Minimal Prometheus scrape_configs:

scrape_configs:
  - job_name: bookstorage
    metrics_path: /metrics
    scheme: http
    bearer_token_file: /etc/bookstorage/bookstorage-metrics.token
    static_configs:
      - targets: ['127.0.0.1:5000']

The Admin > Monitoring page shows an embedded summary (scrape health, request counter, 5-minute rate) by querying the Prometheus HTTP API via BOOKSTORAGE_PROMETHEUS_QUERY_URL.


LibreTranslate integration

When BOOKSTORAGE_TRANSLATE_URL points to a LibreTranslate-compatible service, AniList recommendation descriptions are translated to French for users with the French UI. Translations are cached in the translation_cache table.

BOOKSTORAGE_TRANSLATE_URL=https://libretranslate.com
BOOKSTORAGE_TRANSLATE_API_KEY=your-api-key

Usage — Next: learn how to use BookStorage day to day.

Clone this wiki locally