oCIS Gallery
Self hosted photo gallery backed by ownCloud Infinite Scale
- Category
- Photos & Videos, Selfhosting
- Available on
- Updated
- Oct 15, 2026
Preview
About this app
You already run your own cloud, and oCIS Gallery adds the photo app it’s been missing. It’s built for ownCloud Infinite Scale. Point it at any folders in your personal space, project spaces or shared folders. It turns every photo and video inside them, including subfolders, into a single timeline sorted by when each one was taken.
Browse a justified grid grouped by month, open anything full screen with its camera details, and organize with favorites and albums. Favorites use oCIS’s own favorite flag, so they show up in the Files app too. It runs as a web app inside your oCIS instance, with companion apps for iPhone, iPad and Apple TV. There’s no third-party cloud, no extra copy of your library and no subscription. Your photos stay on your server.
Install with an AI assistant
oCIS Gallery was built with AI help, and so was the Proxmox server it runs on. You can install it the same way. Pick the prompt below that matches how your oCIS runs, fill in the blanks at the top, and paste it into an AI assistant that can run commands on your server, such as Claude Code. It works through the install with you, step by step.
Each prompt covers three things:
- The web app:
gallery/from the zip goes into oCIS's apps directory. - App tokens: switch them on if they're off, and create one for the gallery owner.
- The thumbnail generator from the zip's
tools/gallery-thumbs/: it indexes your gallery folders, renders the thumbnails oCIS can't make, and runs on a schedule.
Before you start
- Download the zip above and put it on the machine the assistant will work on.
- Know the oCIS username whose photos the gallery shows. The generator runs as that account, never as an admin.
- Use an assistant that shows each command before it runs it, and read what it proposes. The prompts tell it to look before changing anything, back up what it edits, and ask before each change.
- Keep your app token out of the chat. It works like a password. The prompts have you run the token command yourself and paste the token straight into a config file.
- Only the Proxmox route has been tested on a real server. The others follow the same steps but haven't been run end to end yet.
oCIS in Docker / Docker Compose
For oCIS running from the owncloud/ocis image under Docker Compose (or plain
docker run). The thumbnail generator runs on the Docker host under systemd.
Run the assistant on the Docker host, as a user who can use docker and
sudo. Fill in the values at the top, then paste everything in the box.
You are helping me install oCIS Gallery on my own server. oCIS (ownCloud
Infinite Scale) runs in Docker. Work with me step by step.
My values:
- oCIS URL: <SERVER_URL>
- Gallery owner (the oCIS user whose photos it shows): <OWNER>
- Release zip, on this Docker host: <ZIP_PATH>
- Compose project directory: <PATH, or "find it">
How to work:
- Look before you change anything. Start with read-only commands, tell me what
you found, and get my OK before each change.
- Back up every file before you edit it, including compose files and .env
(copy it to <file>.bak-<date>).
- Never delete the existing gallery app directory, a volume, or any oCIS data.
Never run `docker compose down -v`.
- Never ask me to paste an app token into this chat, and never print one. Give
me the command to run myself, and tell me which file to paste the token into.
- The zip holds INSTALL.md, DEPLOY.md and tools/gallery-thumbs/README.md. Treat
them as the source of truth and read them before you start. If they disagree
with this prompt, follow them and tell me.
- Environment changes need the container recreated (`docker compose up -d`). A
plain `docker compose restart` keeps the old environment. Either one takes
oCIS offline briefly, so ask me first.
PART 1: The web app
1. Unzip <ZIP_PATH> into a new temporary folder and read the three docs above.
2. Find the oCIS container and its config: `docker ps`, then `docker compose
config` in the project directory, or `docker inspect <container>`. Report
WEB_ASSET_APPS_PATH, OCIS_BASE_DATA_PATH, and the volumes and bind mounts.
3. Work out where the apps directory lives on the host:
- If WEB_ASSET_APPS_PATH is set and bind-mounted from a host folder, use that
host folder as $APPS.
- If it's unset, the apps directory is $OCIS_BASE_DATA_PATH/web/assets/apps
inside the container. Find which host directory or named volume backs it.
- If nothing on the host backs it, propose the bind mount from INSTALL.md:
set WEB_ASSET_APPS_PATH=/web/apps and mount the host folder holding
gallery/ at /web/apps/gallery. Show me the compose diff before applying it.
4. Copy the app over the top, and match the owner:
sudo cp -r <unzipped>/gallery/. "$APPS/gallery/"
sudo chown -R --reference="$APPS" "$APPS/gallery"
"$APPS/gallery/manifest.json" must exist afterwards. Do not copy tools/ or
INSTALL.md into the apps directory.
5. On a first install only, oCIS needs one restart to list a new app. Use
`docker compose up -d` if you changed the compose file, otherwise `docker
compose restart ocis`. Ask first, then wait until the URL answers.
6. Verify:
curl -s <SERVER_URL>/assets/apps/gallery/index.js | grep -o 'version [0-9.]* (built [^)]*)'
Use /assets/apps/..., not /apps/... (that path answers 401, which is
normal). Then I'll log in, open Gallery from the app switcher, and in
Gallery → Settings choose the source folders and press "Save and rescan".
**The generator reads those folders, so I must do this before Part 3.**
If Gallery doesn't appear, check whether this server mounts an apps.yaml. If
it does, show me, and we'll decide whether to add `gallery: { config: {} }`.
PART 2: App tokens
7. Check whether app tokens are on: `curl -s -o /dev/null -w '%{http_code}'
<SERVER_URL>/auth-app/tokens`. 401 means on, 404 means off.
8. If they're off, add OCIS_ADD_RUN_SERVICES=auth-app and
PROXY_ENABLE_APP_AUTH=true to the oCIS service's environment, in the compose
file or its .env. If OCIS_ADD_RUN_SERVICES already has a value, add auth-app
to its comma-separated list. Show me the diff, recreate with `docker compose
up -d` (ask first), and repeat step 7.
9. Give me the command to mint a one-year token for <OWNER>. I'll run it
myself:
docker compose exec ocis ocis auth-app create --user-name <OWNER> --expiration 8760h
(Use the real service name.) Or I can mint it in the oCIS Gallery iPhone app
(Accounts → Apple TV sign-in). The token is shown once. I'll paste it
straight into the env file in step 12.
PART 3: The thumbnail generator
10. It runs on this Docker host, not inside the oCIS container. It needs
systemd, python3 3.10+ (standard library only) and ffmpeg. Check what's
installed and propose the packages. Check `ffmpeg -hide_banner -buildconf |
grep -i heif`; without libheif, HEIC files fail one by one, which is OK. If
this host has no systemd, tell me and use the cron setup in DEPLOY.md
instead of step 14.
11. Run the tests from the unzipped folder:
cd <unzipped>/tools/gallery-thumbs && python3 -m unittest test_gallery_thumbs
12. Create /etc/gallery-thumbs.env from gallery-thumbs.env.example (chmod 600,
root-owned). Fill in OCIS_SERVER and OCIS_USER=<OWNER>. Leave OCIS_TOKEN
for me to paste with an editor. For the memory guard, set GALLERY_CT_STAT to
the oCIS container's cgroup memory.stat, usually
/sys/fs/cgroup/system.slice/docker-<full container id>.scope/memory.stat
Find the real path, and confirm it exists and has an `anon` line.
Leave the other GALLERY_* values at their defaults unless you explain why.
Further accounts go in as OCIS_USER_2/OCIS_TOKEN_2 and so on, each with a
token minted as that account, and each having chosen folders first.
Note: a recreated container gets a new id, so GALLERY_CT_STAT has to be
updated after every `docker compose up -d` that recreates oCIS. Tell me
this in the summary.
13. First runs, one at a time, showing me the output of each. Use a memory cap,
and load the env file with `set -a; . /etc/gallery-thumbs.env; set +a`:
sudo systemd-run --scope -q -p MemoryMax=1G -p MemorySwapMax=0 <unzipped>/tools/gallery-thumbs/gallery_thumbs.py --check-tokens
... gallery_thumbs.py --dry-run
... gallery_thumbs.py --limit 50
After the --limit 50 run I'll check the gallery, then we schedule it.
14. Schedule it:
sudo sh <unzipped>/tools/gallery-thumbs/install-timers.sh check
sudo sh <unzipped>/tools/gallery-thumbs/install-timers.sh
This copies the scripts to /opt/gallery-thumbs. It installs an index job
(every 3 hours by default) and a nightly render job (00:30), and starts a
first index run. If the installer refuses a value, explain why. After the
first index run (`journalctl -u gallery-thumbs-index`), rerun the check.
Gallery → Settings should then say the index was used.
15. Skip the optional `--watch` service; the current apps don't send it scan
requests. Ask me whether I use the oCIS Gallery Apple TV app. If I do, read
"Videos the Apple TV cannot play" in the generator README and offer
`--transcode`.
FINISH
16. Look at "Keeping the server healthy" in INSTALL.md: GOMEMLIMIT under the
container's memory limit, NATS memory sizing in containers, swap, log
rotation. Tell me which apply here, with the exact compose change for each.
**Suggest only; don't change anything without my OK.**
17. Summarize what you installed, every file you changed and its backup, and
how to pause the generator (`sh install-timers.sh pause`), upgrade (copy
gallery/ over the top, no restart; rerun install-timers.sh) and uninstall.
oCIS on Kubernetes (Helm)
For oCIS deployed to Kubernetes, typically with the ownCloud Helm chart. The author has not tested this route. The scheduling script that ships with the generator assumes systemd, so this prompt runs the generator as two CronJobs instead, and the assistant has to adapt more of the setup to your cluster.
Run the assistant on a machine with kubectl and helm access to the cluster.
Fill in the values at the top, then paste everything in the box.
You are helping me install oCIS Gallery on my own oCIS, which runs on
Kubernetes. Work with me step by step. This route hasn't been tested by the
gallery's author, so say so whenever you're making a judgment call.
My values:
- oCIS URL: <SERVER_URL>
- Gallery owner (the oCIS user whose photos it shows): <OWNER>
- Release zip, on this machine: <ZIP_PATH>
- Namespace and Helm release: <NAMESPACE> / <RELEASE, or "find it">
How to work:
- Look before you change anything. Start with read-only commands (get, describe,
`helm get values`), tell me what you found, and get my OK before each change.
- Save the current Helm values (`helm get values -o yaml > values.bak-<date>.yaml`)
before any upgrade, and show me every values diff before applying it.
- Never delete PVCs, PVs or oCIS data, and never uninstall the release.
- Never ask me to paste an app token into this chat, and never print one. Put
tokens in a Kubernetes Secret, which I'll create with a command you give me.
- The zip holds INSTALL.md, DEPLOY.md and tools/gallery-thumbs/README.md. Treat
them as the source of truth and read them before you start. If they disagree
with this prompt, follow them and tell me.
PART 1: The web app
1. Unzip <ZIP_PATH> into a new temporary folder and read the three docs above.
2. Inspect the deployment: `helm get values`, the web/proxy pods, their env
(WEB_ASSET_APPS_PATH, OCIS_BASE_DATA_PATH), and their volumes. Check the
chart's own values for web apps or extensions; recent charts may have a
supported way to add one. Prefer that if it exists.
3. Otherwise, plan with me how to put the gallery/ folder (manifest.json +
index.js) at $WEB_ASSET_APPS_PATH/gallery inside the pod that serves web
assets. Options:
- a PVC mounted at WEB_ASSET_APPS_PATH, filled with `kubectl cp`, or
- an initContainer that copies the files in from a ConfigMap or image.
The files must survive pod restarts, and upgrades copy over the top without
deleting first. Show me the values diff.
4. Apply with `helm upgrade` (ask first). Then verify:
curl -s <SERVER_URL>/assets/apps/gallery/index.js | grep -o 'version [0-9.]* (built [^)]*)'
Use /assets/apps/..., not /apps/... (that path answers 401, which is
normal). Then I'll log in, open Gallery, and in Gallery → Settings choose the
source folders and press "Save and rescan". **The generator reads those
folders, so I must do this before Part 3.**
PART 2: App tokens
5. Check whether app tokens are on: `curl -s -o /dev/null -w '%{http_code}'
<SERVER_URL>/auth-app/tokens`. 401 means on, 404 means off.
6. If they're off, the auth-app service has to run and the proxy needs
PROXY_ENABLE_APP_AUTH=true. Find how this chart enables the auth-app service
(an auth-app service toggle, or OCIS_ADD_RUN_SERVICES in a single-binary
setup), and show me the values diff. Then upgrade (ask first) and repeat
step 5.
7. Give me the command to mint a one-year token for <OWNER>. I'll run it
myself:
kubectl -n <NAMESPACE> exec <a pod with the ocis binary> -- ocis auth-app create --user-name <OWNER> --expiration 8760h
Or I can mint it in the oCIS Gallery iPhone app (Accounts → Apple TV
sign-in). Then give me the `kubectl create secret generic gallery-thumbs
--from-literal=OCIS_TOKEN=...` command to run myself, so the token never
passes through you.
PART 3: The thumbnail generator, as CronJobs
8. Read tools/gallery-thumbs/README.md and gallery-thumbs.env.example in full.
The generator is one stdlib-only Python file (python3 3.10+) and calls
ffmpeg.
9. Propose an image with python3 and ffmpeg (HEIC needs ffmpeg built with
libheif). Either a small one I build and push, or a public image I approve.
Ship gallery_thumbs.py into it, or mount it from a ConfigMap.
10. Write the manifests, and show them to me before applying anything:
- A ConfigMap with OCIS_SERVER, OCIS_USER=<OWNER>, GALLERY_INDEX_INTERVAL
matching the index schedule, and GALLERY_LIMIT=1500.
- The Secret from step 7 for OCIS_TOKEN.
- A small PVC mounted as STATE_DIRECTORY. The generator keeps its state
there, so unchanged files aren't re-uploaded every run.
- CronJob "index": `gallery_thumbs.py --index-only`, every 3 hours.
- CronJob "render": `gallery_thumbs.py --plan-from-json`, nightly at a time
that doesn't overlap the index run.
- On both: concurrencyPolicy: Forbid, a memory limit (start at 1Gi for the
index and 3Gi for the render job), activeDeadlineSeconds just under the
interval for the index job, and no swap.
The systemd memory guard (GALLERY_CT_STAT) can't reach the oCIS pod's
cgroup from here, so it stays off. GALLERY_LIMIT and oCIS's own memory limit
are what protect the server. Say this in the summary.
Further accounts go in as OCIS_USER_2 / OCIS_TOKEN_2 and so on, each with
its own token and having chosen folders first.
11. Before scheduling, run one-off Jobs from the same template and show me each
log: `--check-tokens`, then `--dry-run`, then `--limit 50`. I'll check the
gallery after the last one.
12. Apply the CronJobs (ask first). After the first index run, compare its walk
time with the interval: the interval should be at least 1.25× the walk.
Gallery → Settings should then say the index was used.
13. Skip the optional `--watch` mode; the current apps don't send it scan
requests. Ask me whether I use the oCIS Gallery Apple TV app. If I do, read
"Videos the Apple TV cannot play" in the README and offer `--transcode`.
FINISH
14. Look at "Keeping the server healthy" in INSTALL.md: GOMEMLIMIT against the
pods' memory limits, NATS memory sizing, log retention. Tell me which apply,
with the exact values change. **Suggest only; don't change anything without
my OK.**
15. Summarize what you created and changed, where the backups are, and how to
pause the generator (`kubectl patch cronjob ... suspend: true`), upgrade
(new files over the top; a new script in the image or ConfigMap) and remove
it.
oCIS on a Linux server or VM (systemd)
For oCIS installed directly on a Linux server or VM, either the ocis binary or
a distribution package, running as a systemd service. The thumbnail generator
runs on the same machine.
Run the assistant on the oCIS server, as a user with sudo. Fill in the
values at the top, then paste everything in the box.
You are helping me install oCIS Gallery on my own server. oCIS (ownCloud
Infinite Scale) runs directly on this Linux machine as a systemd service. Work
with me step by step.
My values:
- oCIS URL: <SERVER_URL>
- Gallery owner (the oCIS user whose photos it shows): <OWNER>
- Release zip, on this server: <ZIP_PATH>
How to work:
- Look before you change anything. Start with read-only commands, tell me what
you found, and get my OK before each change.
- Back up every config file before you edit it (copy it to <file>.bak-<date>).
- Never delete the existing gallery app directory or any oCIS data. Upgrades
copy over the top.
- Never ask me to paste an app token into this chat, and never print one. Give
me the command to run myself, and tell me which file to paste the token into.
- The zip holds INSTALL.md, DEPLOY.md and tools/gallery-thumbs/README.md. Treat
them as the source of truth and read them before you start. If they disagree
with this prompt, follow them and tell me.
- Restarting oCIS takes it offline briefly. Ask me before any restart.
PART 1: The web app
1. Unzip <ZIP_PATH> into a new temporary folder and read the three docs above.
2. Find the oCIS service and its environment: `systemctl cat ocis` (or
whatever the unit is called), its EnvironmentFile (often /etc/ocis/ocis.env),
and any ocis.yaml. Report WEB_ASSET_APPS_PATH and OCIS_BASE_DATA_PATH, and
the user the service runs as.
3. The apps directory is WEB_ASSET_APPS_PATH if that's set, otherwise
$OCIS_BASE_DATA_PATH/web/assets/apps, usually /var/lib/ocis/web/assets/apps.
Show me `ls -ld` of it.
4. Copy the app over the top, and match the owner:
sudo cp -r <unzipped>/gallery/. "$APPS/gallery/"
sudo chown -R --reference="$APPS" "$APPS/gallery"
"$APPS/gallery/manifest.json" must exist afterwards. Do not copy tools/ or
INSTALL.md into the apps directory.
5. On a first install only, oCIS needs one restart to list a new app. Ask me
first. Then run `sudo systemctl restart ocis`, and wait until the URL
answers.
6. Verify:
curl -s <SERVER_URL>/assets/apps/gallery/index.js | grep -o 'version [0-9.]* (built [^)]*)'
Use /assets/apps/..., not /apps/... (that path answers 401, which is
normal). Then I'll log in, open Gallery from the app switcher, and in
Gallery → Settings choose the source folders and press "Save and rescan".
**The generator reads those folders, so I must do this before Part 3.**
If Gallery doesn't appear, check whether this server keeps an apps.yaml
(often /etc/ocis/apps.yaml). If it does, show me, and we'll decide whether
to add `gallery: { config: {} }`.
PART 2: App tokens
7. Check whether app tokens are on: `curl -s -o /dev/null -w '%{http_code}'
<SERVER_URL>/auth-app/tokens`. 401 means on, 404 means off.
8. If they're off, add OCIS_ADD_RUN_SERVICES=auth-app and
PROXY_ENABLE_APP_AUTH=true to the service's EnvironmentFile. If
OCIS_ADD_RUN_SERVICES already has a value, add auth-app to its
comma-separated list. Show me the diff, restart (ask first), and repeat
step 7.
9. Give me the command to mint a one-year token for <OWNER>. I'll run it
myself, as the oCIS service user and with the service's environment, e.g.:
sudo -u <service user> sh -c 'set -a; . /etc/ocis/ocis.env; set +a; ocis auth-app create --user-name <OWNER> --expiration 8760h'
Adjust this to the real env file and user. Or I can mint it in the oCIS
Gallery iPhone app (Accounts → Apple TV sign-in). The token is shown once.
I'll paste it straight into the env file in step 12.
PART 3: The thumbnail generator
10. It runs on this machine. It needs python3 3.10+ (standard library only) and
ffmpeg. Check what's installed and propose the packages. Check `ffmpeg
-hide_banner -buildconf | grep -i heif`; without libheif, HEIC files fail
one by one, which is OK.
11. Run the tests from the unzipped folder:
cd <unzipped>/tools/gallery-thumbs && python3 -m unittest test_gallery_thumbs
12. Create /etc/gallery-thumbs.env from gallery-thumbs.env.example (chmod 600,
root-owned). Fill in OCIS_SERVER and OCIS_USER=<OWNER>. Leave OCIS_TOKEN
for me to paste with an editor. For the memory guard, set GALLERY_CT_STAT to
the oCIS service's cgroup memory.stat, usually
/sys/fs/cgroup/system.slice/ocis.service/memory.stat
Confirm it exists and has an `anon` line.
Leave the other GALLERY_* values at their defaults unless you explain why.
Further accounts go in as OCIS_USER_2/OCIS_TOKEN_2 and so on, each with a
token minted as that account, and each having chosen folders first.
13. First runs, one at a time, showing me the output of each. Use a memory cap,
and load the env file with `set -a; . /etc/gallery-thumbs.env; set +a`:
sudo systemd-run --scope -q -p MemoryMax=1G -p MemorySwapMax=0 <unzipped>/tools/gallery-thumbs/gallery_thumbs.py --check-tokens
... gallery_thumbs.py --dry-run
... gallery_thumbs.py --limit 50
After the --limit 50 run I'll check the gallery, then we schedule it.
14. Schedule it:
sudo sh <unzipped>/tools/gallery-thumbs/install-timers.sh check
sudo sh <unzipped>/tools/gallery-thumbs/install-timers.sh
This copies the scripts to /opt/gallery-thumbs. It installs an index job
(every 3 hours by default) and a nightly render job (00:30), and starts a
first index run. If the installer refuses a value, explain why. After the
first index run (`journalctl -u gallery-thumbs-index`), rerun the check.
Gallery → Settings should then say the index was used.
15. Skip the optional `--watch` service; the current apps don't send it scan
requests. Ask me whether I use the oCIS Gallery Apple TV app. If I do, read
"Videos the Apple TV cannot play" in the generator README and offer
`--transcode`.
FINISH
16. Look at "Keeping the server healthy" in INSTALL.md: GOMEMLIMIT (with a
MemoryMax on the oCIS unit), swap, log rotation. Tell me which apply here,
with the exact change for each. **Suggest only; don't change anything
without my OK.**
17. Summarize what you installed, every file you changed and its backup, and
how to pause the generator (`sh install-timers.sh pause`), upgrade (copy
gallery/ over the top, no restart; rerun install-timers.sh) and uninstall.
oCIS in a Proxmox VE container
For oCIS running in a Proxmox VE container. That covers an OCI-image
application container (Proxmox VE 9.1+ running the owncloud/ocis image) and
a classic system container (a Debian or Alpine CT with the ocis binary
inside). This is how the author's production server runs: an OCI container,
with the thumbnail generator on the Proxmox host.
Run the assistant on the Proxmox host as root, or over SSH to it. Fill in the three values at the top, then paste everything in the box.
You are helping me install oCIS Gallery on my own server. oCIS (ownCloud
Infinite Scale) runs in a Proxmox VE container. Work with me step by step.
My values:
- oCIS URL: <SERVER_URL>
- Gallery owner (the oCIS user whose photos it shows): <OWNER>
- Release zip, on this Proxmox host: <ZIP_PATH>
- Container ID: <CTID, or "find it">
How to work:
- Look before you change anything. Start with read-only commands, tell me what
you found, and get my OK before each change.
- Back up every config file before you edit it (copy it to <file>.bak-<date>).
- Never delete the existing gallery app directory or any oCIS data. Upgrades
copy over the top.
- Never ask me to paste an app token into this chat, and never print one. Give
me the command to run myself, and tell me which file to paste the token into.
- The zip holds INSTALL.md, DEPLOY.md and tools/gallery-thumbs/README.md. Treat
them as the source of truth and read them before you start. If they disagree
with this prompt, follow them and tell me.
- Restarting the container takes oCIS offline for a few minutes. A large
install can take minutes to answer again after a cold start. Ask me before
any restart.
PART 1: The web app
1. Unzip <ZIP_PATH> into a new temporary folder and read the three docs above.
2. Find the container. Use `pct list` and `pct config <CTID>`, and tell me
whether it's an OCI-image application container or a classic system
container, and whether it's privileged or unprivileged.
3. Find oCIS's environment. For an OCI container, look at the
`lxc.environment.runtime:` lines in /etc/pve/lxc/<CTID>.conf. Otherwise use
`pct exec <CTID> -- cat /proc/1/environ | tr '\0' '\n'` or the oCIS service's
env file inside the CT. Note WEB_ASSET_APPS_PATH and OCIS_BASE_DATA_PATH. If
WEB_ASSET_APPS_PATH is unset, the apps directory is
$OCIS_BASE_DATA_PATH/web/assets/apps. oCIS's default base is
/var/lib/ocis, but OCI images often use another path, so check.
4. Map that path inside the container to a path on the host. Use the CT's
rootfs or mount points from `pct config`, e.g. a ZFS subvolume such as
/<pool>/subvol-<CTID>-disk-0/... Confirm it with `ls -ld`, and show me the
directory and its owner. In an unprivileged CT the owner is a shifted id such
as 101000.
5. Copy the app over the top, and match the owner:
cp -r <unzipped>/gallery/. "$APPS/gallery/"
chown -R --reference="$APPS" "$APPS/gallery"
"$APPS/gallery/manifest.json" must exist afterwards. Do not copy tools/ or
INSTALL.md into the apps directory.
6. On a first install only, oCIS needs one restart to list a new app. Ask me
first. Then use `pct shutdown <CTID> --timeout 90 && pct start <CTID>`, and
wait until the oCIS URL answers.
7. Verify:
curl -s <SERVER_URL>/assets/apps/gallery/index.js | grep -o 'version [0-9.]* (built [^)]*)'
Use /assets/apps/..., not /apps/... (that path answers 401, which is
normal). Then I'll log in, open Gallery from the app switcher, and in
Gallery → Settings choose the source folders and press "Save and rescan".
**The generator reads those folders, so I must do this before Part 3.**
If Gallery doesn't appear after a restart, check whether this server keeps
an apps.yaml. If it does, show me, and we'll decide whether to add
`gallery: { config: {} }`.
PART 2: App tokens
8. Check whether app tokens are on: `curl -s -o /dev/null -w '%{http_code}'
<SERVER_URL>/auth-app/tokens`. 401 means on, 404 means off.
9. If they're off, oCIS needs OCIS_ADD_RUN_SERVICES=auth-app and
PROXY_ENABLE_APP_AUTH=true. If OCIS_ADD_RUN_SERVICES already has a value, add
auth-app to its comma-separated list instead of replacing it.
- OCI container: back up /etc/pve/lxc/<CTID>.conf, then append raw
`lxc.environment.runtime: NAME=value` lines. **Do not use
`pct set --env`.** It replaces the whole environment set, and would wipe
oCIS's existing variables.
- Classic container: add the variables wherever the oCIS service gets its
environment inside the CT.
Then restart (ask first) and repeat step 8 until it returns 401.
10. Give me the command to mint a one-year token for <OWNER>. I'll run it
myself:
pct exec <CTID> -- ocis auth-app create --user-name <OWNER> --expiration 8760h
If the CLI complains about missing configuration, it needs the server's
environment. Help me run it with that environment, or I can mint the token
in the oCIS Gallery iPhone app (Accounts → Apple TV sign-in), which also
sets a label. The token is shown once. I'll paste it straight into the env
file in step 13.
PART 3: The thumbnail generator
11. Decide with me where it runs. The default is **this Proxmox host**. Its
memory guard can only watch the container's cgroup from here, and it needs
no inbound network access. The alternative is a small separate Debian
container that can reach <SERVER_URL> over HTTPS. Either way it needs
systemd, python3 3.10+ (standard library only) and ffmpeg. Check
`ffmpeg -hide_banner -buildconf | grep -i heif`; without libheif, HEIC files
fail one by one, which is OK.
Installing packages on the hypervisor is my call. Ask me first.
12. Run the tests from the unzipped folder:
cd <unzipped>/tools/gallery-thumbs && python3 -m unittest test_gallery_thumbs
13. Create /etc/gallery-thumbs.env from gallery-thumbs.env.example (chmod 600,
root-owned). Fill in OCIS_SERVER and OCIS_USER=<OWNER>. Leave OCIS_TOKEN
for me to paste with an editor. Also set:
GALLERY_CT_STAT=/sys/fs/cgroup/lxc/<CTID>/memory.stat
Confirm that file exists and has an `anon` line. This turns on the guard
that stops a render pass if oCIS's memory runs away.
Leave the other GALLERY_* values at their defaults unless you explain why.
Further accounts go in as OCIS_USER_2/OCIS_TOKEN_2 and so on, each with a
token minted as that account, and each having chosen folders in Settings
first.
14. First runs, one at a time, showing me the output of each. Use a memory cap,
and load the env file with `set -a; . /etc/gallery-thumbs.env; set +a`:
systemd-run --scope -q -p MemoryMax=1G -p MemorySwapMax=0 <unzipped>/tools/gallery-thumbs/gallery_thumbs.py --check-tokens
... gallery_thumbs.py --dry-run
... gallery_thumbs.py --limit 50
After the --limit 50 run I'll check the gallery, then we schedule it.
15. Schedule it:
sh <unzipped>/tools/gallery-thumbs/install-timers.sh check
sh <unzipped>/tools/gallery-thumbs/install-timers.sh
This copies the scripts to /opt/gallery-thumbs. It installs an index job
(every 3 hours by default) and a nightly render job (00:30), and starts a
first index run. The installer refuses unsafe schedules; if it does, explain
why. After the first index run finishes (`journalctl -u
gallery-thumbs-index`), rerun `install-timers.sh check`, because it sizes
the schedule from the measured walk time. Gallery → Settings should then say
the index was used.
16. Skip the optional `--watch` service; the current apps don't send it scan
requests. Ask me whether I use the oCIS Gallery Apple TV app. If I do, read
"Videos the Apple TV cannot play" in the generator README and offer
`--transcode`.
FINISH
17. Look at the oCIS health advice in INSTALL.md ("Keeping the server
healthy"): GOMEMLIMIT, NATS memory sizing in containers, swap, log
rotation. Tell me which apply to this container, with the exact change for
each. **Suggest only; don't change anything without my OK.**
18. Summarize what you installed, every file you changed and its backup, and
how to pause the generator (`sh install-timers.sh pause`), upgrade (copy
gallery/ over the top, no restart; rerun install-timers.sh) and uninstall.
