Skip to content

Installation

Librariarr runs as a Docker container. The recommended setup uses Docker Compose with a PostgreSQL database.

  • Docker and Docker Compose v2+
  • A Plex, Jellyfin, or Emby media server
  1. Create a docker-compose.yml

    Create a directory for Librariarr and add the following docker-compose.yml:

    docker-compose.yml
    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
    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
    volumes:
    librariarr-db:
  2. Create a .env file

    .env
    # Required — database password
    DB_PASSWORD=your-secure-db-password
    # Optional — session encryption key (auto-generated if not set)
    # SESSION_SECRET=your-random-secret-here
    # Optional
    PUID=1000
    PGID=1000
    LIBRARIARR_PORT=3000
  3. Start the stack

    Terminal window
    docker compose up -d
  4. 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.

VariableRequiredDefaultDescription
DATABASE_URLYesPostgreSQL connection URL (provided in the docker-compose.yml above)
SESSION_SECRETNoAuto-generatedRandom string (32+ characters) used to secure your login sessions. Auto-generated and saved to /config/.session-secret if not set.
PUIDNo1000User ID for file permissions
PGIDNo1000Group ID for file permissions
UMASKNo022File permission mask. Override only if your environment requires different permissions.
LIBRARIARR_PORTNo3000Host port to expose
TZNoUTCTimezone for scheduled jobs (e.g., America/New_York) — full list
NEXT_TELEMETRY_DISABLEDNo1Always set to 1 by the container. Next.js telemetry is permanently disabled.
LOG_DEBUGNofalseEnable debug-level logging
BACKUP_DIRNo/config/backupsBackup storage directory
IMAGE_CACHE_DIRNo/config/cache/imagesArtwork cache directory
PREROLL_ALLOWED_PATHSNo/media,/data,/mnt,/opt/prerollsComma-separated list of allowed directory prefixes for preroll file validation

All persistent data is stored under /config inside the container:

  • /config/backups/ — Backup files (override with BACKUP_DIR)
  • /config/cache/images/ — Cached artwork (override with IMAGE_CACHE_DIR)
  • Database — All configuration, rules, and media metadata is stored in PostgreSQL

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.

  • 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
  1. Create the database and user on your PostgreSQL server:

    CREATE USER librariarr WITH PASSWORD 'your-secure-password';
    CREATE DATABASE librariarr OWNER librariarr;
  2. Use a simplified docker-compose.yml without the database service:

    docker-compose.yml
    services:
    librariarr:
    image: ahembree/librariarr:latest
    container_name: librariarr
    ports:
    - "${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:/config
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
    interval: 30s
    timeout: 5s
    start_period: 60s
    retries: 3
    restart: unless-stopped
  3. Update your .env file with the database password and hostname:

    .env
    DB_PASSWORD=your-secure-password

    Adjust the DATABASE_URL in docker-compose.yml to match your PostgreSQL server’s hostname, port, and credentials.

  4. Start the container:

    Terminal window
    docker compose up -d

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.

If your media server or Arr apps run in separate Docker Compose stacks, create an external network that all stacks share:

Terminal window
docker network create media

Then reference it in each stack. For Librariarr:

docker-compose.yml
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.):

Other stack's docker-compose.yml (excerpt)
services:
sonarr:
# ... existing config ...
networks:
- default
- media
networks:
default:
media:
external: true

Once 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).

On every container start, Librariarr:

  1. Checks database connectivity (retries up to 30 times)
  2. Runs any pending database updates automatically
  3. Starts the web server on port 3000

If database updates fail, the container uses a fallback method to ensure the database is current.

To update to the latest version:

Terminal window
docker compose pull
docker compose up -d

Database updates run automatically on startup — no manual steps needed.