Installation
Librariarr runs as a Docker container. The recommended setup uses Docker Compose with a PostgreSQL database.
Requirements
Section titled “Requirements”- Docker and Docker Compose v2+
- A Plex, Jellyfin, or Emby media server
Quick Start
Section titled “Quick Start”-
Create a
docker-compose.ymlCreate a directory for Librariarr and add the following
docker-compose.yml:docker-compose.yml services:librariarr:image: ahembree/librariarr:latestcontainer_name: librariarrports:- "${LIBRARIARR_PORT:-3000}:3000"environment:- DATABASE_URL=postgresql://librariarr:${DB_PASSWORD}@librariarr-db:5432/librariarr- SESSION_SECRET=${SESSION_SECRET:-}- TZ=${TZ:-UTC}- PUID=${PUID:-1000}- PGID=${PGID:-1000}volumes:- ./config:/confighealthcheck:test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]interval: 30stimeout: 5sstart_period: 60sretries: 3depends_on:librariarr-db:condition: service_healthyrestart: unless-stoppedlibrariarr-db:image: postgres:18-alpinecontainer_name: librariarr-dbenvironment:POSTGRES_USER: librariarrPOSTGRES_PASSWORD: ${DB_PASSWORD}POSTGRES_DB: librariarrvolumes:- librariarr-db:/var/lib/postgresqlhealthcheck:test: ["CMD-SHELL", "pg_isready -U librariarr"]interval: 5stimeout: 5sretries: 5restart: unless-stoppedvolumes:librariarr-db: -
Create a
.envfile.env # Required — database passwordDB_PASSWORD=your-secure-db-password# Optional — session encryption key (auto-generated if not set)# SESSION_SECRET=your-random-secret-here# OptionalPUID=1000PGID=1000LIBRARIARR_PORT=3000 -
Start the stack
Terminal window docker compose up -d -
Open the app
Navigate to
http://your-server:3000. You’ll be directed to the login page where you can sign in with Plex or create local credentials.
Environment Variables
Section titled “Environment Variables”| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | Yes | — | PostgreSQL connection URL (provided in the docker-compose.yml above) |
SESSION_SECRET | No | Auto-generated | Random string (32+ characters) used to secure your login sessions. Auto-generated and saved to /config/.session-secret if not set. |
PUID | No | 1000 | User ID for file permissions |
PGID | No | 1000 | Group ID for file permissions |
UMASK | No | 022 | File permission mask. Override only if your environment requires different permissions. |
LIBRARIARR_PORT | No | 3000 | Host port to expose |
TZ | No | UTC | Timezone for scheduled jobs (e.g., America/New_York) — full list |
NEXT_TELEMETRY_DISABLED | No | 1 | Always set to 1 by the container. Next.js telemetry is permanently disabled. |
LOG_DEBUG | No | false | Enable debug-level logging |
BACKUP_DIR | No | /config/backups | Backup storage directory |
IMAGE_CACHE_DIR | No | /config/cache/images | Artwork cache directory |
PREROLL_ALLOWED_PATHS | No | /media,/data,/mnt,/opt/prerolls | Comma-separated list of allowed directory prefixes for preroll file validation |
Persistent Data
Section titled “Persistent Data”All persistent data is stored under /config inside the container:
/config/backups/— Backup files (override withBACKUP_DIR)/config/cache/images/— Cached artwork (override withIMAGE_CACHE_DIR)- Database — All configuration, rules, and media metadata is stored in PostgreSQL
Using an Existing PostgreSQL Database
Section titled “Using an Existing PostgreSQL Database”If you already have a PostgreSQL server (e.g., a shared instance on your network or a managed database), you can skip the librariarr-db container and point Librariarr directly at it.
Database Requirements
Section titled “Database Requirements”- PostgreSQL 14 or later (17+ recommended)
- A dedicated database for Librariarr (the app manages its own schema)
- A user with full privileges on that database (
CREATE,ALTER,DROP,INSERT,UPDATE,DELETE) - No PostgreSQL extensions are required
-
Create the database and user on your PostgreSQL server:
CREATE USER librariarr WITH PASSWORD 'your-secure-password';CREATE DATABASE librariarr OWNER librariarr; -
Use a simplified
docker-compose.ymlwithout the database service:docker-compose.yml services:librariarr:image: ahembree/librariarr:latestcontainer_name: librariarrports:- "${LIBRARIARR_PORT:-3000}:3000"environment:- DATABASE_URL=postgresql://librariarr:${DB_PASSWORD}@your-db-host:5432/librariarr- SESSION_SECRET=${SESSION_SECRET:-}- TZ=${TZ:-UTC}- PUID=${PUID:-1000}- PGID=${PGID:-1000}volumes:- ./config:/confighealthcheck:test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]interval: 30stimeout: 5sstart_period: 60sretries: 3restart: unless-stopped -
Update your
.envfile with the database password and hostname:.env DB_PASSWORD=your-secure-passwordAdjust the
DATABASE_URLindocker-compose.ymlto match your PostgreSQL server’s hostname, port, and credentials. -
Start the container:
Terminal window docker compose up -d
Docker Networking
Section titled “Docker Networking”By default, Docker Compose creates an isolated network for the Librariarr stack. This works well when you access media servers and integrations (Sonarr, Radarr, etc.) via their host IP addresses. However, if your other services are also running in Docker, you can connect them on a shared network so they can communicate by container name instead.
Connecting to existing containers
Section titled “Connecting to existing containers”If your media server or Arr apps run in separate Docker Compose stacks, create an external network that all stacks share:
docker network create mediaThen reference it in each stack. For Librariarr:
services: librariarr: image: ahembree/librariarr:latest container_name: librariarr ports: - "${LIBRARIARR_PORT:-3000}:3000" environment: - DATABASE_URL=postgresql://librariarr:${DB_PASSWORD}@librariarr-db:5432/librariarr - SESSION_SECRET=${SESSION_SECRET:-} - TZ=${TZ:-UTC} - PUID=${PUID:-1000} - PGID=${PGID:-1000} volumes: - ./config:/config networks: - default - media healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 30s timeout: 5s start_period: 60s retries: 3 depends_on: librariarr-db: condition: service_healthy restart: unless-stopped
librariarr-db: image: postgres:18-alpine container_name: librariarr-db environment: POSTGRES_USER: librariarr POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: librariarr volumes: - librariarr-db:/var/lib/postgresql healthcheck: test: ["CMD-SHELL", "pg_isready -U librariarr"] interval: 5s timeout: 5s retries: 5 restart: unless-stopped
networks: default: media: external: true
volumes: librariarr-db:Add the same media network to your other stacks (Plex, Sonarr, Radarr, etc.):
services: sonarr: # ... existing config ... networks: - default - media
networks: default: media: external: trueOnce all containers are on the media network, you can reference them by container name when adding servers and integrations in Librariarr (e.g., http://plex:32400, http://sonarr:8989).
Startup Behavior
Section titled “Startup Behavior”On every container start, Librariarr:
- Checks database connectivity (retries up to 30 times)
- Runs any pending database updates automatically
- Starts the web server on port 3000
If database updates fail, the container uses a fallback method to ensure the database is current.
Updating
Section titled “Updating”To update to the latest version:
docker compose pulldocker compose up -dDatabase updates run automatically on startup — no manual steps needed.
Next Steps
Section titled “Next Steps”- Configure your instance — authentication, schedules, and general settings
- Connect a server — add your Plex, Jellyfin, or Emby server
- Security hardening — optional Docker security settings for hardened deployments