ContentsInstall with Docker
  1. Getting started

    1. What Kryspal Media is
    2. System requirements
    3. Install with Docker
    4. First-time setup
    5. Upgrade and back up
  2. Libraries

    1. Create and manage libraries
    2. File and folder naming
    3. Flexible file layout
    4. Metadata and NFO
    5. Tags
    6. Images
    7. strm and cloud drives
    8. StrmTool settings
    9. Subtitles
    10. Intro and outro
    11. Search tips
    12. Actors and people
    13. Duplicate videos
  3. Playback

    1. Web player
    2. Third-party players
    3. Remote access
  4. Members and devices

    1. Members
    2. Parental controls
    3. Devices and simultaneous streams
  5. Plugins

    1. Plugin center
    2. Plugins
    3. Third-party plugins
  6. Move from another server

    1. Move from Emby
    2. Move from Jellyfin
  7. Licenses and plans

    1. Compare plans
    2. PRO features in detail
    3. MAX features in detail
    4. Buy, activate and move a license
    5. Offline grace and expiry
  8. Troubleshooting

    1. Logs and reporting a problem

Install with Docker

Kryspal Media runs as two containers, the server and its PostgreSQL database, started with one Docker Compose file. The images support x86 (amd64) and ARM (arm64).

On this page
  1. Before you start
  2. Install with one command (Linux host or VPS)
  3. Install on a NAS with Docker Compose
  4. Ports, folders and data
  5. Extras you can add
  6. Use your own PostgreSQL
  7. Automated deployments
  8. The server keeps restarting and the log says "the data directory does not match this database"
  9. Next

Before you start#

  • Docker and Docker Compose v2 are installed.
  • You know where your media lives on the host (for example /volume1/movies).

Install with one command (Linux host or VPS)#

For a Linux machine or VPS that already has Docker. The script writes the compose file, starts it and waits until the server is healthy. Replace /srv/media with the folder that holds your movies and series:

curl -fsSL https://media.kryspal.net/install.sh | bash -s -- --media /srv/media

Run the same command again to upgrade; see Upgrade and back up.

  • Read the script first. Download it, read it, then run it:

    curl -fsSL https://media.kryspal.net/install.sh -o install.sh
    less install.sh
    bash install.sh --media /srv/media
    
  • More than one media folder. Repeat --media, for example --media /volume1/movies --media /volume2/tv. One folder is mounted at /media; with several, each is mounted at /media plus its full path, such as /media/volume1/movies. To keep other container paths, see Media outside /media.

    curl -fsSL https://media.kryspal.net/install.sh | bash -s -- \
      --media /volume1/movies \
      --media /volume2/tv
    

On an upgrade --media is ignored; to change the folders, edit compose.yaml. - Where things are. The compose file and a small .env are in /opt/kryspal-media (change it with --dir). The data is in the Docker volumes kryspal-media_data, kryspal-media_pgdata and kryspal-media_db. - If Docker is missing, the script stops and says where to get it. --install-docker lets it use Docker's official installer; --no-pull is for an offline host. - What an upgrade does. It pulls the newest images and recreates the containers, and never deletes your data. Your compose.yaml stays as it is; if a new version changes it, the new file is saved next to it as compose.yaml.new. - Outside access. The port speaks plain HTTP, so put a reverse proxy with HTTPS in front of it and never forward port 5797. See Remote access. - Not for a NAS. A project made from the command line is not shown in a NAS container manager. Use Docker Compose there.

Install on a NAS with Docker Compose#

Use this on Synology, QNAP and other NAS systems, where you create a project by pasting compose YAML into the container manager. Any other host with Docker can use it too.

  1. Create a folder, and in it a file named compose.yaml with this content (in a NAS container manager, paste it where it asks for the compose file):

    services:
      server:
        image: kryspal/kryspalmedia:latest
        restart: unless-stopped
        stop_grace_period: 60s
        ports:
          - "5797:5797" # LAN
          - "5798:5798" # WAN
          # - "7359:7359/udp" # discovery
        environment:
          EXTERNAL_HTTP_ADDR: ":5798" # WAN
        volumes:
          - /path/to/media:/media
          # 2+ folders: use these instead
          # - /mnt/movies:/media/mnt/movies
          # - /mnt/tv:/media/mnt/tv
          - data:/var/lib/mediaserver
          - db:/var/lib/kryspal-db:ro
        depends_on:
          - postgres
      postgres:
        image: kryspal/kryspalmedia-postgres:16
        restart: unless-stopped
        stop_grace_period: 60s
        volumes:
          - pgdata:/var/lib/postgresql/data
          - db:/var/lib/kryspal-db
    volumes:
      data:
      pgdata:
      db:
    
  2. Replace /path/to/media with your media folder on the host. For more than one folder, add one volumes line per folder, mounted under /media plus its full path, for example - /mnt/tv:/media/mnt/tv. A folder mounted outside /media is refused by the server.

  3. Start it (in a NAS container manager, create and start the project):

    docker compose up -d
    
  4. Open http://<host>:5797 and follow the setup wizard to create the first administrator. See First-time setup. The admin console is at http://<host>:5797/web/.

  5. In your player (Infuse and others), enter the server address http://<host>:5797 and a member account.

NAS with file ACLs (UGREEN, Synology and similar). The server runs as user mediaserver (uid and gid 1000) inside the container. On these systems the permission shown by ls is not the whole story: access is decided by the NAS's own ACL, which is often granted to a group such as admin, not to gid 1000. The symptom is "library root unavailable: … permission denied" (the library shows as offline) although the folder looks open to everyone. The one-line installer checks this for you: it tries each media folder with a throw-away read-only container and, when a folder cannot be read, adds the first group of your user that works as group_add in compose.yaml. With your own compose file, add the group that can read your media to the server service, then run docker compose up -d again:

    group_add:
      - "10"   # the gid from `id -g` of the user that can read the files

To make the media folder completely read-only, add :ro to its line; subtitle download, NFO and image write-back, and deleting files then cannot work.

To upgrade, run docker compose pull and docker compose up -d. The database structure is upgraded automatically on first start; on a large library this can take a minute or two. See Upgrade and back up.

Ports, folders and data#

Automatic discovery. Emby and Jellyfin use 7359/udp too, so the compose file leaves this line commented out. install.sh turns it on when the port is free.

To let players find the server by themselves:

  1. Make sure Emby or Jellyfin is not using 7359/udp.
  2. Remove the # in front of the 7359:7359/udp line in the compose file.
  3. Recreate the container.

Players can always type the server address instead.

What Details
HTTP port 5797. Players, the Kryspal web player and the admin console all use it.
Outside-access port 5798. Forward only this one on your router; connections that arrive here always count as outside your network.
Discovery port 7359 (UDP), off by default in the compose file. Lets players on your local network find the server. See below.
Server data The data volume (/var/lib/mediaserver): keys, settings, uploaded images, installed plugins, and the image cache (thumbnails and pre-generated posters; the cache is rebuilt if you delete it). Back it up.
Database The pgdata volume in the database container. Items, members, watch history.
Database password The db volume. The password is generated automatically on first start and shared between the two containers; you never type it.
Database port 5432 is not published to the host. Only the Docker network can reach it.
Media Mounted at /media inside the container (the example mounts /path/to/media). With several folders from the install script, each one is at /media plus its full path, for example /media/volume1/movies. When you create a library in the admin console, enter the path as the container sees it, for example /media/Movies. Your media folders are read-only by default; Kryspal writes to them or deletes files in them only when you turn on subtitle download, write-back (NFO and images) or Allow deletion on a library.

The database is not reachable from outside, and its password is generated for you.

Extras you can add#

  • Access from outside your network. The compose file already publishes port 5798 (WAN) and sets EXTERNAL_HTTP_ADDR: ":5798". Forward only 5798 on your router. Everything that arrives on this port counts as outside your network. We do not use 8920 because it clashes with Emby's HTTPS port when both run on one machine.
  • NAS file permissions. If your NAS uses file ACLs (for example Synology), add user: "<uid>:<gid>" to the server, using the owner of your media files (id -u and id -g).
  • A bigger database memory setting. On a host with plenty of memory you can add a command: to the postgres service to raise PostgreSQL's memory settings.

Use your own PostgreSQL#

You need PostgreSQL 16 or newer with the pg_bigm extension, which the Chinese search uses. Create a database and a user for Kryspal Media, remove the postgres service, the pgdata and db volumes, and the server's depends_on and db volume line, then add an environment: section to the server with DATABASE_URL set to your own connection string, for example postgres://user:password@db.example:5432/kryspal?sslmode=disable. The server creates its tables on first start. An account with enough privileges must run CREATE EXTENSION pg_bigm beforehand.

Automated deployments#

If you deploy by script and do not want the wizard, add INITIAL_ADMIN_PASSWORD to the server's environment: section. When the database has no members yet, the server creates the administrator at startup and the setup wizard is skipped. If you leave it out, the wizard runs.

The server keeps restarting and the log says "the data directory does not match this database"#

At start-up the server checks that the server identity and keys in the data volume are the same ones the database has on record. If they differ, it refuses to start, the container restarts over and over, and the log shows this line: the data directory does not match this database.

  1. First check that the data volume is mounted. The most common cause is a NAS that mounts an external or network disk later than the container starts, so the server sees an empty folder. Once the disk is mounted, restart the container: docker compose restart server.
  2. Only if you changed the keys or the data folder on purpose, accept the change: add ACCEPT_DATA_DIR_CHANGE: "true" to the server's environment: section and start it once. After it starts successfully, remove that line.

Next#