Framewrk
← Back

Installing Framewrk

One container, one folder for its database, port 8770. Everything else is set up in the console after it starts — there is nothing to configure first.

Pick your platform. Each section ends with the thing that actually catches people out there.

Before you start, you need a PhotoPrism instance Framewrk can reach, and an Aura and/or Nixplay account with at least one frame on it.

After it starts, on every platform: open http://<host>:8770, find the one-time admin password in the container log, sign in, and choose your own password when asked.


Linux

mkdir framewrk && cd framewrk
curl -O https://raw.githubusercontent.com/smichalczyk/framewrk/main/compose.yaml

Set PUID and PGID in compose.yaml to your own user, and TZ to your timezone:

id -u    # -> PUID
id -g    # -> PGID

Then:

docker compose up -d
docker compose logs | grep -A2 "Admin password"

Reaching PhotoPrism. If PhotoPrism is a container on the same host, put both on one network and address it by name (http://photoprism:2342) rather than a LAN address that can change. Uncomment the networks block at the bottom of compose.yaml. If Framewrk still cannot see it, network_mode: host usually settles it — Linux only, and it ignores ports, so the console lands on the host’s 8770 directly.

The catch: leave PUID/PGID unset and everything in data/ ends up owned by root. It works, right up until the day you want to read your own backup.


macOS

Needs Docker Desktop or Colima.

mkdir framewrk && cd framewrk
curl -O https://raw.githubusercontent.com/smichalczyk/framewrk/main/compose.yaml

Delete the PUID and PGID lines. Docker Desktop’s VM maps ownership for you, and setting them here causes the mismatch it is meant to prevent. Set TZ.

docker compose up -d
docker compose logs | grep -A2 "Admin password"

The catch: a Mac that sleeps stops syncing. Framewrk catches up on the next run rather than losing anything, but if the frames matter, run it somewhere that stays awake.


Windows

Needs Docker Desktop with the WSL 2 backend.

In PowerShell:

mkdir framewrk; cd framewrk
curl.exe -O https://raw.githubusercontent.com/smichalczyk/framewrk/main/compose.yaml

Delete the PUID and PGID lines, set TZ, and change the volume to a named volume:

    volumes:
      - framewrk-data:/data

volumes:
  framewrk-data:
docker compose up -d
docker compose logs | Select-String -Context 0,2 "Admin password"

The catch, and it is a real one: do not bind-mount a Windows path such as C:\Users\you\framewrk\data into /data. SQLite’s write-ahead log needs file locking that does not work reliably across the Windows/WSL filesystem bridge, and the failure does not look like a filesystem problem — it looks like a corrupted database, three weeks later. A named volume lives inside the Linux VM and has none of that. To get a backup out:

docker exec framewrk sqlite3 /data/sync.db ".backup /data/backup.db"
docker cp framewrk:/data/backup.db .

Synology

DSM 7.2 or newer, with Container Manager installed from Package Center.

1. Find your user’s numbers

This is the step everyone skips, and it is why most Synology support threads exist. Synology’s first user account is 1026, not 1000, and the primary group users is 100.

Enable SSH (Control Panel → Terminal & SNMP → Enable SSH service), then:

ssh you@your-nas
id
# uid=1026(you) gid=100(users) ...

Note both numbers and turn SSH back off if you had it off.

2. Make the folders

In File Station, inside the docker shared folder (Container Manager creates it), make framewrk, and inside that, data.

3. Create the project

Container Manager → Project → Create.

Paste this, with your two numbers and your timezone:

services:
  framewrk:
    image: ghcr.io/smichalczyk/framewrk:latest
    container_name: framewrk
    restart: unless-stopped
    ports:
      - "8770:8770"
    environment:
      - PUID=1026
      - PGID=100
      - TZ=Europe/London
    volumes:
      - /volume1/docker/framewrk/data:/data

Next → Next → Done. Container Manager pulls the image and starts it.

4. Sign in

Container Manager → Container → framewrk → Log, find the admin password, then open http://<nas-ip>:8770.

The catches:


QNAP

QTS or QuTS hero with Container Station 3.

1. Find your user’s numbers

Do not use admin — it is uid 0. Use a normal share user. Over SSH:

id your-user
# uid=1000(your-user) gid=100(everyone) ...

2. Make the folders

In File Station, inside the Container share (Container Station creates it), make framewrk, and inside that, data.

Check the real path in File Station’s properties — it is usually /share/Container/... but on some models /share/CACHEDEV1_DATA/Container/.... Getting this wrong silently creates an empty directory, and the database starts fresh on every boot.

3. Create the application

Container Station → Applications → Create. Name it framewrk and paste:

services:
  framewrk:
    image: ghcr.io/smichalczyk/framewrk:latest
    container_name: framewrk
    restart: unless-stopped
    ports:
      - "8770:8770"
    environment:
      - PUID=1000
      - PGID=100
      - TZ=Europe/London
    volumes:
      - /share/Container/framewrk/data:/data

Click Validate, then Create.

4. Sign in

Containers → framewrk → Logs for the password, then http://<nas-ip>:8770.

The catches:


Unraid

From Community Applications

Search Apps for Framewrk and install. The template fills in the port, the /data path, PUID, PGID and TZ for you — set your timezone and press Apply.

By hand

Docker → Add Container, then:

Field Value
Name framewrk
Repository ghcr.io/smichalczyk/framewrk:latest
Network Type bridge
WebUI http://[IP]:[PORT:8770]
Port container 8770 → host 8770
Path container /data → host /mnt/user/appdata/framewrk
Variable PUID = 99
Variable PGID = 100
Variable TZ = your timezone

Sign in

Click the container → Logs for the admin password, then the WebUI link.

The catch: 99/100 is Unraid’s nobody/users, which is what the rest of your appdata uses. Leaving them unset makes everything in the folder root-owned, and Unraid’s own backup plugins then cannot read it.


TrueNAS SCALE

24.10 (Electric Eel) or newer, where the apps engine is plain Docker.

1. Make a dataset

Storage → Datasets → select your pool → Add Dataset, named framewrk. Note the path it gives you, e.g. /mnt/tank/apps/framewrk.

Then Datasets → framewrk → Permissions → Edit: set Owner apps and Group apps (both UID/GID 568), and apply recursively.

2. Install

Apps → Discover Apps → the menu at the top right → Install via YAML.

services:
  framewrk:
    image: ghcr.io/smichalczyk/framewrk:latest
    container_name: framewrk
    restart: unless-stopped
    ports:
      - "8770:8770"
    environment:
      - PUID=568
      - PGID=568
      - TZ=America/New_York
    volumes:
      - /mnt/tank/apps/framewrk:/data

Save.

3. Sign in

Apps → Installed → framewrk → Logs for the password, then http://<truenas-ip>:8770.

The catches:


Something went wrong

Still stuck? Open a discussion with your platform, the version from Settings → About, and the relevant lines from Logs.