Compare commits

...
47 Commits
Author SHA1 Message Date
Worph 6af22d72d7 Pin meta-watch 1.2.2 (MetaWatch, MetaWatchShared): restore hand-picked subtitle per file, auto-arm online result, no-subtitles notice (#819) 2026-11-04 16:22:55 +00:00
Worph cbbfdd6503 Pin meta-watch 1.2.1 (MetaWatch, MetaWatchShared): subtitle search starts with playback (#820) 2026-11-04 15:54:04 +00:00
Worph 21bdcef56b Pin meta-read 1.5.1 (MetaRead, MetaReadShared): forget a work from the Library wall 2026-11-04 15:40:39 +00:00
Worph ac9036d848 Pin meta-core 2.1.0.1, meta-watch 1.2.0.2, meta-read 1.5.0.1 (report inbox); MetaRead apps get META_CORE_URL 2026-11-04 12:30:40 +00:00
Manielle 29c3c516e1 Pin meta-read 1.4.2.1 (SVG covers, reader and phone fixes, reading positions as of capture) 2026-10-27 22:53:43 +01:00
Worph 7517eaab58 Pin meta-read 1.4.2 (MetaRead, MetaReadShared): phone layout on the claims line 2026-10-27 19:50:10 +00:00
Worph fcd0a9703b meta-core claims model: pin meta-core 2.0.1, meta-read 1.4.1, meta-watch 1.1.0, meta-search 1.3.2, meta-share 2.7.0, gateway 1.1.1, meta-sort 1.1.1, plugins 1.1.0; signing keys + db-cache backup exclude 2026-10-27 19:08:14 +00:00
Manielle 26929835d3 Pin meta-read 1.3.9.2 2026-10-27 19:47:06 +01:00
Manielle 8f87a59c98 Pin meta-read 1.3.9.1 2026-10-27 19:10:52 +01:00
Worph e36abaa72a route on the ip zone (APP_IP_ZONE) instead of nip.io 2026-10-27 16:37:43 +00:00
Manielle c9aa19c56f Pin meta-read 1.3.8 and meta-feeder-torznab 1.0.45 2026-10-25 18:00:03 +01:00
Manielle ff3fe134ba bump meta-read 1.3.7.1 (MetaRead, MetaReadShared): titles cut at ' / ' and ignore 'bk N' / 'book N' 2026-10-24 23:41:44 +02:00
Manielle e1885e511b bump meta-read 1.3.7 (MetaRead, MetaReadShared): grouping independent of arrival order, book pages find every copy 2026-10-24 19:48:18 +02:00
Manielle 1cc88c8079 bump meta-read 1.3.6 (MetaRead, MetaReadShared): files of one book group across spellings and accents, books classed by language, MOBI recognised 2026-10-24 18:02:55 +02:00
Manielle e55a013fc0 bump meta-feeder-torznab 1.0.44 (MetaFeederProwlarr): Title - Author with a two-word author on the right reads the credit last 2026-10-24 18:00:39 +02:00
Manielle 33dcd08527 bump meta-read 1.3.5 (MetaRead, MetaReadShared): one tile per book with Anna's Archive first, paged EPUB with tap turns, format sniffing, release-named shell cache 2026-10-24 16:29:06 +02:00
Manielle 0c8ccdf28a bump meta-read 1.3.4 (MetaRead, MetaReadShared): the reader waits out a 503 while a book's bytes arrive, says so, and stops when closed 2026-10-24 00:58:55 +02:00
Manielle 5234d0c27f bump meta-feeder-torznab 1.0.43 (MetaFeederProwlarr): books inside a pack read their own credit 2026-10-23 22:30:28 +02:00
Manielle 089a659e1f bump meta-feeder-torznab 1.0.42 (MetaFeederProwlarr): scene-style ebook names, full test suite green 2026-10-23 21:55:14 +02:00
Manielle 705f340cd0 bump meta-feeder-torznab 1.0.41 (MetaFeederProwlarr): reads Title - Author, Title by Author and Author [Series] Title ebook names 2026-10-23 21:18:00 +02:00
Manielle 1b64345cae bump meta-feeder-torznab 1.0.40 (MetaFeederProwlarr): ebook releases carry author, year, format and language 2026-10-22 22:26:24 +02:00
Manielle 4eb554f9fe bump meta-read 1.3.3 (MetaRead, MetaReadShared): swipe to turn, same-title cards, touch and keyboard polish, cover fetch limit 2026-10-22 21:04:42 +02:00
Manielle 79c9b35bff bump meta-read 1.3.2 (MetaRead, MetaReadShared): security hardening, per-profile sign-out, reader fixes 2026-10-22 19:28:00 +02:00
Manielle d35a6e2098 bump meta-read 1.3.1 (MetaRead, MetaReadShared); profiles are created in MetaWatch on the shared app, invite-gated locally on the standalone one 2026-10-21 19:48:34 +02:00
Worph 8147f1c927 MetaCore: mem_limit 8g/6g -> 1g (SQLite store idles ~70-160 MB, 568 MB peak) 2026-10-19 21:59:38 +00:00
Worph ace786c219 MetaCore 1.2.0: no-op write skip, schema counters, snapshot replay 2026-10-19 21:42:13 +00:00
Worph f0cb8a4ed0 MetaCore 1.1.0: Redis replaced by embedded SQLite 2026-10-19 20:51:38 +00:00
Worph 235b1a7264 MetaFeederSuwayomi 1.1.0 for the stock Suwayomi app (port 80, login on the config page); meta-share 2.6.4, meta-transport-ipfs 1.3.4 2026-10-19 20:09:17 +00:00
Manielle 479f53850b bump meta-read 1.2.3 (MetaRead, MetaReadShared) 2026-10-19 18:53:35 +00:00
Manielle 1662e4ea04 bump meta-read 1.2.1 (MetaRead, MetaReadShared) 2026-10-19 18:10:06 +00:00
Manielle 8c98785e38 serve assets and the store archive from gitea-watch (the GitHub repo is gone)
github.com/Worph/MetaAppStore answers 404, and with it every jsDelivr
cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/ URL: the icons, thumbnails and
screenshots of all 44 apps were missing from the store listing, and the store
source in the README no longer downloaded.

- Asset URLs in every Apps/*/docker-compose.yml now point at
  https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/{AppName}/
  (103 of the 109 distinct URLs checked: 200 image/png). The other 6, MetaGateway
  and MetaWatch screenshot-1..3, name files that have never been in this repo.
- README: the store source is https://gitea-watch.nsl.sh/metastar/MetaAppStore/archive/main.zip
  (public, checked to download anonymously).
- CLAUDE.md and CONTRIBUTING.md: the asset rule and its grep guard follow, so an
  import cannot bring back a jsDelivr URL unnoticed.
2026-10-19 16:06:27 +00:00
Manielle 051cc588ad bump meta-read 1.2.0 (MetaRead, MetaReadShared) 2026-10-19 15:49:06 +00:00
Worph 220e892583 bump meta-read 1.1.1 (MetaRead, MetaReadShared) 2026-10-19 11:31:06 +00:00
Worph 74d4a51548 MetaWatch, MetaWatchShared: meta-watch 1.0.93 (#766 keep offline queue + Offline & storage settings, Save file through the offline store) 2026-10-18 14:29:24 +00:00
Worph c34ef3134e MetaWatch, MetaWatchShared: meta-watch 1.0.89 (#822 int64 duration wrap) 2026-10-18 11:11:59 +00:00
Worph df3a989683 MetaWatch, MetaWatchShared: meta-watch 1.0.88 (#809 genre lookup 400, #821 SourceBuffer backpressure) 2026-10-17 16:04:11 +00:00
Worph 7dbd8e8a31 images from IPCR (ipcr-watch.nsl.sh/ipns/metadec.eth) at the first gitea-built releases 2026-10-13 13:56:53 +00:00
Worph 7d934d85f1 MetaFeederStremio: pin 1.3.0 (CI-published build of the live/* + release-facts feeder) 2026-10-12 15:01:58 +00:00
Worph bf98f5e1e7 MetaFeederProwlarr: pin torznab 1.0.37 (the live/* + release-facts build; 1.0.36 was retagged) 2026-10-12 13:51:35 +00:00
Worph 22d45bbf9a bump meta-gateway 1.0.42, meta-search 1.2.9, torznab 1.0.36, stremio 1.2.0, tribler 1.0.8 (live/* transient fields, release facts) 2026-10-12 13:32:57 +00:00
Worph a976c001fa MetaFeederStremio: bump to 1.1.0 (AIOStreams structured metadata) 2026-10-12 12:17:41 +00:00
Worph fb958ebd79 MetaTransportNzb: pin meta-transport-nzb 1.4.0 (disk admission, failed jobs discard scratch) 2026-10-12 12:15:23 +00:00
Worph 0072954c35 MetaWatch, MetaWatchShared: meta-watch 1.0.85 (#744 dead source errors out behind Cloudflare) 2026-10-11 13:46:13 +00:00
Worph 945b891308 app 2026-10-11 15:08:11 +02:00
Worph 8b58d9bdc8 MetaWatch, MetaWatchShared: meta-watch 1.0.83 (#801 Play best decode-first, #744 dead source errors out) 2026-10-11 13:05:51 +00:00
Worph d0b9e48a66 add MetaFeederStremio (meta-feeder-stremio 1.0.0) 2026-10-11 12:54:54 +00:00
Worph bfdf2cb849 bump meta-search 1.2.8, meta-watch 1.0.81 (MetaWatch, MetaWatchShared, MetaRead, MetaReadShared) 2026-10-10 18:59:11 +00:00
55 changed files with 1096 additions and 315 deletions
+43 -32
View File
@@ -5,23 +5,20 @@ services:
# Public ingress goes through the `metacore` hash-lock proxy below — this
# service has no public Caddy labels and no exposed host ports.
metacore-app:
image: ghcr.io/worph/meta-core:1.0.23
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core:2.1.0.1
container_name: metacore-app
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
# instead of swap. Both values must move together or swap comes back.
#
# Raised 768m -> 1536m (2026-08-26): on watch.nsl.sh the Redis working set
# ran at 73-97% of 768m, i.e. one indexing burst away from an OOM kill that
# takes the record store (and every service reading it) down with it.
# 1536m puts steady state near 30%.
#
# Raised 1536m -> 6g (2026-09-30): the record index costs ~40 KB of RAM per
# record, and watch.nsl.sh's working set reached 4.8 GiB (tens of
# thousands of records). A cap is a ceiling, not a reservation — a small
# library still uses a few hundred MB — so a generous one costs nothing
# until the library grows into it.
mem_limit: 6g
memswap_limit: 6g
# Lowered to 1g (2026-10-19, meta-core 1.2.0). The store is an embedded
# SQLite file now (no Redis, no in-memory search copy): on watch.nsl.sh,
# 169k records, meta-core idles at ~70-160 MB and peaked at 568 MB during
# a full counter rebuild (POST /api/schema/rescan) — the heaviest operation
# it has. Page cache for the database file is charged here too but is
# reclaimable. History: 768m → 1536m (Redis working set) → 6g → 8g (the
# Redis-era in-memory index, ~30 KB/record, OOM-killed repeatedly).
mem_limit: 1g
memswap_limit: 1g
hostname: metacore-app
restart: unless-stopped
privileged: true
@@ -31,7 +28,10 @@ services:
- 80
volumes:
# Shared infrastructure state (leader election, Redis dump, service discovery).
# Shared infrastructure state: the metadata store (db/meta-core.db, SQLite),
# the leader lock, identity and mounts. Since meta-core 2.0.0 also
# db-cache/cache.db: every index/derived table, rebuilt from db/ on
# demand — so it is excluded from backups (see x-compose-app.backup).
# Lives inside /DATA/AppData/metacore/ so CasaOS archives it on uninstall.
- ${DATA_ROOT:-/DATA}/AppData/metacore/meta-core:/meta-core:rw
@@ -48,7 +48,7 @@ services:
# `filePath` points into it. This MUST be a bind mount: without it the
# directory is the container's writable layer, so any `docker compose
# up -d` that recreates metacore-app silently deletes every poster while
# Redis keeps pointing at them. That is exactly what happened on
# the records keep pointing at them. That is exactly what happened on
# watch.nsl.sh on 2026-08-03 (270 files → 0), and it is the reason a
# fraction of poster CIDs 404 with a healthy-looking record behind them.
# metacore-app is the only service that mounts /files; the gateway and
@@ -65,7 +65,7 @@ services:
- BASE_URL=https://metacore-$APP_DOMAIN
- TZ=$TZ
# Runs as root for nginx, Redis, rclone mounts
# Runs as root for nginx and rclone mounts
user: 0:0
healthcheck:
@@ -101,7 +101,7 @@ services:
BACKEND_HOST: "metacore-app"
BACKEND_PORT: "80"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metacore-app
@@ -120,8 +120,8 @@ services:
caddy_0.1_handle: ""
caddy_0.1_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metacore-IP.nip.io (gateway TLS) ----
caddy_1: metacore-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metacore-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metacore-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metacore-app:80"
@@ -155,15 +155,15 @@ x-casaos:
en_us: |
**The infrastructure foundation for the MetaMesh media management ecosystem.**
MetaCore provides the shared services that power all MetaMesh applications: distributed leader election, Redis database, WebDAV file serving, remote mount management, and service discovery.
MetaCore provides the shared services that power all MetaMesh applications: distributed leader election, embedded SQLite database, WebDAV file serving, remote mount management, and service discovery.
**Key Features:**
- **Leader Election** - Automatic flock-based leader election with failover support
- **Redis Database** - Centralized metadata storage for all MetaMesh services
- **SQLite Database** - Centralized metadata storage for all MetaMesh services: a backed-up truth file plus a rebuildable index cache
- **WebDAV File Serving** - Cached file access for all services via HTTP
- **Mount Management** - Add NFS, SMB, and rclone remote mounts from the dashboard
- **File Watcher** - Monitors folders and notifies services of new files
- **Metadata Editor** - Browse and edit file metadata stored in Redis
- **Metadata Editor** - Browse and edit file metadata stored in SQLite
- **Service Discovery** - Automatic registration and discovery of MetaMesh services
- **OIDC Single Sign-On** - Dashboard protected by Yundera's built-in Authelia (auto-registered, no secrets to configure)
@@ -174,33 +174,33 @@ x-casaos:
fr_fr: |
**La fondation d'infrastructure pour l'ecosysteme de gestion de medias MetaMesh.**
MetaCore fournit les services partages qui alimentent toutes les applications MetaMesh : election de leader distribuee, base de donnees Redis, service de fichiers WebDAV, gestion de montages distants et decouverte de services.
MetaCore fournit les services partages qui alimentent toutes les applications MetaMesh : election de leader distribuee, base de donnees SQLite embarquee, service de fichiers WebDAV, gestion de montages distants et decouverte de services.
**Fonctionnalites Cles:**
- **Election de Leader** - Election automatique basee sur flock avec support de basculement
- **Base de Donnees Redis** - Stockage centralise des metadonnees pour tous les services
- **Base de Donnees SQLite** - Stockage centralise des metadonnees pour tous les services : un fichier de verite sauvegarde et un cache d'index reconstructible
- **Service de Fichiers WebDAV** - Acces aux fichiers en cache via HTTP
- **Gestion des Montages** - Ajout de montages NFS, SMB et rclone depuis le tableau de bord
- **Surveillance de Fichiers** - Surveille les dossiers et notifie les services des nouveaux fichiers
- **Editeur de Metadonnees** - Parcourir et editer les metadonnees stockees dans Redis
- **Editeur de Metadonnees** - Parcourir et editer les metadonnees stockees dans SQLite
- **Decouverte de Services** - Enregistrement et decouverte automatiques des services
- **SSO OIDC** - Tableau de bord protege par l'Authelia integre de Yundera (auto-enregistre, aucun secret a configurer)
**Installez ceci EN PREMIER** avant MetaSort, MetaFuse ou MetaStremio.
tagline:
en_us: MetaMesh infrastructure - Leader election, Redis, WebDAV, and service discovery
fr_fr: Infrastructure MetaMesh - Election de leader, Redis, WebDAV et decouverte de services
en_us: MetaMesh infrastructure - Leader election, SQLite, WebDAV, and service discovery
fr_fr: Infrastructure MetaMesh - Election de leader, SQLite, WebDAV et decouverte de services
title:
en_us: MetaCore
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaCore/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaCore/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaCore/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaCore/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaCore/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaCore/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaCore/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaCore/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaCore/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaCore/thumbnail.png
index: /
store_app_id: metacore
@@ -239,6 +239,11 @@ x-compose-app:
- path: /DATA/AppData/metacore/meta-core
user: $PUID
group: $PGID
# meta-core 2.0.0 rebuildable index cache (META_CORE_CACHE_PATH default
# /meta-core/db-cache/cache.db). Excluded from backups below.
- path: /DATA/AppData/metacore/meta-core/db-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metacore/cache
user: $PUID
group: $PGID
@@ -248,6 +253,12 @@ x-compose-app:
- path: /DATA/AppData/metacore/plugin/share
user: $PUID
group: $PGID
# The index cache is derived data: meta-core rebuilds it from db/meta-core.db
# (the truth file, which IS backed up) when it is missing or stale. Never
# back it up — a restore brings it back empty and it repopulates on boot.
backup:
exclude:
- meta-core/db-cache/
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metacore-${domain}
webui-path: "/"
+4 -4
View File
@@ -2,7 +2,7 @@
# Authelia Configuration for MetaMesh (OIDC provider mode)
#
# Template — MetaCore/pre-install-cmd substitutes the placeholders below at
# install time: APP_DOMAIN, APP_PUBLIC_IP_DASH, HMAC secret, RSA JWKS private
# install time: APP_DOMAIN, APP_PUBLIC_IP_DASH, APP_IP_ZONE, HMAC secret, RSA JWKS private
# key, and one argon2id hash per OIDC client.
#
# Protected apps reach Authelia via OIDC (not forward_auth) so each app's
@@ -81,7 +81,7 @@ __OIDC_JWKS_KEY__
require_pkce: false
redirect_uris:
- 'https://metacore-__AUTH_DOMAIN__/oauth2/callback'
- 'https://metacore-__APP_PUBLIC_IP_DASH__.nip.io/oauth2/callback'
- 'https://metacore-__APP_PUBLIC_IP_DASH__.__APP_IP_ZONE__/oauth2/callback'
- 'https://metacore-__APP_PUBLIC_IP_DASH__.sslip.io/oauth2/callback'
scopes:
- 'openid'
@@ -104,7 +104,7 @@ __OIDC_JWKS_KEY__
require_pkce: false
redirect_uris:
- 'https://metasort-__AUTH_DOMAIN__/oauth2/callback'
- 'https://metasort-__APP_PUBLIC_IP_DASH__.nip.io/oauth2/callback'
- 'https://metasort-__APP_PUBLIC_IP_DASH__.__APP_IP_ZONE__/oauth2/callback'
- 'https://metasort-__APP_PUBLIC_IP_DASH__.sslip.io/oauth2/callback'
scopes:
- 'openid'
@@ -127,7 +127,7 @@ __OIDC_JWKS_KEY__
require_pkce: false
redirect_uris:
- 'https://metafuse-__AUTH_DOMAIN__/oauth2/callback'
- 'https://metafuse-__APP_PUBLIC_IP_DASH__.nip.io/oauth2/callback'
- 'https://metafuse-__APP_PUBLIC_IP_DASH__.__APP_IP_ZONE__/oauth2/callback'
- 'https://metafuse-__APP_PUBLIC_IP_DASH__.sslip.io/oauth2/callback'
scopes:
- 'openid'
+3 -3
View File
@@ -24,7 +24,7 @@ services:
# are its ids, cover, synopsis, reading direction, author." Keyless.
# ---------------------------------------------------------------------------
metafeederanilist-feeder:
image: ghcr.io/worph/meta-feeder-anilist:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-anilist:1.0.5
cpu_shares: 30
container_name: metafeederanilist-feeder
mem_limit: 256m
@@ -90,8 +90,8 @@ x-casaos:
title:
en_us: MetaFeeder · AniList
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederAniList/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederAniList/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederAniList/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederAniList/thumbnail.png
store_app_id: metafeederanilist
is_uncontrolled: false
+3 -3
View File
@@ -22,7 +22,7 @@ services:
# metafeederarxiv-feeder — the arxiv feeder. Keyless; no config needed.
# ---------------------------------------------------------------------------
metafeederarxiv-feeder:
image: ghcr.io/worph/meta-feeder-arxiv:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-arxiv:1.0.4
cpu_shares: 30
container_name: metafeederarxiv-feeder
hostname: metafeederarxiv-feeder
@@ -78,8 +78,8 @@ x-casaos:
title:
en_us: MetaFeeder · arXiv
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederArxiv/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederArxiv/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederArxiv/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederArxiv/thumbnail.png
store_app_id: metafeederarxiv
is_uncontrolled: false
+3 -3
View File
@@ -22,7 +22,7 @@ services:
# metafeedereuropepmc-feeder — the europepmc feeder (upstream `pubmed`). Keyless.
# ---------------------------------------------------------------------------
metafeedereuropepmc-feeder:
image: ghcr.io/worph/meta-feeder-europepmc:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-europepmc:1.0.3
cpu_shares: 30
container_name: metafeedereuropepmc-feeder
hostname: metafeedereuropepmc-feeder
@@ -79,8 +79,8 @@ x-casaos:
title:
en_us: MetaFeeder · Europe PMC
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederEuropePMC/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederEuropePMC/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederEuropePMC/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederEuropePMC/thumbnail.png
store_app_id: metafeedereuropepmc
is_uncontrolled: false
+3 -3
View File
@@ -21,7 +21,7 @@ services:
# metafeedergiphy-feeder — the giphy feeder. Needs a Giphy API key.
# ---------------------------------------------------------------------------
metafeedergiphy-feeder:
image: ghcr.io/worph/meta-feeder-giphy:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-giphy:1.0.2
cpu_shares: 30
container_name: metafeedergiphy-feeder
hostname: metafeedergiphy-feeder
@@ -81,8 +81,8 @@ x-casaos:
title:
en_us: MetaFeeder · Giphy
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederGiphy/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederGiphy/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederGiphy/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederGiphy/thumbnail.png
store_app_id: metafeedergiphy
is_uncontrolled: false
+3 -3
View File
@@ -16,7 +16,7 @@ services:
# for discovery/query; it returns records (no meta-core, no enrichment).
# ---------------------------------------------------------------------------
metafeedergutenberg-feeder:
image: ghcr.io/worph/meta-feeder-gutenberg:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-gutenberg:1.0.5
cpu_shares: 30
container_name: metafeedergutenberg-feeder
hostname: metafeedergutenberg-feeder
@@ -78,8 +78,8 @@ x-casaos:
title:
en_us: MetaFeeder · Gutenberg
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederGutenberg/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederGutenberg/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederGutenberg/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederGutenberg/thumbnail.png
store_app_id: metafeedergutenberg
is_uncontrolled: false
@@ -26,7 +26,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeederinternetarchive-feeder:
image: ghcr.io/worph/meta-feeder-internetarchive:1.1.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-internetarchive:1.1.4
cpu_shares: 30
container_name: metafeederinternetarchive-feeder
# Bytes tier: a single archive item can list hundreds of files and one
@@ -93,8 +93,8 @@ x-casaos:
title:
en_us: MetaFeeder · Internet Archive
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederInternetArchive/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederInternetArchive/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederInternetArchive/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederInternetArchive/thumbnail.png
store_app_id: metafeederinternetarchive
is_uncontrolled: false
+3 -3
View File
@@ -27,7 +27,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeederjamendo-feeder:
image: ghcr.io/worph/meta-feeder-jamendo:1.1.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-jamendo:1.1.4
cpu_shares: 30
container_name: metafeederjamendo-feeder
# Bytes tier: one mp32 derivative is buffered whole before hand-off.
@@ -99,8 +99,8 @@ x-casaos:
title:
en_us: MetaFeeder · Jamendo
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederJamendo/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederJamendo/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederJamendo/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederJamendo/thumbnail.png
store_app_id: metafeederjamendo
is_uncontrolled: false
@@ -29,7 +29,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeedermusicbrainz-feeder:
image: ghcr.io/worph/meta-feeder-musicbrainz:1.1.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-musicbrainz:1.1.4
cpu_shares: 30
container_name: metafeedermusicbrainz-feeder
# Identity tier: JSON in, cards out, nothing buffered. Swap disabled
@@ -100,8 +100,8 @@ x-casaos:
title:
en_us: MetaFeeder · MusicBrainz
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederMusicBrainz/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederMusicBrainz/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederMusicBrainz/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederMusicBrainz/thumbnail.png
store_app_id: metafeedermusicbrainz
is_uncontrolled: false
@@ -39,7 +39,7 @@ services:
# for discovery/query; the human configures it from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeederopensubtitles-feeder:
image: ghcr.io/worph/meta-feeder-opensubtitles:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-opensubtitles:1.0.4
cpu_shares: 30
container_name: metafeederopensubtitles-feeder
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of
@@ -151,8 +151,8 @@ x-casaos:
title:
en_us: MetaFeeder · OpenSubtitles
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederOpenSubtitles/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederOpenSubtitles/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederOpenSubtitles/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederOpenSubtitles/thumbnail.png
store_app_id: metafeederopensubtitles
is_uncontrolled: false
+24 -5
View File
@@ -40,7 +40,7 @@ services:
# package, published as ${{ github.repository }}) was renamed. The old
# `meta-feeder-indexer` package still exists but is frozen at 1.0.23 and
# receives no further pushes. The APP keeps the `metafeederprowlarr` name.
image: ghcr.io/worph/meta-feeder-torznab:1.0.35
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-torznab:1.1.0
cpu_shares: 30
container_name: metafeederprowlarr-feeder
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -76,10 +76,15 @@ services:
# was dropped — its 500 did match the default.
META_GATEWAY_PROWLARR_PAGE_SIZE: "20"
TZ: "$TZ"
# Own claim-signing key (self-published records); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeederprowlarr-feeder.key"
volumes:
# Persist feeder config (config.json saved via the config UI) + redb cache.
# Transient librqbit downloads go to the container's /tmp (off backup).
- ${DATA_ROOT:-/DATA}/AppData/metafeederprowlarr/state:/data/meta-feeder:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeederprowlarr/keys:/keys:rw
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
interval: 5s
@@ -102,7 +107,7 @@ services:
# No healthcheck: these plugin images don't ship one (curl absent).
# ---------------------------------------------------------------------------
metafeederprowlarr-filename-parser:
image: ghcr.io/worph/metamesh-plugin-filename-parser:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-filename-parser:1.1.0
cpu_shares: 30
container_name: metafeederprowlarr-filename-parser
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -118,11 +123,17 @@ services:
# (meta-sort's Scan card) sees it as bound elsewhere, never addable.
BEACON_BINDS: "metafeederprowlarr-feeder"
EMIT_TITLE_TAGS: "true"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeederprowlarr-filename-parser.key"
volumes:
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeederprowlarr/keys:/keys:rw
networks:
- metafeederprowlarr
metafeederprowlarr-tmdb:
image: ghcr.io/worph/metamesh-plugin-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-tmdb:1.1.0
cpu_shares: 30
container_name: metafeederprowlarr-tmdb
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -145,8 +156,13 @@ services:
# unavailable" and silently writes no posters/backdrops, so every record then
# fails meta-watch's poster gate. Drop only after re-tagging the plugin.
WEBDAV_URL: "http://metacore-app:9000/webdav"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeederprowlarr-tmdb.key"
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metafeederprowlarr/tmdb-cache:/cache
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeederprowlarr/keys:/keys:rw
networks:
- metafeederprowlarr
- pcs
@@ -215,8 +231,8 @@ x-casaos:
title:
en_us: MetaFeeder · Prowlarr
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederProwlarr/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederProwlarr/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederProwlarr/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederProwlarr/thumbnail.png
store_app_id: metafeederprowlarr
is_uncontrolled: false
@@ -255,3 +271,6 @@ x-compose-app:
- path: /DATA/AppData/metafeederprowlarr/tmdb-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metafeederprowlarr/keys
user: $PUID
group: $PGID
+3 -3
View File
@@ -21,7 +21,7 @@ services:
# metafeederscihub-feeder — the scihub feeder. Needs SCIHUB_MIRRORS to do anything.
# ---------------------------------------------------------------------------
metafeederscihub-feeder:
image: ghcr.io/worph/meta-feeder-scihub:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-scihub:1.0.3
cpu_shares: 30
container_name: metafeederscihub-feeder
hostname: metafeederscihub-feeder
@@ -86,8 +86,8 @@ x-casaos:
title:
en_us: MetaFeeder · Sci-Hub
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederSciHub/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederSciHub/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederSciHub/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederSciHub/thumbnail.png
store_app_id: metafeederscihub
is_uncontrolled: false
+205
View File
@@ -0,0 +1,205 @@
name: metafeederstremio
# =============================================================================
# MetaFeeder · Stremio — Stremio addons (AIOStreams, Torrentio, …) as a torrent
# source for MetaMesh.
#
# Same model as MetaFeeder · Prowlarr: this app is only the GLUE. The source is a
# separate app — **AIOStreams** (Yundera store, container `aiostreams:3000`) is
# the recommended one: a single addon URL that aggregates Torrentio, Comet,
# MediaFusion, … Any addon speaking the Stremio protocol works, including
# Torrentio's public link.
#
# Answers id-anchored queries only, the three shapes MetaWatch sends:
# film `tmdbid:603 contentKind:movie`
# season `tmdbid:1399 season:1` (one addon call per episode)
# episode `tmdbid:1399 season:1 episode:2`
# (`imdbid:` works in place of `tmdbid:`). Each P2P stream is one per-file
# BitTorrent record — infoHash + fileIdx, i.e. the exact episode inside a season
# pack — that MetaTransport · Torrent plays with no .torrent file.
#
# ⚠ P2P ONLY. Configure AIOStreams WITHOUT a debrid service. Debrid links are
# personal, expiring and carry your token: this feeder drops them, and the
# gateway must never relay one user's debrid account to the mesh. Debrid will be
# a client-side MetaShare option instead.
#
# Self-contained: calls the addons and TMDB directly, holds no bytes, runs no
# enrichment sidecars, does NOT talk to meta-core — the MetaGateway core stores
# and announces the records it returns.
#
# It needs, over the shared `pcs` network:
# - the **MetaGateway** app — which must list this feeder's URL
# (`http://metafeederstremio-feeder:8080`) in its feeders config. Discovery
# is startup-only, so restart the gateway afterwards.
# - an addon (AIOStreams app, or a public addon URL).
#
# Everything is scoped under the `metafeederstremio-*` prefix +
# /DATA/AppData/metafeederstremio/ data root, so it installs alongside the other
# Meta* apps with zero collisions.
# =============================================================================
services:
# ---------------------------------------------------------------------------
# metafeederstremio-feeder — the feeder (meta-feeder-stremio) hosting the
# `stremio` upstream. The gateway core reaches it directly on `pcs` for
# discovery/query; the human configures it from the MetaGateway dashboard
# (configure panel).
# ---------------------------------------------------------------------------
metafeederstremio-feeder:
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-stremio:1.3.1
cpu_shares: 30
container_name: metafeederstremio-feeder
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of
# swap. One HTTP client + in-memory TMDB/record caches.
mem_limit: 256m
memswap_limit: 256m
hostname: metafeederstremio-feeder
restart: unless-stopped
# Its only write is its own state dir below, which Maison creates as
# $PUID:$PGID (x-compose-app.folders). So no root is needed.
user: $PUID:$PGID
expose:
- 8080
environment:
# INFRA-ONLY env (the "config: no env if in webui" rule). The addon URLs and
# the TMDB token are read from the persisted config.json written by this
# feeder's config page (opened from the MetaGateway dashboard). The
# STREMIO_ADDON_URLS / TMDB_TOKEN env vars exist only as first-boot seeds;
# don't set them here.
RUST_LOG: "info"
TZ: "$TZ"
volumes:
# Persist feeder config (config.json saved via the config UI).
- ${DATA_ROOT:-/DATA}/AppData/metafeederstremio/state:/data/meta-feeder:rw
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
interval: 5s
timeout: 3s
retries: 10
start_period: 5s
networks:
- pcs
networks:
pcs:
name: ${APP_NET:-pcs}
external: true
x-casaos:
architectures:
- amd64
- arm64
author: Worph Team
category: Media
developer: Aptero Team
description:
en_us: |
**Stremio addons as a MetaMesh source — AIOStreams, Torrentio and friends.**
MetaFeeder · Stremio asks your Stremio addons for the torrents of a film or
an episode, and turns each one into a MetaMesh release that **MetaWatch**
can play. The addons have already done the hard matching work: every
result points at the **exact file** — the right episode inside a season
pack or a complete-series torrent — so nothing is guessed from release
names.
**Use it with AIOStreams** (one link that aggregates Torrentio, Comet,
MediaFusion, …) or paste any addon's install link — Torrentio's public link
works too.
**Torrent (P2P) streams only.** Set up AIOStreams **without** a debrid
service: debrid links are personal and expire, so this feeder ignores
them rather than share your account with the mesh.
**Fast and self-contained:** an addon answers in about a second, results
stream in as they arrive, nothing is stored here and no enrichment
sidecars run. ~256 MB RAM.
**Requires:** **MetaGateway** — its meta-core stores the results and
announces them to the swarm; the gateway must list this feeder in its
config. A free **TMDB** token gives releases their poster and summary.
**Pairs with:** **AIOStreams**, **MetaWatch**, **MetaTransport · Torrent**.
fr_fr: |
**Les addons Stremio comme source MetaMesh — AIOStreams, Torrentio et autres.**
MetaFeeder · Stremio demande à vos addons Stremio les torrents d'un film ou
d'un épisode, et transforme chacun en une release MetaMesh que
**MetaWatch** peut lire. Les addons ont déjà fait le travail de
correspondance : chaque résultat désigne le **fichier exact** — le bon
épisode dans un pack de saison ou une intégrale — rien n'est deviné à
partir des noms de release.
**À utiliser avec AIOStreams** (un seul lien qui agrège Torrentio, Comet,
MediaFusion, …) ou collez le lien d'installation de n'importe quel addon —
le lien public de Torrentio fonctionne aussi.
**Flux torrent (P2P) uniquement.** Configurez AIOStreams **sans** service
de debrid : les liens debrid sont personnels et expirent, ce feeder les
ignore plutôt que de partager votre compte avec le mesh.
**Rapide et autonome :** un addon répond en une seconde environ, les
résultats arrivent au fil de l'eau, rien n'est stocké ici, aucun plugin
d'enrichissement. ~256 Mo de RAM.
**Nécessite :** l'app **MetaGateway** (son meta-core stocke et annonce les
résultats ; la passerelle doit lister ce feeder dans sa configuration). Un
jeton **TMDB** gratuit donne aux releases leur affiche et leur résumé.
tagline:
en_us: Stremio addons (AIOStreams, Torrentio) as a torrent source — exact file per episode
fr_fr: Addons Stremio (AIOStreams, Torrentio) comme source torrent — le fichier exact par épisode
title:
en_us: MetaFeeder · Stremio
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederStremio/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederStremio/thumbnail.png
store_app_id: metafeederstremio
is_uncontrolled: false
tips:
before_install:
en_us: |
**Install order:** **MetaGateway** first, then **AIOStreams** (Yundera
store) if you use it.
**After installing this app:**
1. In **AIOStreams**, build a configuration **without any debrid
service** (torrent/P2P addons only, e.g. Torrentio), save it and copy
its install link (`…/manifest.json`). From inside the PCS you can use
the internal form `http://aiostreams:3000/stremio/…/manifest.json`.
2. Open this feeder's config panel (the **MetaGateway** dashboard → this
feeder → *configure*), paste the link into **Stremio addon URLs** (one
per line), add your **TMDB token** (v4 read token from
themoviedb.org → Settings → API) and save. The feeder restarts itself.
3. In **MetaGateway**, add this feeder to its feeders config — name
`stremio-feeder`, URL `http://metafeederstremio-feeder:8080` — from
the gateway dashboard's *Add a feeder* box. The gateway restarts
itself and picks up the `stremio` upstream.
**Without an addon URL** the feeder stays up but reports degraded and
answers nothing. **Without a TMDB token** it answers only `imdbid:`
searches and releases have no poster — MetaWatch sends `tmdbid:`.
**Only film and episode lookups reach it** (a title, season or episode
page). The free-text search box never does: addons cannot search by text.
**No web UI of its own:** configure it from the **MetaGateway** dashboard
→ this feeder → *configure* (the gateway proxies this feeder's config
page, behind the gateway's login).
# Maison (Yundera dashboard) configuration. Read in preference to x-casaos.
# schema_version 2 is required for `folders`: an older Maison refuses the app
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# The feeder runs as $PUID:$PGID, so this ownership is what lets it write.
folders:
- path: /DATA/AppData/metafeederstremio/state
user: $PUID
group: $PGID
Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

+43 -38
View File
@@ -8,21 +8,24 @@ name: metafeedersuwayomi
# own. Split out of the former MetaFeeder · Comic app; **MetaFeeder · AniList**
# is the optional identity tier beside it.
#
# ⚠ **Needs meta-gateway ≥ 1.0.28** — chapters arrive unresolved and their page
# list follows as an EnrichPatch, which an older gateway drops.
#
# ⚠ **Suwayomi itself is a SEPARATE app — install it first.** This feeder ships
# pointed at `suwayomi:4567`, the container the **Suwayomi** store app publishes
# on the shared `pcs` network.
# pointed at `http://suwayomi` (port 80), the container the stock **Suwayomi**
# store app publishes on the shared `pcs` network.
#
# ⚠ **Give the feeder Suwayomi's login.** The stock app runs
# `AUTH_MODE: simple_login`; enter its admin password (Maison → Suwayomi →
# credentials) on this feeder's config page. Only this feeder talks to
# Suwayomi — readers get chapters through the gateway — so its login stays on.
#
# ⚠ **Querying Suwayomi WRITES.** Its search and chapter calls are GraphQL
# mutations that cache source results into its library database.
#
# ⚠ **Suwayomi must be reachable UNAUTHENTICATED.** An undownloaded chapter is a
# list of per-page URLs pointing at the Suwayomi container, redeemed by the
# READER's meta-share peer with no credentials. Suwayomi's `simple_login` 401s
# those routes — a library that lists every chapter and opens none. The Suwayomi
# store app therefore runs `AUTH_MODE: none` behind an AppShield/OIDC gate.
# How a chapter is read: its record carries one portable `tachiyomi` locator
# (minted from the chapter's address on its SITE, so every box agrees on it).
# Opening it makes the gateway redeem it here: the feeder fetches every page
# through Suwayomi and answers one CBZ, which the gateway stores once and the
# mesh serves from then on. Needs a gateway that redeems `provider-file`
# locators and MetaTransport · IPFS ≥ 1.3.4 (64 MiB redeem ceiling).
#
# It needs, over the shared `pcs` network:
# - the **MetaGateway** app — which must list this feeder's URL
@@ -37,11 +40,11 @@ name: metafeedersuwayomi
services:
# ---------------------------------------------------------------------------
# metafeedersuwayomi-feeder — the chapter tier. Resolves a work to titles,
# searches every installed source, returns the chapters. Chapters are listed
# lazily: each chapter's page list is fetched only when a reader opens it.
# searches every installed source, returns the chapters. Listing fetches no
# page: a chapter's pages are fetched once, when a reader first opens it.
# ---------------------------------------------------------------------------
metafeedersuwayomi-feeder:
image: ghcr.io/worph/meta-feeder-suwayomi:1.0.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-suwayomi:1.1.0
cpu_shares: 30
container_name: metafeedersuwayomi-feeder
mem_limit: 256m
@@ -54,16 +57,15 @@ services:
environment:
RUST_LOG: "info,meta_feeder=info,suwayomi_feeder=info"
META_FEEDER_STATE_DIR: "/data/meta-feeder"
# INFRA-ONLY env, and only a FIRST-BOOT SEED: `base_url` is a field on
# this feeder's own config page (the MetaGateway dashboard (configure panel)), and a value saved
# there wins. `suwayomi` is the container the Suwayomi store app publishes
# on `pcs` — change it only to point at a Suwayomi somewhere else, and see
# the reachability warning in the header before you do.
SUWAYOMI_URL: "http://suwayomi:4567"
# Listing chapters is cheap (one call returns them all); RESOLVING a
# chapter's page list is what costs. 0 = fetch nothing until a reader
# clicks. Raise it to pre-warm the first N ordinals per work.
SUWAYOMI_WARM_CHAPTERS: "0"
# FIRST-BOOT SEEDS only: `base_url`, `username` and `password` are fields
# on this feeder's own config page (MetaGateway dashboard → this feeder →
# configure), and a value saved there wins. `suwayomi` is the container
# the Suwayomi store app publishes on `pcs`, on port 80.
SUWAYOMI_URL: "http://suwayomi"
# The stock Suwayomi app's login user. Its password is per-install
# (Maison → Suwayomi → credentials) and no app can read another's
# secret, so it is entered once on the config page.
SUWAYOMI_USERNAME: "admin"
# ⚠ SUWAYOMI_MAX_CHAPTERS is deliberately NOT set: it bounds how many
# chapters are LISTED, and any value can only truncate a long series into
# looking short.
@@ -101,9 +103,9 @@ x-casaos:
you installed in the **Suwayomi** app, and mints its own work cards so search
works on its own. Add **MetaFeeder · AniList** to name works across sources.
**Install Suwayomi first.** It is a separate app in this store (with a
FlareSolverr sidecar, so Cloudflare-protected sources work). This feeder arrives
pointed at it and needs no wiring.
**Install Suwayomi first** (a separate app, with a FlareSolverr sidecar so
Cloudflare-protected sources work). This feeder arrives pointed at it; give it
Suwayomi's admin password on its config page.
**You own the sources.** Suwayomi ships exactly one built-in source — *Local
source*, which reads CBZ/CBR from its own folder. Everything else is an extension
@@ -114,8 +116,9 @@ x-casaos:
**Multi-source by design.** Every installed source that carries a work
contributes, and each chapter row offers a chooser across them.
**Lazy by default.** Listing a series' chapters costs one upstream call however
long it is; a chapter's page list is fetched only when someone opens it.
**Fetched once, shared after.** Listing a series' chapters costs one upstream
call however long it is. A chapter's pages are fetched the first time someone
opens it, stored as one CBZ, and served from the mesh from then on.
**Requires:** **MetaGateway** — its meta-core stores the resolved records and
announces them to the swarm. The gateway must list this feeder in its config.
**Pairs with: MetaRead**, the reading client.
@@ -131,8 +134,9 @@ x-casaos:
**Vous possédez les sources.** Suwayomi n'embarque que *Local source* ; tout le
reste est une extension que **vous** installez via l'interface Suwayomi.
**Paresseux par défaut.** Lister les chapitres coûte un appel ; les pages d'un
chapitre ne sont récupérées qu'à l'ouverture.
**Récupéré une fois, partagé ensuite.** Lister les chapitres coûte un appel ;
les pages d'un chapitre sont récupérées à sa première ouverture, stockées en un
CBZ, puis servies par le maillage.
**Nécessite :** les apps **MetaGateway** et **Suwayomi**. **Va avec : MetaRead.**
tagline:
@@ -142,8 +146,8 @@ x-casaos:
title:
en_us: MetaFeeder · Suwayomi
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederSuwayomi/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederSuwayomi/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederSuwayomi/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederSuwayomi/thumbnail.png
store_app_id: metafeedersuwayomi
is_uncontrolled: false
@@ -152,8 +156,8 @@ x-casaos:
before_install:
en_us: |
**Install order:** **MetaGateway** first, then **Suwayomi** — the separate
store app this feeder reads. This app arrives pointed at `suwayomi:4567`; without
that app installed it stays healthy and simply finds no chapters.
store app this feeder reads. This app arrives pointed at `http://suwayomi`;
without that app installed it stays healthy and simply finds no chapters.
**After installing this app:**
1. In **MetaGateway**, add this feeder from the dashboard's *Add a feeder* box —
@@ -167,16 +171,17 @@ x-casaos:
4. Optionally install **MetaFeeder · AniList** so chapters from several sources
converge on one work page.
5. **Give the feeder Suwayomi's login:** copy the admin password from Maison →
Suwayomi → credentials into this feeder's config page (*Suwayomi password*).
Changed it in Maison later? Enter it here again.
This app has no web UI of its own: the **feeder's config page** (Suwayomi URL,
chapters per work, chapters pre-loaded) opens from the **MetaGateway**
username, password, chapters per work) opens from the **MetaGateway**
dashboard → this feeder → *configure*. Suwayomi's own UI is the Suwayomi app.
**⚠ Querying Suwayomi writes to it.** Rows will appear in its library that you
did not add by hand. That is inherent to how the aggregator works.
**Suwayomi's own login must stay off** — the reader fetches chapter pages from it
unauthenticated, so enabling it gives a library that lists every chapter and can
open none.
**No web UI of its own:** configure it from the **MetaGateway** dashboard → this feeder → *configure* (the gateway proxies this feeder's config page, behind the gateway's login).
# Maison (Yundera dashboard) configuration. Read in preference to x-casaos.
+6 -6
View File
@@ -43,7 +43,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeedertmdb-feeder:
image: ghcr.io/worph/meta-feeder-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-tmdb:1.0.6
cpu_shares: 30
container_name: metafeedertmdb-feeder
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of
@@ -162,12 +162,12 @@ x-casaos:
title:
en_us: MetaFeeder · TMDB
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTMDB/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTMDB/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTMDB/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTMDB/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTMDB/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTMDB/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTMDB/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTMDB/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTMDB/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTMDB/thumbnail.png
store_app_id: metafeedertmdb
is_uncontrolled: false
+24 -5
View File
@@ -71,7 +71,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeedertribler-feeder:
image: ghcr.io/worph/meta-feeder-tribler:1.0.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-tribler:1.1.0
cpu_shares: 30
container_name: metafeedertribler-feeder
hostname: metafeedertribler-feeder
@@ -93,10 +93,15 @@ services:
META_FEEDER_CALLBACK_URL: "http://metafeedertribler-feeder:8080/enrich/callback"
META_FEEDER_STATE_DIR: "/data/meta-feeder"
TZ: "$TZ"
# Own claim-signing key (self-published records); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeedertribler-feeder.key"
volumes:
# Persist feeder config (config.json pre-seeded + editable via UI) + redb
# cache. config.json lives at gateway/tribler/config.json under this dir.
- ${DATA_ROOT:-/DATA}/AppData/metafeedertribler/state:/data/meta-feeder:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeedertribler/keys:/keys:rw
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
interval: 5s
@@ -123,7 +128,7 @@ services:
# images don't ship one (curl absent).
# ---------------------------------------------------------------------------
metafeedertribler-filename-parser:
image: ghcr.io/worph/metamesh-plugin-filename-parser:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-filename-parser:1.1.0
cpu_shares: 30
container_name: metafeedertribler-filename-parser
hostname: metafeedertribler-filename-parser
@@ -136,11 +141,17 @@ services:
BEACON_BINDS: "metafeedertribler-feeder"
PORT: "8080"
EMIT_TITLE_TAGS: "true"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeedertribler-filename-parser.key"
volumes:
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeedertribler/keys:/keys:rw
networks:
- metafeedertribler
metafeedertribler-tmdb:
image: ghcr.io/worph/metamesh-plugin-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-tmdb:1.1.0
cpu_shares: 30
container_name: metafeedertribler-tmdb
hostname: metafeedertribler-tmdb
@@ -155,8 +166,13 @@ services:
CACHE_DIR: "/cache"
# Posters land in the shared meta-core (over pcs) so the ingester seeds them.
WEBDAV_URL: "http://metacore-app:9000/webdav"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeedertribler-tmdb.key"
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metafeedertribler/tmdb-cache:/cache
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeedertribler/keys:/keys:rw
networks:
- metafeedertribler
- pcs
@@ -214,8 +230,8 @@ x-casaos:
title:
en_us: MetaFeeder · Tribler
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTribler/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederTribler/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTribler/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederTribler/thumbnail.png
store_app_id: metafeedertribler
is_uncontrolled: false
@@ -275,3 +291,6 @@ x-compose-app:
- path: /DATA/AppData/metafeedertribler/tribler-seed
user: $PUID
group: $PGID
- path: /DATA/AppData/metafeedertribler/keys
user: $PUID
group: $PGID
+22 -8
View File
@@ -38,7 +38,7 @@ services:
# the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeederusenet-feeder:
image: ghcr.io/worph/meta-feeder-usenet:1.2.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-usenet:1.2.1
cpu_shares: 30
container_name: metafeederusenet-feeder
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead
@@ -101,7 +101,7 @@ services:
# images don't ship one (curl absent).
# ---------------------------------------------------------------------------
metafeederusenet-filename-parser:
image: ghcr.io/worph/metamesh-plugin-filename-parser:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-filename-parser:1.1.0
cpu_shares: 30
container_name: metafeederusenet-filename-parser
mem_limit: 256m
@@ -115,11 +115,17 @@ services:
# (meta-sort's Scan card) sees it as bound elsewhere, never addable.
BEACON_BINDS: "metafeederusenet-feeder"
EMIT_TITLE_TAGS: "true"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeederusenet-filename-parser.key"
volumes:
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeederusenet/keys:/keys:rw
networks:
- metafeederusenet
metafeederusenet-tmdb:
image: ghcr.io/worph/metamesh-plugin-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-tmdb:1.1.0
cpu_shares: 30
container_name: metafeederusenet-tmdb
mem_limit: 384m
@@ -137,8 +143,13 @@ services:
# the sibling feeder apps' identical note: the published image needs
# this, unlike the source build the dev stack runs).
WEBDAV_URL: "http://metacore-app:9000/webdav"
# Own claim-signing key (enrichment claims); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metafeederusenet-tmdb.key"
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metafeederusenet/tmdb-cache:/cache
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metafeederusenet/keys:/keys:rw
networks:
- metafeederusenet
- pcs
@@ -198,12 +209,12 @@ x-casaos:
title:
en_us: MetaFeeder · Usenet
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederUsenet/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederUsenet/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederUsenet/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederUsenet/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederUsenet/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederUsenet/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederUsenet/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederUsenet/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederUsenet/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederUsenet/thumbnail.png
store_app_id: metafeederusenet
is_uncontrolled: false
@@ -252,6 +263,9 @@ x-compose-app:
- path: /DATA/AppData/metafeederusenet/tmdb-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metafeederusenet/keys
user: $PUID
group: $PGID
# No web UI: Maison files it under Services. Configured from MetaGateway.
# Shown from the tile menu.
tips:
@@ -22,7 +22,7 @@ services:
# metafeederwikicommons-feeder — the wikicommons feeder. Keyless; no config needed.
# ---------------------------------------------------------------------------
metafeederwikicommons-feeder:
image: ghcr.io/worph/meta-feeder-wikicommons:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-wikicommons:1.0.2
cpu_shares: 30
container_name: metafeederwikicommons-feeder
hostname: metafeederwikicommons-feeder
@@ -79,8 +79,8 @@ x-casaos:
title:
en_us: MetaFeeder · Wikimedia Commons
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederWikiCommons/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederWikiCommons/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederWikiCommons/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederWikiCommons/thumbnail.png
store_app_id: metafeederwikicommons
is_uncontrolled: false
+3 -3
View File
@@ -30,7 +30,7 @@ services:
# from the MetaGateway dashboard (configure panel).
# ---------------------------------------------------------------------------
metafeederyoutube-feeder:
image: ghcr.io/worph/meta-feeder-youtube:1.1.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-youtube:1.1.3
cpu_shares: 30
container_name: metafeederyoutube-feeder
# Delegated tier: it moves an 11-character video id, never bytes.
@@ -100,8 +100,8 @@ x-casaos:
title:
en_us: MetaFeeder · YouTube
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederYouTube/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFeederYouTube/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederYouTube/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFeederYouTube/thumbnail.png
store_app_id: metafeederyoutube
is_uncontrolled: false
+9 -9
View File
@@ -4,7 +4,7 @@ services:
# Backend service. Reachable on the pcs network as `metafuse-app`.
# Public ingress goes through the `metafuse` hash-lock proxy below.
metafuse-app:
image: ghcr.io/worph/meta-fuse:1.1.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-fuse:1.1.6
cpu_shares: 50
container_name: metafuse-app
hostname: metafuse-app
@@ -77,7 +77,7 @@ services:
BACKEND_HOST: "metafuse-app"
BACKEND_PORT: "80"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metafuse-app
@@ -94,8 +94,8 @@ services:
caddy_0.2_handle: ""
caddy_0.2_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metafuse-IP.nip.io (gateway TLS) ----
caddy_1: metafuse-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metafuse-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metafuse-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metafuse-app:80"
@@ -168,12 +168,12 @@ x-casaos:
title:
en_us: MetaFuse
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFuse/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFuse/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFuse/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFuse/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFuse/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaFuse/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFuse/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFuse/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFuse/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaFuse/thumbnail.png
index: /
store_app_id: metafuse
+3 -3
View File
@@ -77,9 +77,9 @@ over mDNS on `pcs` regardless.
| Image | Tag |
|-------|-----|
| `ghcr.io/worph/meta-gateway` | `1.0.25` |
| `ghcr.io/worph/meta-share` | `1.0.26` |
| `ghcr.io/worph/meta-core` | `1.0.12` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-gateway` | `1.0.43` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share` | `2.6.2` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core` | `1.0.24` |
| `ghcr.io/yundera/appshield` | `2.0.9` |
No feeder images are listed here any more: every content source is a **separate
+46 -16
View File
@@ -35,7 +35,7 @@ services:
# ===========================================================================
metagateway-core:
# 1.0.1 carries the new meta-core API (records cids/ set, identity).
image: ghcr.io/worph/meta-core:1.0.23
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core:2.1.0.1
container_name: metagateway-core
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
# instead of swap. Mirrors the dev sub-stack limits.
@@ -50,6 +50,8 @@ services:
- 9000
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metagateway/metacore:/meta-core:rw
# (meta-core 2.0.0 keeps its rebuildable index cache at
# /meta-core/db-cache/cache.db inside this bind — excluded from backups.)
- ${DATA_ROOT:-/DATA}/AppData/metagateway/files:/files:rw
environment:
- BASE_URL=http://metagateway-core:9000
@@ -81,7 +83,7 @@ services:
# MetaShare app's `metashare-<tier>` hostnames, which on a shared `pcs`
# would be ANOTHER hull's plugins writing to another /data).
# - 3000 HTTP API - 3001 plugin callback API (internal only)
image: ghcr.io/worph/meta-share:2.4.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share:2.7.0
container_name: metagateway-share
# The swarm and blockstore moved to the ipfs plugin, so the hull needs far
# less than the monolith did.
@@ -103,6 +105,9 @@ services:
# hull's; ipfs/blocks.redb is the ipfs plugin's corner of the SAME folder
# (layout unchanged from 1.0.x, so an existing cache carries over).
- ${DATA_ROOT:-/DATA}/AppData/metagateway/share-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metagateway/keys:/keys:rw
environment:
META_CORE_URL: "http://metagateway-core:9000"
BASE_URL: "http://metagateway-share:3000"
@@ -110,6 +115,8 @@ services:
META_SHARE_PLUGIN_IPFS_URL: "http://metagateway-share-ipfs:3000"
META_SHARE_PLUGIN_TORRENT_URL: "off"
META_SHARE_PLUGIN_NZB_URL: "off"
# Own claim-signing key; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metagateway-share.key"
TZ: "$TZ"
depends_on:
metagateway-core:
@@ -129,7 +136,7 @@ services:
# mDNS, bitswap), the blockstore, gateway discovery and the peer directory
# the hull uses to forward Usenet cids. Waits up to 60 s for the hull's
# internal /health before opening blocks.redb, so no depends_on.
image: ghcr.io/worph/meta-transport-ipfs:1.3.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-ipfs:1.3.4
container_name: metagateway-share-ipfs
hostname: metagateway-share-ipfs
restart: unless-stopped
@@ -184,8 +191,12 @@ services:
# P2P listen/announce so it's discoverable + dialable off-host + the
# 2026-07 discovery/filters fixes that make the meta-search fan-out
# actually route `fileType:video` queries here.
image: ghcr.io/worph/meta-gateway:1.0.41
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-gateway:1.1.1
container_name: metagateway-app
# Run as the PUID that Maison creates the app folders with (as the Shared
# variant does). The image default user (uid 10001) cannot write them on a
# fresh install: "create ipfs dir … Permission denied".
user: "1000:1000"
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
# instead of swap. Mirrors the dev sub-stack limits.
# 1g -> 2g (2026-09-30): the DHT-joined dispatcher runs at ~1.2 GiB on
@@ -207,6 +218,9 @@ services:
# gateway-config.json (feeders map) + gateway-enabled.json, written by
# pre-install-cmd. Runtime redb caches also live here.
- ${DATA_ROOT:-/DATA}/AppData/metagateway/state:/data/meta-gateway:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metagateway/keys:/keys:rw
environment:
# NOTE: `meta_core_url` (and `meta_share_url`) live in gateway-config.json
# since v1.0.12 — no longer read from env. The pre-install-cmd below seeds
@@ -215,6 +229,9 @@ services:
# libp2p identify agent_version) — without it meta-search can't HTTP-fetch
# /api/gateway/plugins on this gateway to populate its routing table.
META_GATEWAY_PEER_ID: "metagateway"
# Own claim-signing key for the records it auto-stores in its meta-core;
# generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metagateway-app.key"
# MUST be resolvable BY A REMOTE PEER — it is advertised verbatim in the
# identify `baseUrl=` token and used for nothing else in-process. A
# docker-internal name here (the old `http://metagateway-app:3000`) makes
@@ -306,7 +323,7 @@ services:
BACKEND_HOST: "metagateway-app"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metagateway-app
labels:
@@ -331,8 +348,8 @@ services:
caddy_0.3_handle: ""
caddy_0.3_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metagateway-IP.nip.io (gateway TLS) ----
caddy_1: metagateway-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metagateway-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metagateway-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metagateway-app:3000"
@@ -385,7 +402,7 @@ services:
expose: ["80"]
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metagateway-core"
BACKEND_PORT: "80"
LISTEN_PORT: "80"
@@ -393,7 +410,7 @@ services:
caddy_0: metagatewaycore-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metagatewaycore-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metagatewaycore-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metagatewaycore-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -414,7 +431,7 @@ services:
expose: ["80"]
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metagateway-share"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -422,7 +439,7 @@ services:
caddy_0: metagatewayshare-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metagatewayshare-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metagatewayshare-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metagatewayshare-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -512,12 +529,12 @@ x-casaos:
title:
en_us: MetaGateway
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/thumbnail.png
index: /
store_app_id: metagateway
@@ -609,6 +626,11 @@ x-compose-app:
- path: /DATA/AppData/metagateway/metacore
user: $PUID
group: $PGID
# meta-core 2.0.0 rebuildable index cache (default
# /meta-core/db-cache/cache.db). Excluded from backups below.
- path: /DATA/AppData/metagateway/metacore/db-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metagateway/files
user: $PUID
group: $PGID
@@ -624,6 +646,14 @@ x-compose-app:
- path: /DATA/AppData/metagateway/share-ipfs-state
user: $PUID
group: $PGID
- path: /DATA/AppData/metagateway/keys
user: $PUID
group: $PGID
# Derived data only: meta-core rebuilds its index cache from the truth file
# (metacore/db/meta-core.db, which IS backed up). keys/ stays backed up.
backup:
exclude:
- metacore/db-cache/
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metagateway-${domain}
webui-path: "/"
+17 -9
View File
@@ -33,7 +33,7 @@ services:
# co-located metashare-app then seeds the resolved CIDs.
# ---------------------------------------------------------------------------
metagateway-app:
image: ghcr.io/worph/meta-gateway:1.0.41
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-gateway:1.1.1
container_name: metagateway-app
hostname: metagateway-app
restart: unless-stopped
@@ -55,6 +55,9 @@ services:
volumes:
# gateway-config.json (source definitions, feeder URLs) + dispatcher state.
- ${DATA_ROOT:-/DATA}/AppData/metagateway/state:/data/meta-gateway:rw
# Claim-signing key (meta-core 2.0.0 claims model) for the records the
# dispatcher writes to metacore-app. Config — backed up.
- ${DATA_ROOT:-/DATA}/AppData/metagateway/keys:/keys:rw
environment:
# Advertised verbatim in this peer's libp2p identify `agent_version`
# (`baseUrl=...`) and used for NOTHING else in-process — see
@@ -72,6 +75,8 @@ services:
# carve-out in the Caddy labels below is what makes this URL answerable.
META_GATEWAY_BASE_URL: "https://metagateway-${APP_DOMAIN}"
META_GATEWAY_PEER_ID: "metagateway"
# Own claim-signing key; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metagateway-app.key"
# --- cross-node discoverability (added 2026-08-26) ---------------------
# WITHOUT META_GATEWAY_PUBLIC_ADDR meta-gateway starts in local/mDNS-only
# mode: it loads NO kad bootstraps, sets kad_provide_enabled=false, and so
@@ -130,7 +135,7 @@ services:
retries: 10
start_period: 5s
labels:
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/icon.png
networks:
- metagateway
- pcs
@@ -144,7 +149,7 @@ services:
# Runs as 10001:999 — the uid/gid baked into the meta-feeder-tmdb image.
# ---------------------------------------------------------------------------
metagateway-card:
image: ghcr.io/worph/meta-feeder-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-feeder-tmdb:1.0.6
container_name: metagateway-card
hostname: metagateway-card
restart: unless-stopped
@@ -166,7 +171,7 @@ services:
retries: 10
start_period: 5s
labels:
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/icon.png
networks:
- metagateway
@@ -193,7 +198,7 @@ services:
BACKEND_HOST: "metagateway-app"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metagateway-app
labels:
@@ -221,8 +226,8 @@ services:
caddy_0.3_handle: ""
caddy_0.3_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metagateway-IP.nip.io (gateway TLS) ----
caddy_1: metagateway-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metagateway-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metagateway-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metagateway-app:3000"
@@ -256,7 +261,7 @@ services:
caddy_2.3_handle: ""
caddy_2.3_handle.reverse_proxy: "{{upstreams 80}}"
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/icon.png
networks:
- metagateway
- pcs
@@ -277,7 +282,7 @@ x-casaos:
category: Media
developer: Aptero Team
hostname: metagateway-${APP_DOMAIN}
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaGateway/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaGateway/icon.png
index: /
is_uncontrolled: false
main: metagateway
@@ -356,6 +361,9 @@ x-compose-app:
- path: /DATA/AppData/metagateway/state
user: $PUID
group: $PGID
- path: /DATA/AppData/metagateway/keys
user: $PUID
group: $PGID
- path: /DATA/AppData/metagateway/card
user: 10001
group: 999
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginanimedetector-plugin:
image: ghcr.io/worph/metamesh-plugin-anime-detector:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-anime-detector:1.1.0
cpu_shares: 30
container_name: metapluginanimedetector-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -49,6 +49,13 @@ services:
# Nothing to configure: this plugin takes its work from the /process
# payload and writes back through the caller. No key, no WebDAV.
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginanimedetector-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginanimedetector/keys:/keys:rw
networks:
- pcs
networks:
@@ -100,8 +107,8 @@ x-casaos:
title:
en_us: MetaPlugin · Anime Detector
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginAnimeDetector/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginAnimeDetector/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginAnimeDetector/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginAnimeDetector/thumbnail.png
store_app_id: metapluginanimedetector
is_uncontrolled: false
@@ -124,3 +131,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginanimedetector/keys
user: $PUID
group: $PGID
+12 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginffmpeg-plugin:
image: ghcr.io/worph/metamesh-plugin-ffmpeg:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-ffmpeg:1.1.0
cpu_shares: 30
container_name: metapluginffmpeg-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,10 +53,16 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginffmpeg-plugin.key"
volumes:
# Plugin cache. Persisted so a recreate does not redo work that is
# expensive to redo; safe to delete, it rebuilds.
- ${DATA_ROOT:-/DATA}/AppData/metapluginffmpeg/cache:/cache:rw
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginffmpeg/keys:/keys:rw
networks:
- pcs
networks:
@@ -110,8 +116,8 @@ x-casaos:
title:
en_us: MetaPlugin · FFmpeg
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFFmpeg/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFFmpeg/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFFmpeg/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFFmpeg/thumbnail.png
store_app_id: metapluginffmpeg
is_uncontrolled: false
@@ -144,3 +150,6 @@ x-compose-app:
- path: /DATA/AppData/metapluginffmpeg/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metapluginffmpeg/keys
user: $PUID
group: $PGID
+12 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginfileinfo-plugin:
image: ghcr.io/worph/metamesh-plugin-file-info:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-file-info:1.1.0
cpu_shares: 30
container_name: metapluginfileinfo-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,10 +53,16 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginfileinfo-plugin.key"
volumes:
# Plugin cache. Persisted so a recreate does not redo work that is
# expensive to redo; safe to delete, it rebuilds.
- ${DATA_ROOT:-/DATA}/AppData/metapluginfileinfo/cache:/cache:rw
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginfileinfo/keys:/keys:rw
networks:
- pcs
networks:
@@ -108,8 +114,8 @@ x-casaos:
title:
en_us: MetaPlugin · File Info
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFileInfo/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFileInfo/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFileInfo/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFileInfo/thumbnail.png
store_app_id: metapluginfileinfo
is_uncontrolled: false
@@ -142,3 +148,6 @@ x-compose-app:
- path: /DATA/AppData/metapluginfileinfo/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metapluginfileinfo/keys
user: $PUID
group: $PGID
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginfilenameparser-plugin:
image: ghcr.io/worph/metamesh-plugin-filename-parser:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-filename-parser:1.1.0
cpu_shares: 30
container_name: metapluginfilenameparser-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -54,6 +54,13 @@ services:
# Blank = off = the plugin's own default, which is MetaSort's semantics.
EMIT_TITLE_TAGS: "${EMIT_TITLE_TAGS:-}"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginfilenameparser-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginfilenameparser/keys:/keys:rw
networks:
- pcs
networks:
@@ -108,8 +115,8 @@ x-casaos:
title:
en_us: MetaPlugin · Filename Parser
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFilenameParser/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFilenameParser/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFilenameParser/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFilenameParser/thumbnail.png
store_app_id: metapluginfilenameparser
is_uncontrolled: false
@@ -136,3 +143,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginfilenameparser/keys
user: $PUID
group: $PGID
+12 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: background.
# ---------------------------------------------------------------------------
metapluginfullhash-plugin:
image: ghcr.io/worph/metamesh-plugin-fullhash:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-fullhash:1.1.0
cpu_shares: 30
container_name: metapluginfullhash-plugin
# 2 GB, swap disabled (memswap_limit == mem_limit) → OOM instead of
@@ -50,10 +50,16 @@ services:
# Nothing to configure: this plugin takes its work from the /process
# payload and writes back through the caller. No key, no WebDAV.
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginfullhash-plugin.key"
volumes:
# Plugin cache. Persisted so a recreate does not redo work that is
# expensive to redo; safe to delete, it rebuilds.
- ${DATA_ROOT:-/DATA}/AppData/metapluginfullhash/cache:/cache:rw
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginfullhash/keys:/keys:rw
networks:
- pcs
networks:
@@ -108,8 +114,8 @@ x-casaos:
title:
en_us: MetaPlugin · Full Hash
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFullHash/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginFullHash/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFullHash/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginFullHash/thumbnail.png
store_app_id: metapluginfullhash
is_uncontrolled: false
@@ -139,3 +145,6 @@ x-compose-app:
- path: /DATA/AppData/metapluginfullhash/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metapluginfullhash/keys
user: $PUID
group: $PGID
+17 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginjellyfinnfo-plugin:
image: ghcr.io/worph/metamesh-plugin-jellyfin-nfo:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-jellyfin-nfo:1.1.0
cpu_shares: 30
container_name: metapluginjellyfinnfo-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,6 +53,13 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginjellyfinnfo-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginjellyfinnfo/keys:/keys:rw
networks:
- pcs
networks:
@@ -106,8 +113,8 @@ x-casaos:
title:
en_us: MetaPlugin · Jellyfin NFO
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginJellyfinNFO/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginJellyfinNFO/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginJellyfinNFO/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginJellyfinNFO/thumbnail.png
store_app_id: metapluginjellyfinnfo
is_uncontrolled: false
@@ -133,3 +140,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginjellyfinnfo/keys
user: $PUID
group: $PGID
+17 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginlanguage-plugin:
image: ghcr.io/worph/metamesh-plugin-language:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-language:1.1.0
cpu_shares: 30
container_name: metapluginlanguage-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -49,6 +49,13 @@ services:
# Nothing to configure: this plugin takes its work from the /process
# payload and writes back through the caller. No key, no WebDAV.
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginlanguage-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginlanguage/keys:/keys:rw
networks:
- pcs
networks:
@@ -102,8 +109,8 @@ x-casaos:
title:
en_us: MetaPlugin · Language
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginLanguage/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginLanguage/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginLanguage/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginLanguage/thumbnail.png
store_app_id: metapluginlanguage
is_uncontrolled: false
@@ -126,3 +133,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginlanguage/keys
user: $PUID
group: $PGID
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: background.
# ---------------------------------------------------------------------------
metapluginopensubtitles-plugin:
image: ghcr.io/worph/metamesh-plugin-opensubtitle:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-opensubtitle:1.1.0
cpu_shares: 30
container_name: metapluginopensubtitles-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,6 +53,13 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginopensubtitles-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginopensubtitles/keys:/keys:rw
networks:
- pcs
networks:
@@ -106,8 +113,8 @@ x-casaos:
title:
en_us: MetaPlugin · OpenSubtitles
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginOpenSubtitles/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginOpenSubtitles/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginOpenSubtitles/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginOpenSubtitles/thumbnail.png
store_app_id: metapluginopensubtitles
is_uncontrolled: false
@@ -137,3 +144,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginopensubtitles/keys
user: $PUID
group: $PGID
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: background.
# ---------------------------------------------------------------------------
metapluginstillextractor-plugin:
image: ghcr.io/worph/metamesh-plugin-still-extractor:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-still-extractor:1.1.0
cpu_shares: 30
container_name: metapluginstillextractor-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,6 +53,13 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginstillextractor-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginstillextractor/keys:/keys:rw
networks:
- pcs
networks:
@@ -106,8 +113,8 @@ x-casaos:
title:
en_us: MetaPlugin · Still Extractor
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginStillExtractor/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginStillExtractor/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginStillExtractor/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginStillExtractor/thumbnail.png
store_app_id: metapluginstillextractor
is_uncontrolled: false
@@ -133,3 +140,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginstillextractor/keys
user: $PUID
group: $PGID
+17 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: fast.
# ---------------------------------------------------------------------------
metapluginsubtitle-plugin:
image: ghcr.io/worph/metamesh-plugin-subtitle:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-subtitle:1.1.0
cpu_shares: 30
container_name: metapluginsubtitle-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,6 +53,13 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginsubtitle-plugin.key"
volumes:
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginsubtitle/keys:/keys:rw
networks:
- pcs
networks:
@@ -107,8 +114,8 @@ x-casaos:
title:
en_us: MetaPlugin · Subtitle
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginSubtitle/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginSubtitle/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginSubtitle/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginSubtitle/thumbnail.png
store_app_id: metapluginsubtitle
is_uncontrolled: false
@@ -134,3 +141,10 @@ x-casaos:
# outright rather than starting it without its directories.
x-compose-app:
schema_version: 2
# Created and chowned by Maison before any image is pulled, before any hook
# runs and before the containers start — on the first boot and every one after.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metapluginsubtitle/keys
user: $PUID
group: $PGID
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: background.
# ---------------------------------------------------------------------------
metapluginsubtitleextractor-plugin:
image: ghcr.io/worph/metamesh-plugin-subtitle-extractor:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-subtitle-extractor:1.1.0
cpu_shares: 30
container_name: metapluginsubtitleextractor-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,10 +53,16 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metapluginsubtitleextractor-plugin.key"
volumes:
# Plugin cache. Persisted so a recreate does not redo work that is
# expensive to redo; safe to delete, it rebuilds.
- ${DATA_ROOT:-/DATA}/AppData/metapluginsubtitleextractor/cache:/cache:rw
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metapluginsubtitleextractor/keys:/keys:rw
networks:
- pcs
networks:
@@ -111,8 +117,8 @@ x-casaos:
title:
en_us: MetaPlugin · Subtitle Extractor
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginSubtitleExtractor/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginSubtitleExtractor/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginSubtitleExtractor/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginSubtitleExtractor/thumbnail.png
store_app_id: metapluginsubtitleextractor
is_uncontrolled: false
@@ -145,3 +151,6 @@ x-compose-app:
- path: /DATA/AppData/metapluginsubtitleextractor/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metapluginsubtitleextractor/keys
user: $PUID
group: $PGID
+12 -3
View File
@@ -33,7 +33,7 @@ services:
# consumer on the box can reach it by name. Default queue: background.
# ---------------------------------------------------------------------------
metaplugintmdb-plugin:
image: ghcr.io/worph/metamesh-plugin-tmdb:1.0.4
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-tmdb:1.1.0
cpu_shares: 30
container_name: metaplugintmdb-plugin
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
@@ -53,10 +53,16 @@ services:
# nothing. Every record then fails MetaWatch's poster gate.
WEBDAV_URL: "http://metacore-app:9000/webdav"
TZ: "$TZ"
# meta-core claims model (v2.0.0): this plugin signs its own claims.
# Key generated on first boot if missing; lives in the backed-up keys/ dir.
METAMESH_SIGNING_KEY_FILE: "/keys/metaplugintmdb-plugin.key"
volumes:
# Plugin cache. Persisted so a recreate does not redo work that is
# expensive to redo; safe to delete, it rebuilds.
- ${DATA_ROOT:-/DATA}/AppData/metaplugintmdb/cache:/cache:rw
# Signing key (METAMESH_SIGNING_KEY_FILE). Config, not cache: it is the
# plugin's identity on every claim, so it MUST be backed up.
- ${DATA_ROOT:-/DATA}/AppData/metaplugintmdb/keys:/keys:rw
networks:
- pcs
networks:
@@ -111,8 +117,8 @@ x-casaos:
title:
en_us: MetaPlugin · TMDB
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginTMDB/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaPluginTMDB/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginTMDB/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaPluginTMDB/thumbnail.png
store_app_id: metaplugintmdb
is_uncontrolled: false
@@ -149,3 +155,6 @@ x-compose-app:
- path: /DATA/AppData/metaplugintmdb/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metaplugintmdb/keys
user: $PUID
group: $PGID
+44 -13
View File
@@ -47,7 +47,7 @@ services:
# consumer, not a library indexer.
# ---------------------------------------------------------------------------
metaread-core:
image: ghcr.io/worph/meta-core:1.0.23
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core:2.1.0.1
container_name: metaread-core
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of
# swap.
@@ -62,6 +62,8 @@ services:
- 9000
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metaread/metacore:/meta-core:rw
# (meta-core 2.0.0 keeps its rebuildable index cache at
# /meta-core/db-cache/cache.db inside this bind — excluded from backups.)
environment:
- BASE_URL=http://metaread-core:9000
- ENABLE_FILE_WATCHER=false
@@ -86,7 +88,7 @@ services:
# peer count before suspecting the feeders.
# ---------------------------------------------------------------------------
metaread-search:
image: ghcr.io/worph/meta-search:1.2.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-search:1.3.2
container_name: metaread-search
mem_limit: 1g
memswap_limit: 1g
@@ -103,6 +105,9 @@ services:
# (beacon v2) instead of reading kv-leader.info off a shared
# volume. See docs/project-architecture/beacon-v2.md.
- ${DATA_ROOT:-/DATA}/AppData/metaread/search-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metaread/keys:/keys:rw
environment:
P2P_LISTEN: "/ip4/0.0.0.0/tcp/4001"
# ⚠ The IPV4 spelling, never the bare APP_PUBLIC_IP: on an IPv6-primary
@@ -121,6 +126,8 @@ services:
META_CORE_URL: "http://metaread-core:9000"
BASE_URL: "http://metaread-search:3000"
INTERNAL_BASE_URL: "http://metaread-search:3000"
# Own claim-signing key (relayed claims are forwarded verbatim, never re-signed); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metaread-search.key"
TZ: "$TZ"
depends_on:
metaread-core:
@@ -154,7 +161,7 @@ services:
# MetaShare app's `metashare-<tier>` hostnames, which on a shared `pcs`
# would be ANOTHER hull's plugins writing to another /data).
# - 3000 HTTP API - 3001 plugin callback API (internal only)
image: ghcr.io/worph/meta-share:2.4.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share:2.7.0
container_name: metaread-share
# The swarm and blockstore moved to the ipfs plugin, so the hull needs far
# less than the monolith did.
@@ -176,6 +183,9 @@ services:
# hull's; ipfs/blocks.redb is the ipfs plugin's corner of the SAME folder
# (layout unchanged from 1.0.x, so an existing cache carries over).
- ${DATA_ROOT:-/DATA}/AppData/metaread/share-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metaread/keys:/keys:rw
environment:
META_CORE_URL: "http://metaread-core:9000"
BASE_URL: "http://metaread-share:3000"
@@ -183,6 +193,8 @@ services:
META_SHARE_PLUGIN_IPFS_URL: "http://metaread-share-ipfs:3000"
META_SHARE_PLUGIN_TORRENT_URL: "off"
META_SHARE_PLUGIN_NZB_URL: "off"
# Own claim-signing key; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metaread-share.key"
TZ: "$TZ"
depends_on:
metaread-core:
@@ -202,7 +214,7 @@ services:
# mDNS, bitswap), the blockstore, gateway discovery and the peer directory
# the hull uses to forward Usenet cids. Waits up to 60 s for the hull's
# internal /health before opening blocks.redb, so no depends_on.
image: ghcr.io/worph/meta-transport-ipfs:1.3.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-ipfs:1.3.4
container_name: metaread-share-ipfs
hostname: metaread-share-ipfs
restart: unless-stopped
@@ -247,7 +259,7 @@ services:
# My List, Continue Reading and reading positions live in the User Data Layer.
# ---------------------------------------------------------------------------
metaread-app:
image: ghcr.io/worph/meta-read:1.0.9
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-read:1.5.1
container_name: metaread-app
hostname: metaread-app
restart: unless-stopped
@@ -266,10 +278,16 @@ services:
environment:
META_SHARE_URL: "http://metaread-share:3000"
META_SEARCH_URL: "http://metaread-search:3000"
# This stack's own meta-core, used ONLY to forward 🐛 bug reports to its
# inbox (/api/reports). Unset hides the button.
META_CORE_URL: "http://metaread-core:9000"
# Browser-reachable topbar chips — the AppShield gates below expose the
# co-located transport and discovery peers behind Yundera OIDC.
META_SHARE_PUBLIC_URL: "https://metareadshare-${APP_DOMAIN}"
META_SEARCH_PUBLIC_URL: "https://metareadsearch-${APP_DOMAIN}"
# Standalone: this app brings its own meta-core and there is no MetaWatch to
# create profiles in, so profile creation stays invite-gated here.
META_READ_PROFILE_CREATION: "local"
TZ: "$TZ"
depends_on:
metaread-search:
@@ -300,7 +318,7 @@ services:
- 80
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metaread-app"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -308,7 +326,7 @@ services:
caddy_0: metaread-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metaread-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metaread-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metaread-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -334,7 +352,7 @@ services:
- 80
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metaread-share"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -342,7 +360,7 @@ services:
caddy_0: metareadshare-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metareadshare-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metareadshare-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metareadshare-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -364,7 +382,7 @@ services:
- 80
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metaread-search"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -372,7 +390,7 @@ services:
caddy_0: metareadsearch-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metareadsearch-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metareadsearch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metareadsearch-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -480,8 +498,8 @@ x-casaos:
title:
en_us: MetaRead
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaRead/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaRead/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaRead/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaRead/thumbnail.png
store_app_id: metaread
is_uncontrolled: false
@@ -521,6 +539,11 @@ x-compose-app:
- path: /DATA/AppData/metaread/metacore
user: $PUID
group: $PGID
# meta-core 2.0.0 rebuildable index cache (default
# /meta-core/db-cache/cache.db). Excluded from backups below.
- path: /DATA/AppData/metaread/metacore/db-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metaread/data
user: $PUID
group: $PGID
@@ -536,5 +559,13 @@ x-compose-app:
- path: /DATA/AppData/metaread/metashare-config
user: $PUID
group: $PGID
- path: /DATA/AppData/metaread/keys
user: $PUID
group: $PGID
# Derived data only: meta-core rebuilds its index cache from the truth file
# (metacore/db/meta-core.db, which IS backed up). keys/ stays backed up.
backup:
exclude:
- metacore/db-cache/
webui-host: metaread-${domain}
webui-path: "/"
+25 -8
View File
@@ -60,7 +60,7 @@ services:
# peer count before suspecting the feeders.
# ---------------------------------------------------------------------------
metaread-search:
image: ghcr.io/worph/meta-search:1.2.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-search:1.3.2
container_name: metaread-search
# 2g, not the self-contained listing's 1g: on the shared core it indexes the
# gateway box's whole catalogue (~830 MiB steady state on watch.nsl.sh).
@@ -79,11 +79,19 @@ services:
# (beacon v2) instead of reading kv-leader.info off a shared
# volume. See docs/project-architecture/beacon-v2.md.
- ${DATA_ROOT:-/DATA}/AppData/metaread/search-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metaread/keys:/keys:rw
environment:
# Distinct from metawatch-search on the same core, so the two discovery
# peers do not register under one name.
SERVICE_NAME: "metaread-search"
META_SEARCH_PUBLIC_URL: "https://metareadsearch-${APP_DOMAIN}"
# Profiles are created in MetaWatch (it shares this box's meta-core), so MetaRead
# only signs in with an existing secret key. See META_READ_PROFILE_CREATION in
# the meta-read README.
META_READ_PROFILE_CREATION: "watch"
META_READ_WATCH_URL: "https://metawatch-${APP_DOMAIN}"
# glibc malloc: cap the per-thread arenas and hand freed memory back to
# the OS, so RSS comes down after a fan-out burst.
MALLOC_ARENA_MAX: "2"
@@ -106,6 +114,8 @@ services:
META_CORE_URL: "http://metacore-app:80"
BASE_URL: "http://metaread-search:3000"
INTERNAL_BASE_URL: "http://metaread-search:3000"
# Own claim-signing key (relayed claims are forwarded verbatim, never re-signed); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metaread-search.key"
TZ: "$TZ"
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:3000/health"]
@@ -127,7 +137,7 @@ services:
# User Data Layer.
# ---------------------------------------------------------------------------
metaread-app:
image: ghcr.io/worph/meta-read:1.0.9
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-read:1.5.1
container_name: metaread-app
hostname: metaread-app
restart: unless-stopped
@@ -149,6 +159,10 @@ services:
SERVICE_NAME: "meta-read"
META_SHARE_URL: "http://metashare-app:3000"
META_SEARCH_URL: "http://metaread-search:3000"
# The shared MetaCore, used ONLY to forward 🐛 bug reports to its inbox
# (/api/reports, read on MetaCore's dashboard → Reports). Unset hides the
# button. Reached over `pcs`, like metaread-search.
META_CORE_URL: "http://metacore-app:80"
# Browser-reachable topbar chips. Transport is the shared MetaShare app
# (its own AppShield gate); discovery is this stack's gate below.
META_SHARE_PUBLIC_URL: "https://metashare-${APP_DOMAIN}"
@@ -174,14 +188,14 @@ services:
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 3000}}"
caddy_1: metaread-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metaread-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 3000}}"
caddy_2: metaread-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 3000}}"
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaRead/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaRead/icon.png
networks:
- metaread
- pcs
@@ -203,7 +217,7 @@ services:
- 80
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metaread-search"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -211,7 +225,7 @@ services:
caddy_0: metareadsearch-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metareadsearch-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metareadsearch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metareadsearch-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -304,8 +318,8 @@ x-casaos:
title:
en_us: MetaRead (shared backend)
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaRead/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaRead/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaRead/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaRead/thumbnail.png
store_app_id: metareadshared
is_uncontrolled: false
@@ -356,6 +370,9 @@ x-compose-app:
- path: /DATA/AppData/metaread/search-data
user: $PUID
group: $PGID
- path: /DATA/AppData/metaread/keys
user: $PUID
group: $PGID
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metaread-${domain}
webui-path: "/"
+18 -9
View File
@@ -13,7 +13,7 @@ services:
# - 3000 HTTP API + dashboard (proxied through the hash-lock + Caddy)
# - 3001 plugin callback API — internal only, never published
metashare-app:
image: ghcr.io/worph/meta-share:2.4.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share:2.7.0
container_name: metashare-app
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of
# swap. The swarm, blockstore and torrent session moved to the plugins, so
@@ -42,6 +42,10 @@ services:
# host folder, which they mount too — so the tmp/ → cache/ rename(2) stays
# atomic. Layout unchanged from the monolith: existing caches carry over.
- ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw
# Claim-signing key (meta-core 2.0.0 claims model): the hull's identity on
# the claims it writes (content links, archive marks, pointer resolves).
# Config — backed up, deliberately NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metashare/keys:/keys:rw
environment:
# Service registration / neighbour announce.
@@ -51,6 +55,8 @@ services:
# Inter-peer fetch URL, announced in identify by the ipfs plugin. Same as
# BASE_URL in prod (other peers fetch via the public Caddy URL).
- INTERNAL_BASE_URL=https://metashare-$APP_DOMAIN
# Own claim-signing key; generated on first boot if missing.
- METAMESH_SIGNING_KEY_FILE=/keys/metashare-app.key
- TZ=$TZ
user: 0:0
@@ -86,7 +92,7 @@ services:
BACKEND_HOST: "metashare-app"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metashare-app
@@ -115,8 +121,8 @@ services:
caddy_0.6_handle: ""
caddy_0.6_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metashare-IP.nip.io (gateway TLS) ----
caddy_1: metashare-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metashare-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metashare-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metashare-app:3000"
@@ -218,12 +224,12 @@ x-casaos:
title:
en_us: MetaShare
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaShare/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaShare/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaShare/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaShare/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaShare/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaShare/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaShare/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaShare/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaShare/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaShare/thumbnail.png
index: /
store_app_id: metashare
@@ -276,6 +282,9 @@ x-compose-app:
- path: /DATA/AppData/metashare/data
user: $PUID
group: $PGID
- path: /DATA/AppData/metashare/keys
user: $PUID
group: $PGID
# Fetched content only: everything under these can be pulled again off the
# swarm/NNTP/HTTP (meta-share reclaim.rs, "cache means cache"). They are ~94G
# on a busy peer, so without this every backup — and Maison's pre-update
+19 -9
View File
@@ -4,7 +4,7 @@ services:
# Backend service. Reachable on the pcs network as `metasort-app`.
# Public ingress goes through the `metasort` hash-lock proxy below.
metasort-app:
image: ghcr.io/worph/meta-sort:1.0.12
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-sort:1.1.1
container_name: metasort-app
hostname: metasort-app
restart: unless-stopped
@@ -39,6 +39,11 @@ services:
- ${DATA_ROOT:-/DATA}/AppData/metasort/config/supervisord-metasort.conf:/etc/supervisor/conf.d/supervisord.conf:ro
- ${DATA_ROOT:-/DATA}/AppData/metasort/config/nginx-metasort.conf:/etc/nginx/nginx.conf:ro
# Signing keys (meta-core 2.0.0 claims model): metasort-app.key is
# meta-sort's own identity; plugins/<pluginId>.key are minted per plugin
# and injected into the plugin containers it spawns. Config — backed up.
- ${DATA_ROOT:-/DATA}/AppData/metasort/keys:/keys:rw
# Note: no /files mounts — files are accessed via WebDAV from MetaCore
# (Architecture V3). MetaCore is the single source of truth for media files.
@@ -61,6 +66,8 @@ services:
# Compose project label stamped on the plugin containers meta-sort spawns,
# so they group under one stack instead of floating loose.
- PLUGIN_STACK_NAME=metasort-plugins
# meta-sort's own claim-signing key; generated on first boot if missing.
- METAMESH_SIGNING_KEY_FILE=/keys/metasort-app.key
# Note: Runs as root for nginx, Redis, and file management
user: 0:0
@@ -89,7 +96,7 @@ services:
BACKEND_HOST: "metasort-app"
BACKEND_PORT: "80"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metasort-app
@@ -108,8 +115,8 @@ services:
caddy_0.1_handle: ""
caddy_0.1_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metasort-IP.nip.io (gateway TLS) ----
caddy_1: metasort-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metasort-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metasort-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metasort-app:80"
@@ -182,12 +189,12 @@ x-casaos:
title:
en_us: MetaSort
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaSort/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaSort/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaSort/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaSort/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaSort/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaSort/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaSort/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaSort/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaSort/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaSort/thumbnail.png
index: /
store_app_id: metasort
@@ -217,6 +224,9 @@ x-compose-app:
- path: /DATA/AppData/metasort/cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metasort/keys
user: $PUID
group: $PGID
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metasort-${domain}
webui-path: "/"
+5 -5
View File
@@ -15,7 +15,7 @@ defaults:
plugins:
file-info:
enabled: true
image: ghcr.io/worph/metamesh-plugin-file-info:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-file-info:1.1.0
instances: 1
resources:
memory: 128m
@@ -23,7 +23,7 @@ plugins:
ffmpeg:
enabled: true
image: ghcr.io/worph/metamesh-plugin-ffmpeg:1.0.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-ffmpeg:1.1.0
instances: 1
resources:
memory: 512m
@@ -31,7 +31,7 @@ plugins:
subtitle:
enabled: true
image: ghcr.io/worph/metamesh-plugin-subtitle:1.0.2
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-subtitle:1.1.0
instances: 1
resources:
memory: 128m
@@ -39,7 +39,7 @@ plugins:
subtitle-extractor:
enabled: true
image: ghcr.io/worph/metamesh-plugin-subtitle-extractor:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-subtitle-extractor:1.1.0
instances: 1
resources:
memory: 512m
@@ -48,7 +48,7 @@ plugins:
still-extractor:
enabled: true
image: ghcr.io/worph/metamesh-plugin-still-extractor:1.0.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/metamesh-plugin-still-extractor:1.1.0
instances: 1
resources:
memory: 512m
+7 -7
View File
@@ -2,7 +2,7 @@ name: metastremio
services:
metastremio:
image: ghcr.io/worph/meta-stremio:1.1.3
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-stremio:1.1.4
cpu_shares: 50
container_name: metastremio
restart: unless-stopped
@@ -45,7 +45,7 @@ services:
caddy_0: metastremio-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 7000}}"
caddy_1: metastremio-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metastremio-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 7000}}"
caddy_2: metastremio-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -107,12 +107,12 @@ x-casaos:
title:
en_us: MetaStremio
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaStremio/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaStremio/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaStremio/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaStremio/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaStremio/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaStremio/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaStremio/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaStremio/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaStremio/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaStremio/thumbnail.png
index: /
store_app_id: metastremio
+3 -3
View File
@@ -16,7 +16,7 @@ name: metatransportipfs
services:
metashare-ipfs:
image: ghcr.io/worph/meta-transport-ipfs:1.3.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-ipfs:1.3.4
container_name: metashare-ipfs
hostname: metashare-ipfs
restart: unless-stopped
@@ -121,8 +121,8 @@ x-casaos:
title:
en_us: MetaTransport · IPFS
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportIpfs/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportIpfs/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportIpfs/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportIpfs/thumbnail.png
store_app_id: metatransportipfs
is_uncontrolled: false
+3 -3
View File
@@ -16,7 +16,7 @@ name: metatransportnzb
services:
metashare-nzb:
image: ghcr.io/worph/meta-transport-nzb:1.3.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-nzb:1.4.1
container_name: metashare-nzb
hostname: metashare-nzb
restart: unless-stopped
@@ -98,8 +98,8 @@ x-casaos:
title:
en_us: MetaTransport · Usenet
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportNzb/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportNzb/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportNzb/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportNzb/thumbnail.png
store_app_id: metatransportnzb
is_uncontrolled: false
+3 -3
View File
@@ -16,7 +16,7 @@ name: metatransporttorrent
services:
metashare-torrent:
image: ghcr.io/worph/meta-transport-torrent:1.2.1
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-torrent:1.2.3
container_name: metashare-torrent
hostname: metashare-torrent
restart: unless-stopped
@@ -107,8 +107,8 @@ x-casaos:
title:
en_us: MetaTransport · BitTorrent
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportTorrent/icon.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaTransportTorrent/thumbnail.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportTorrent/icon.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaTransportTorrent/thumbnail.png
store_app_id: metatransporttorrent
is_uncontrolled: false
+4 -4
View File
@@ -50,10 +50,10 @@ another MetaShare archivist) must be reachable on the swarm. Install
| Image | Tag |
|-------|-----|
| `ghcr.io/worph/meta-watch` | `1.0.34` |
| `ghcr.io/worph/meta-search` | `1.1.0` |
| `ghcr.io/worph/meta-share` | `1.0.26` |
| `ghcr.io/worph/meta-core` | `1.0.12` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-watch` | `1.0.89` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-search` | `1.2.10` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share` | `2.6.2` |
| `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core` | `1.0.24` |
| `ghcr.io/yundera/appshield` | `2.0.9` |
Publish the `worph/*` tags before listing the app — `:latest` tracks the newest
+51 -17
View File
@@ -29,7 +29,7 @@ services:
metawatch-core:
# 1.0.1 carries the identity API (commit 52f5b5c) required for MetaWatch
# sign-in / keypair generation; 1.0.0 predates it.
image: ghcr.io/worph/meta-core:1.0.23
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-core:2.1.0.1
container_name: metawatch-core
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
# instead of swap. Mirrors the dev sub-stack limits.
@@ -44,6 +44,8 @@ services:
- 9000
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metawatch/metacore:/meta-core:rw
# (meta-core 2.0.0 keeps its rebuildable index cache at
# /meta-core/db-cache/cache.db inside this bind — excluded from backups.)
# Subtitle store: player-uploaded subtitles land in /files/plugin/subtitles
# (WebDAV PUT + POST /api/files/register, needs meta-core with that route).
# Plugin output only — no /files/watch mount, watcher stays off.
@@ -72,7 +74,7 @@ services:
# RSA-keyed bootstrap.libp2p.io nodes) and therefore to DISCOVER remote
# gateways via the kad `metamesh-gateway` provider namespace. Without it
# this peer only ever sees same-host mDNS peers.
image: ghcr.io/worph/meta-search:1.2.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-search:1.3.2
container_name: metawatch-search
# Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM
# instead of swap. Mirrors the dev sub-stack limits.
@@ -96,6 +98,9 @@ services:
# swarm. Without this mount both are on the container's writable layer and
# every image bump loses the prefs and re-fetches every poster.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/search-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/keys:/keys:rw
environment:
P2P_LISTEN: "/ip4/0.0.0.0/tcp/4001"
# Public IPFS DHT bootstraps by explicit /dns4/.../tcp/4001 (the nested
@@ -121,6 +126,8 @@ services:
SEARCH_TIMEOUT_SECS: "300"
META_CORE_URL: "http://metawatch-core:9000"
BASE_URL: "http://metawatch-search:3000"
# Own claim-signing key (relayed claims are forwarded verbatim, never re-signed); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metawatch-search.key"
# Renamed at the 1.1.0 bump (2026-08-26), as the old note here said to do:
# META_SHARE_PEER_API_URL was the pre-1.0.8 spelling and now only logs a
# deprecation warning. Do NOT set both.
@@ -157,7 +164,7 @@ services:
# MetaShare app's `metashare-<tier>` hostnames, which on a shared `pcs`
# would be ANOTHER hull's plugins writing to another /data).
# - 3000 HTTP API - 3001 plugin callback API (internal only)
image: ghcr.io/worph/meta-share:2.4.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-share:2.7.0
container_name: metawatch-share
# The swarm and blockstore moved to the ipfs plugin, so the hull needs far
# less than the monolith did.
@@ -179,6 +186,9 @@ services:
# hull's; ipfs/blocks.redb is the ipfs plugin's corner of the SAME folder
# (layout unchanged from 1.0.x, so an existing cache carries over).
- ${DATA_ROOT:-/DATA}/AppData/metawatch/share-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/keys:/keys:rw
environment:
META_CORE_URL: "http://metawatch-core:9000"
BASE_URL: "http://metawatch-share:3000"
@@ -186,6 +196,8 @@ services:
META_SHARE_PLUGIN_IPFS_URL: "http://metawatch-share-ipfs:3000"
META_SHARE_PLUGIN_TORRENT_URL: "off"
META_SHARE_PLUGIN_NZB_URL: "off"
# Own claim-signing key; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metawatch-share.key"
TZ: "$TZ"
depends_on:
metawatch-core:
@@ -205,7 +217,7 @@ services:
# mDNS, bitswap), the blockstore, gateway discovery and the peer directory
# the hull uses to forward Usenet cids. Waits up to 60 s for the hull's
# internal /health before opening blocks.redb, so no depends_on.
image: ghcr.io/worph/meta-transport-ipfs:1.3.0
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-transport-ipfs:1.3.4
container_name: metawatch-share-ipfs
hostname: metawatch-share-ipfs
restart: unless-stopped
@@ -250,8 +262,12 @@ services:
# My List + Continue Watching persist in /DATA/AppData/metawatch/data.
# ---------------------------------------------------------------------------
metawatch-app:
image: ghcr.io/worph/meta-watch:1.0.74
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-watch:1.2.2
container_name: metawatch-app
# Run as the PUID that Maison creates the app folders with (as the Shared
# variant does). The image default user (uid 10001) cannot write them on a
# fresh install: "create ipfs dir … Permission denied".
user: "1000:1000"
hostname: metawatch-app
restart: unless-stopped
cpu_shares: 30
@@ -264,6 +280,9 @@ services:
- 3000
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metawatch/data:/app/data
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/keys:/keys:rw
environment:
META_SHARE_URL: "http://metawatch-share:3000"
META_SEARCH_URL: "http://metawatch-search:3000"
@@ -275,6 +294,8 @@ services:
META_WATCH_SYNC_PEERS: "http://metawatch-search:3000"
# This box's own core — subtitle store only (uploads + curated matches).
META_CORE_URL: "http://metawatch-core:9000"
# Own claim-signing key for the subtitle-store claims it writes; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metawatch-app.key"
TZ: "$TZ"
depends_on:
metawatch-search:
@@ -310,7 +331,7 @@ services:
BACKEND_HOST: "metawatch-app"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metawatch-app
labels:
@@ -322,8 +343,8 @@ services:
caddy_0.1_handle: ""
caddy_0.1_handle.reverse_proxy: "{{upstreams 80}}"
# ---- metawatch-IP.nip.io (gateway TLS) ----
caddy_1: metawatch-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metawatch-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metawatch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.0_handle: "/health"
caddy_1.0_handle.reverse_proxy: "metawatch-app:3000"
@@ -359,7 +380,7 @@ services:
expose: ["80"]
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metawatch-share"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -367,7 +388,7 @@ services:
caddy_0: metawatchshare-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metawatchshare-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metawatchshare-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metawatchshare-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -388,7 +409,7 @@ services:
expose: ["80"]
environment:
OIDC_REGISTRAR_URL: "http://auth-registrar:9092"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
BACKEND_HOST: "metawatch-search"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
@@ -396,7 +417,7 @@ services:
caddy_0: metawatchsearch-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metawatchsearch-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metawatchsearch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metawatchsearch-${APP_PUBLIC_IP_DASH}.sslip.io
@@ -478,12 +499,12 @@ x-casaos:
title:
en_us: MetaWatch
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/icon.png
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/thumbnail.png
index: /
store_app_id: metawatch
@@ -526,6 +547,11 @@ x-compose-app:
- path: /DATA/AppData/metawatch/metacore
user: $PUID
group: $PGID
# meta-core 2.0.0 rebuildable index cache (default
# /meta-core/db-cache/cache.db). Excluded from backups below.
- path: /DATA/AppData/metawatch/metacore/db-cache
user: $PUID
group: $PGID
- path: /DATA/AppData/metawatch/search-data
user: $PUID
group: $PGID
@@ -541,6 +567,14 @@ x-compose-app:
- path: /DATA/AppData/metawatch/data
user: $PUID
group: $PGID
- path: /DATA/AppData/metawatch/keys
user: $PUID
group: $PGID
# Derived data only: meta-core rebuilds its index cache from the truth file
# (metacore/db/meta-core.db, which IS backed up). keys/ stays backed up.
backup:
exclude:
- metacore/db-cache/
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metawatch-${domain}
webui-path: "/"
+26 -13
View File
@@ -45,7 +45,7 @@ services:
# core of its own.
# ---------------------------------------------------------------------------
metawatch-search:
image: ghcr.io/worph/meta-search:1.2.7
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-search:1.3.2
container_name: metawatch-search
hostname: metawatch-search
restart: unless-stopped
@@ -71,6 +71,9 @@ services:
# swarm. Without this mount both are on the container's writable layer and
# every image bump loses the prefs and re-fetches every poster.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/search-data:/data:rw
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/keys:/keys:rw
environment:
P2P_LISTEN: "/ip4/0.0.0.0/tcp/4001"
# Public IPFS DHT bootstraps by explicit /dns4/.../tcp/4001 (the nested
@@ -93,6 +96,8 @@ services:
META_CORE_URL: "http://metacore-app:80"
BASE_URL: "http://metawatch-search:3000"
INTERNAL_BASE_URL: "http://metawatch-search:3000"
# Own claim-signing key (relayed claims are forwarded verbatim, never re-signed); generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metawatch-search.key"
TZ: "$TZ"
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:3000/health"]
@@ -115,7 +120,7 @@ services:
# owns the caddy_* labels directly and Caddy proxies straight to :3000.
# ---------------------------------------------------------------------------
metawatch-app:
image: ghcr.io/worph/meta-watch:1.0.74
image: ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/meta-watch:1.2.2
container_name: metawatch-app
hostname: metawatch-app
restart: unless-stopped
@@ -130,6 +135,9 @@ services:
- 3000
volumes:
- ${DATA_ROOT:-/DATA}/AppData/metawatch/data:/app/data
# Claim-signing keys (meta-core 2.0.0 claims model), one file per writer
# service in this stack. Config — backed up, NOT in backup.exclude.
- ${DATA_ROOT:-/DATA}/AppData/metawatch/keys:/keys:rw
environment:
# The STANDALONE MetaShare app — this variant ships no transport peer.
META_SHARE_URL: "http://metashare-app:3000"
@@ -143,6 +151,8 @@ services:
# variant has no private core: it writes to the standalone MetaCore app,
# which already mounts /files and runs the watcher.
META_CORE_URL: "http://metacore-app:80"
# Own claim-signing key for the subtitle-store claims it writes; generated on first boot if missing.
METAMESH_SIGNING_KEY_FILE: "/keys/metawatch-app.key"
TZ: "$TZ"
depends_on:
metawatch-search:
@@ -159,8 +169,8 @@ services:
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 3000}}"
# ---- metawatch-IP.nip.io (gateway TLS) ----
caddy_1: metawatch-${APP_PUBLIC_IP_DASH}.nip.io
# ---- metawatch-IP.<IP_ZONE> (gateway TLS) ----
caddy_1: metawatch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 3000}}"
@@ -168,7 +178,7 @@ services:
caddy_2: metawatch-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 3000}}"
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/icon.png
networks:
- metawatch
- pcs
@@ -197,7 +207,7 @@ services:
BACKEND_HOST: "metawatch-search"
BACKEND_PORT: "3000"
LISTEN_PORT: "80"
REDIRECT_HOST_SUFFIXES: "${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.nip.io,${APP_PUBLIC_IP_DASH}.sslip.io"
REDIRECT_HOST_SUFFIXES: "${APP_HOST_SUFFIXES:-${APP_DOMAIN},${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE},${APP_PUBLIC_IP_DASH}.sslip.io}"
depends_on:
- metawatch-search
labels:
@@ -205,14 +215,14 @@ services:
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metawatchsearch-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1: metawatchsearch-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metawatchsearch-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 80}}"
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/icon.png
networks:
- metawatch
- pcs
@@ -237,7 +247,7 @@ x-casaos:
tags: ["media", "needs-public-ip"]
developer: Aptero Team
hostname: metawatch-${APP_DOMAIN}
icon: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/icon.png
icon: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/icon.png
index: /
is_uncontrolled: false
main: metawatch-app
@@ -245,10 +255,10 @@ x-casaos:
scheme: https
store_app_id: metawatchshared
screenshot_link:
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-1.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-2.png
- https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/screenshot-3.png
thumbnail: https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/MetaWatch/thumbnail.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-1.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-2.png
- https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/screenshot-3.png
thumbnail: https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/MetaWatch/thumbnail.png
title:
en_us: MetaWatch (shared backend)
tagline:
@@ -346,6 +356,9 @@ x-compose-app:
- path: /DATA/AppData/metawatch/data
user: $PUID
group: $PGID
- path: /DATA/AppData/metawatch/keys
user: $PUID
group: $PGID
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metawatch-${domain}
webui-path: "/"
+11 -9
View File
@@ -11,14 +11,15 @@ that are *not* MetaMesh (Jellyfin, Nextcloud, MetaMCP — third-party
`metatool-ai` software despite the name, …) stay in `Worph/AppStore` and must
not be added here.
⚠ **Asset URLs are repo-scoped.** Everything in this repo must reference
`https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/{AppName}/`. A file
copied over from `Worph/AppStore` will carry the old
`.../gh/Worph/AppStore@main/...` URL and its icon will silently 404 in the store
⚠ **Asset URLs point at this repo on Gitea.** Everything in this repo must reference
`https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/{AppName}/`.
The GitHub repos are gone, so every jsDelivr `cdn.jsdelivr.net/gh/Worph/...` URL
(this repo's old ones, or `.../gh/Worph/AppStore@main/...` in a file copied over
from `Worph/AppStore`) 404s and the icon silently disappears from the store
listing. Grep after any import:
```bash
grep -rn 'gh/Worph/AppStore@main' Apps/ # must be empty
grep -rn 'cdn.jsdelivr.net/gh/Worph' Apps/ # must be empty
```
## Structure
@@ -39,10 +40,11 @@ grep -rn 'gh/Worph/AppStore@main' Apps/ # must be empty
- **Networking**: `expose`, not `ports`; main services join the external `pcs`
network for Caddy routing. Three caddy labels per public service:
`caddy_0` gateway domain (`appname-${APP_DOMAIN}`, `gateway_tls` import),
`caddy_1` nip.io, `caddy_2` sslip.io (Let's Encrypt, no import)
`caddy_1` `<app>-${APP_PUBLIC_IP_DASH}.${APP_IP_ZONE}` (the IP zone, `gateway_tls` import), `caddy_2` sslip.io (Let's Encrypt, no import)
- **`store_app_id`** is the lowercased app name (`MetaFeederTMDB` → `metafeedertmdb`)
- **Images**: `ghcr.io/worph/meta*` pinned to `:latest` on purpose; the Yundera
perimeter images (`nginx-hash-lock`, `appshield`) stay version-pinned
- **Images**: pulled from IPCR on watch.nsl.sh, `ipcr-watch.nsl.sh/ipns/metadec.eth/metadec.eth/<image>:<version>`,
pinned to explicit versions (built by each repo's `.gitea/workflows/` on gitea-watch.nsl.sh/metastar on `v*` tags;
ghcr.io/worph is no longer published). The Yundera perimeter images (`nginx-hash-lock`, `appshield`) stay on ghcr.io/yundera
- **Install order**: `MetaCore` first — every other app depends on it
- **Multi-language**: descriptions/taglines carry `en_us`, `fr_fr`, `es_es`, `zh_cn`, `ko_kr`, `de_de`
@@ -103,5 +105,5 @@ shared MetaPlugin app requires setting the variable explicitly.
```bash
docker compose -f Apps/{AppName}/docker-compose.yml config # compose validity
jq . category-list.json recommend-list.json featured-apps.json
grep -rn 'gh/Worph/AppStore@main' Apps/ # must be empty
grep -rn 'cdn.jsdelivr.net/gh/Worph' Apps/ # must be empty
```
+1 -1
View File
@@ -2,4 +2,4 @@
Refer to https://raw.githubusercontent.com/Yundera/AppStore/refs/heads/main/CONTRIBUTING.md
only difference is in this repos the links for assets and appstore are different
use https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/
use https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/
+5 -4
View File
@@ -11,7 +11,7 @@ collection.
In Yundera / CasaOS → App Store → *Add source*:
```
https://github.com/Worph/MetaAppStore/archive/refs/heads/main.zip
https://gitea-watch.nsl.sh/metastar/MetaAppStore/archive/main.zip
```
## What's in here
@@ -22,7 +22,7 @@ https://github.com/Worph/MetaAppStore/archive/refs/heads/main.zip
| Library | `MetaSort`, `MetaFuse`, `MetaStremio` |
| Network | `MetaShare` (content transport), `MetaGateway`, `MetaGatewayShared` |
| Clients | `MetaWatch`, `MetaWatchShared`, `MetaRead`, `MetaReadShared` |
| Feeders | `MetaFeederAniList`, `MetaFeederArxiv`, `MetaFeederEuropePMC`, `MetaFeederGiphy`, `MetaFeederGutenberg`, `MetaFeederInternetArchive`, `MetaFeederJamendo`, `MetaFeederMusicBrainz`, `MetaFeederOpenSubtitles`, `MetaFeederProwlarr`, `MetaFeederSciHub`, `MetaFeederSuwayomi`, `MetaFeederTMDB`, `MetaFeederTribler`, `MetaFeederUsenet`, `MetaFeederWikiCommons`, `MetaFeederYouTube` |
| Feeders | `MetaFeederAniList`, `MetaFeederArxiv`, `MetaFeederEuropePMC`, `MetaFeederGiphy`, `MetaFeederGutenberg`, `MetaFeederInternetArchive`, `MetaFeederJamendo`, `MetaFeederMusicBrainz`, `MetaFeederOpenSubtitles`, `MetaFeederProwlarr`, `MetaFeederSciHub`, `MetaFeederStremio`, `MetaFeederSuwayomi`, `MetaFeederTMDB`, `MetaFeederTribler`, `MetaFeederUsenet`, `MetaFeederWikiCommons`, `MetaFeederYouTube` |
| Plugins | `MetaPluginAnimeDetector`, `MetaPluginFFmpeg`, `MetaPluginFileInfo`, `MetaPluginFilenameParser`, `MetaPluginFullHash`, `MetaPluginJellyfinNFO`, `MetaPluginLanguage`, `MetaPluginOpenSubtitles`, `MetaPluginStillExtractor`, `MetaPluginSubtitle`, `MetaPluginSubtitleExtractor`, `MetaPluginTMDB` — headless enrichment workers, one per `metamesh-plugin-*` image |
`MetaCore` is the dependency of every other app — install it first.
@@ -40,10 +40,11 @@ tier `MetaFeederSuwayomi` reads) and **SegmentPlayer**.
## Assets
Icons and screenshots are served from jsDelivr:
Icons and screenshots are served by Gitea, as raw files of this repo (the GitHub
repo, and with it the jsDelivr `gh/Worph/...` URLs, is gone):
```
https://cdn.jsdelivr.net/gh/Worph/MetaAppStore@main/Apps/{AppName}/
https://gitea-watch.nsl.sh/metastar/MetaAppStore/raw/branch/main/Apps/{AppName}/
```
`psd-source/meta-icons-v2/` holds the procedural icon generator for the family —
+1
View File
@@ -127,6 +127,7 @@ APPS = {
"MetaFeederJamendo": ("JAMENDO", "note", ORANGE),
"MetaFeederMusicBrainz": ("MUSICBRAINZ", "disc", ORANGE),
"MetaFeederYouTube": ("YOUTUBE", "video", ORANGE),
"MetaFeederStremio": ("STREMIO", "play", ORANGE),
# MetaPlugin family — headless enrichment workers, blue ring.
"MetaPluginFileInfo": ("FILE INFO", "fileinfo", BLUE),
"MetaPluginFFmpeg": ("FFMPEG", "film", BLUE),
@@ -0,0 +1,209 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024">
<defs>
<linearGradient id="e0" gradientUnits="userSpaceOnUse" x1="783.1" y1="578.2" x2="783.4" y2="666.2"><stop offset="0" stop-color="#556dcf"/><stop offset="1" stop-color="#6364d1"/></linearGradient>
<linearGradient id="e1" gradientUnits="userSpaceOnUse" x1="783.4" y1="666.2" x2="636.7" y2="789.7"><stop offset="0" stop-color="#6364d1"/><stop offset="1" stop-color="#6c5dd2"/></linearGradient>
<linearGradient id="e2" gradientUnits="userSpaceOnUse" x1="835.6" y1="448.9" x2="783.1" y2="578.2"><stop offset="0" stop-color="#4479ce"/><stop offset="1" stop-color="#556dcf"/></linearGradient>
<linearGradient id="e3" gradientUnits="userSpaceOnUse" x1="783.1" y1="578.2" x2="836.5" y2="548.1"><stop offset="0" stop-color="#556dcf"/><stop offset="1" stop-color="#546ecf"/></linearGradient>
<linearGradient id="e4" gradientUnits="userSpaceOnUse" x1="734.9" y1="293.1" x2="835.6" y2="448.9"><stop offset="0" stop-color="#3695c6"/><stop offset="1" stop-color="#4479ce"/></linearGradient>
<linearGradient id="e5" gradientUnits="userSpaceOnUse" x1="520.6" y1="190.1" x2="426.4" y2="168.1"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#2bbbba"/></linearGradient>
<linearGradient id="e6" gradientUnits="userSpaceOnUse" x1="636.7" y1="789.7" x2="545.6" y2="836.8"><stop offset="0" stop-color="#6c5dd2"/><stop offset="1" stop-color="#6e5cd2"/></linearGradient>
<linearGradient id="e7" gradientUnits="userSpaceOnUse" x1="520.6" y1="190.1" x2="589.5" y2="173.7"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#2fb0be"/></linearGradient>
<linearGradient id="e8" gradientUnits="userSpaceOnUse" x1="589.5" y1="173.7" x2="734.9" y2="293.1"><stop offset="0" stop-color="#2fb0be"/><stop offset="1" stop-color="#3695c6"/></linearGradient>
<linearGradient id="e9" gradientUnits="userSpaceOnUse" x1="267.3" y1="260.5" x2="182.7" y2="382.3"><stop offset="0" stop-color="#2cb7bc"/><stop offset="1" stop-color="#30abbf"/></linearGradient>
<linearGradient id="e10" gradientUnits="userSpaceOnUse" x1="836.5" y1="548.1" x2="783.4" y2="666.2"><stop offset="0" stop-color="#546ecf"/><stop offset="1" stop-color="#6364d1"/></linearGradient>
<linearGradient id="e11" gradientUnits="userSpaceOnUse" x1="636.7" y1="789.7" x2="708.2" y2="763.4"><stop offset="0" stop-color="#6c5dd2"/><stop offset="1" stop-color="#6d5dd2"/></linearGradient>
<linearGradient id="e12" gradientUnits="userSpaceOnUse" x1="426.4" y1="168.1" x2="267.3" y2="260.5"><stop offset="0" stop-color="#2bbbba"/><stop offset="1" stop-color="#2cb7bc"/></linearGradient>
<linearGradient id="e13" gradientUnits="userSpaceOnUse" x1="182.7" y1="382.3" x2="166.7" y2="566.8"><stop offset="0" stop-color="#30abbf"/><stop offset="1" stop-color="#3890c7"/></linearGradient>
<linearGradient id="e14" gradientUnits="userSpaceOnUse" x1="783.4" y1="666.2" x2="708.2" y2="763.4"><stop offset="0" stop-color="#6364d1"/><stop offset="1" stop-color="#6d5dd2"/></linearGradient>
<linearGradient id="e15" gradientUnits="userSpaceOnUse" x1="835.6" y1="448.9" x2="836.5" y2="548.1"><stop offset="0" stop-color="#4479ce"/><stop offset="1" stop-color="#546ecf"/></linearGradient>
<linearGradient id="e16" gradientUnits="userSpaceOnUse" x1="734.9" y1="293.1" x2="760.3" y2="319.9"><stop offset="0" stop-color="#3695c6"/><stop offset="1" stop-color="#388fc8"/></linearGradient>
<linearGradient id="e17" gradientUnits="userSpaceOnUse" x1="358.4" y1="809.1" x2="545.6" y2="836.8"><stop offset="0" stop-color="#5d68d0"/><stop offset="1" stop-color="#6e5cd2"/></linearGradient>
<linearGradient id="e18" gradientUnits="userSpaceOnUse" x1="166.7" y1="566.8" x2="225.8" y2="701.1"><stop offset="0" stop-color="#3890c7"/><stop offset="1" stop-color="#437ace"/></linearGradient>
<linearGradient id="e19" gradientUnits="userSpaceOnUse" x1="734.9" y1="293.1" x2="674.0" y2="239.3"><stop offset="0" stop-color="#3695c6"/><stop offset="1" stop-color="#33a1c2"/></linearGradient>
<linearGradient id="e20" gradientUnits="userSpaceOnUse" x1="225.8" y1="701.1" x2="358.4" y2="809.1"><stop offset="0" stop-color="#437ace"/><stop offset="1" stop-color="#5d68d0"/></linearGradient>
<linearGradient id="e21" gradientUnits="userSpaceOnUse" x1="426.4" y1="168.1" x2="589.5" y2="173.7"><stop offset="0" stop-color="#2bbbba"/><stop offset="1" stop-color="#2fb0be"/></linearGradient>
<linearGradient id="e22" gradientUnits="userSpaceOnUse" x1="708.2" y1="763.4" x2="545.6" y2="836.8"><stop offset="0" stop-color="#6d5dd2"/><stop offset="1" stop-color="#6e5cd2"/></linearGradient>
<linearGradient id="e23" gradientUnits="userSpaceOnUse" x1="836.5" y1="548.1" x2="708.2" y2="763.4"><stop offset="0" stop-color="#546ecf"/><stop offset="1" stop-color="#6d5dd2"/></linearGradient>
<linearGradient id="e24" gradientUnits="userSpaceOnUse" x1="267.3" y1="260.5" x2="283.5" y2="265.3"><stop offset="0" stop-color="#2cb7bc"/><stop offset="1" stop-color="#2db6bc"/></linearGradient>
<linearGradient id="e25" gradientUnits="userSpaceOnUse" x1="283.5" y1="265.3" x2="182.7" y2="382.3"><stop offset="0" stop-color="#2db6bc"/><stop offset="1" stop-color="#30abbf"/></linearGradient>
<linearGradient id="e26" gradientUnits="userSpaceOnUse" x1="760.3" y1="319.9" x2="835.6" y2="448.9"><stop offset="0" stop-color="#388fc8"/><stop offset="1" stop-color="#4479ce"/></linearGradient>
<linearGradient id="e27" gradientUnits="userSpaceOnUse" x1="182.7" y1="382.3" x2="210.0" y2="412.0"><stop offset="0" stop-color="#30abbf"/><stop offset="1" stop-color="#32a5c1"/></linearGradient>
<linearGradient id="e28" gradientUnits="userSpaceOnUse" x1="426.4" y1="168.1" x2="283.5" y2="265.3"><stop offset="0" stop-color="#2bbbba"/><stop offset="1" stop-color="#2db6bc"/></linearGradient>
<linearGradient id="e29" gradientUnits="userSpaceOnUse" x1="835.6" y1="448.9" x2="794.7" y2="427.3"><stop offset="0" stop-color="#4479ce"/><stop offset="1" stop-color="#3e7dcd"/></linearGradient>
<linearGradient id="e30" gradientUnits="userSpaceOnUse" x1="545.6" y1="836.8" x2="592.7" y2="793.7"><stop offset="0" stop-color="#6e5cd2"/><stop offset="1" stop-color="#6a5fd2"/></linearGradient>
<linearGradient id="e31" gradientUnits="userSpaceOnUse" x1="426.4" y1="168.1" x2="521.2" y2="187.1"><stop offset="0" stop-color="#2bbbba"/><stop offset="1" stop-color="#2eb2bd"/></linearGradient>
<linearGradient id="e32" gradientUnits="userSpaceOnUse" x1="794.7" y1="427.3" x2="836.5" y2="548.1"><stop offset="0" stop-color="#3e7dcd"/><stop offset="1" stop-color="#546ecf"/></linearGradient>
<linearGradient id="e33" gradientUnits="userSpaceOnUse" x1="210.0" y1="412.0" x2="166.7" y2="566.8"><stop offset="0" stop-color="#32a5c1"/><stop offset="1" stop-color="#3890c7"/></linearGradient>
<linearGradient id="e34" gradientUnits="userSpaceOnUse" x1="589.5" y1="173.7" x2="521.2" y2="187.1"><stop offset="0" stop-color="#2fb0be"/><stop offset="1" stop-color="#2eb2bd"/></linearGradient>
<linearGradient id="e35" gradientUnits="userSpaceOnUse" x1="589.5" y1="173.7" x2="674.0" y2="239.3"><stop offset="0" stop-color="#2fb0be"/><stop offset="1" stop-color="#33a1c2"/></linearGradient>
<linearGradient id="e36" gradientUnits="userSpaceOnUse" x1="291.2" y1="705.5" x2="358.4" y2="809.1"><stop offset="0" stop-color="#4877ce"/><stop offset="1" stop-color="#5d68d0"/></linearGradient>
<linearGradient id="e37" gradientUnits="userSpaceOnUse" x1="225.8" y1="701.1" x2="291.2" y2="705.5"><stop offset="0" stop-color="#437ace"/><stop offset="1" stop-color="#4877ce"/></linearGradient>
<linearGradient id="e38" gradientUnits="userSpaceOnUse" x1="836.5" y1="548.1" x2="749.1" y2="617.9"><stop offset="0" stop-color="#546ecf"/><stop offset="1" stop-color="#596bd0"/></linearGradient>
<linearGradient id="e39" gradientUnits="userSpaceOnUse" x1="708.2" y1="763.4" x2="592.7" y2="793.7"><stop offset="0" stop-color="#6d5dd2"/><stop offset="1" stop-color="#6a5fd2"/></linearGradient>
<linearGradient id="e40" gradientUnits="userSpaceOnUse" x1="433.3" y1="760.0" x2="545.6" y2="836.8"><stop offset="0" stop-color="#5a6ad0"/><stop offset="1" stop-color="#6e5cd2"/></linearGradient>
<linearGradient id="e41" gradientUnits="userSpaceOnUse" x1="166.7" y1="566.8" x2="244.4" y2="570.5"><stop offset="0" stop-color="#3890c7"/><stop offset="1" stop-color="#398bc9"/></linearGradient>
<linearGradient id="e42" gradientUnits="userSpaceOnUse" x1="358.4" y1="809.1" x2="433.3" y2="760.0"><stop offset="0" stop-color="#5d68d0"/><stop offset="1" stop-color="#5a6ad0"/></linearGradient>
<linearGradient id="e43" gradientUnits="userSpaceOnUse" x1="244.4" y1="570.5" x2="225.8" y2="701.1"><stop offset="0" stop-color="#398bc9"/><stop offset="1" stop-color="#437ace"/></linearGradient>
<linearGradient id="e44" gradientUnits="userSpaceOnUse" x1="521.2" y1="187.1" x2="283.5" y2="265.3"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#2db6bc"/></linearGradient>
<linearGradient id="e45" gradientUnits="userSpaceOnUse" x1="749.1" y1="617.9" x2="708.2" y2="763.4"><stop offset="0" stop-color="#596bd0"/><stop offset="1" stop-color="#6d5dd2"/></linearGradient>
<linearGradient id="e46" gradientUnits="userSpaceOnUse" x1="674.0" y1="239.3" x2="760.3" y2="319.9"><stop offset="0" stop-color="#33a1c2"/><stop offset="1" stop-color="#388fc8"/></linearGradient>
<linearGradient id="e47" gradientUnits="userSpaceOnUse" x1="521.2" y1="187.1" x2="674.0" y2="239.3"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#33a1c2"/></linearGradient>
<linearGradient id="e48" gradientUnits="userSpaceOnUse" x1="283.5" y1="265.3" x2="210.0" y2="412.0"><stop offset="0" stop-color="#2db6bc"/><stop offset="1" stop-color="#32a5c1"/></linearGradient>
<linearGradient id="e49" gradientUnits="userSpaceOnUse" x1="760.3" y1="319.9" x2="794.7" y2="427.3"><stop offset="0" stop-color="#388fc8"/><stop offset="1" stop-color="#3e7dcd"/></linearGradient>
<linearGradient id="e50" gradientUnits="userSpaceOnUse" x1="749.1" y1="617.9" x2="592.7" y2="793.7"><stop offset="0" stop-color="#596bd0"/><stop offset="1" stop-color="#6a5fd2"/></linearGradient>
<linearGradient id="e51" gradientUnits="userSpaceOnUse" x1="794.7" y1="427.3" x2="749.1" y2="617.9"><stop offset="0" stop-color="#3e7dcd"/><stop offset="1" stop-color="#596bd0"/></linearGradient>
<linearGradient id="e52" gradientUnits="userSpaceOnUse" x1="433.3" y1="760.0" x2="592.7" y2="793.7"><stop offset="0" stop-color="#5a6ad0"/><stop offset="1" stop-color="#6a5fd2"/></linearGradient>
<linearGradient id="e53" gradientUnits="userSpaceOnUse" x1="210.0" y1="412.0" x2="244.4" y2="570.5"><stop offset="0" stop-color="#32a5c1"/><stop offset="1" stop-color="#398bc9"/></linearGradient>
<linearGradient id="e54" gradientUnits="userSpaceOnUse" x1="283.5" y1="265.3" x2="422.2" y2="284.1"><stop offset="0" stop-color="#2db6bc"/><stop offset="1" stop-color="#30aac0"/></linearGradient>
<linearGradient id="e55" gradientUnits="userSpaceOnUse" x1="291.2" y1="705.5" x2="433.3" y2="760.0"><stop offset="0" stop-color="#4877ce"/><stop offset="1" stop-color="#5a6ad0"/></linearGradient>
<linearGradient id="e56" gradientUnits="userSpaceOnUse" x1="521.2" y1="187.1" x2="422.2" y2="284.1"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#30aac0"/></linearGradient>
<linearGradient id="e57" gradientUnits="userSpaceOnUse" x1="760.3" y1="319.9" x2="632.4" y2="323.9"><stop offset="0" stop-color="#388fc8"/><stop offset="1" stop-color="#3697c5"/></linearGradient>
<linearGradient id="e58" gradientUnits="userSpaceOnUse" x1="244.4" y1="570.5" x2="291.2" y2="705.5"><stop offset="0" stop-color="#398bc9"/><stop offset="1" stop-color="#4877ce"/></linearGradient>
<linearGradient id="e59" gradientUnits="userSpaceOnUse" x1="283.5" y1="265.3" x2="318.3" y2="407.9"><stop offset="0" stop-color="#2db6bc"/><stop offset="1" stop-color="#349ec3"/></linearGradient>
<linearGradient id="e60" gradientUnits="userSpaceOnUse" x1="521.2" y1="187.1" x2="632.4" y2="323.9"><stop offset="0" stop-color="#2eb2bd"/><stop offset="1" stop-color="#3697c5"/></linearGradient>
<linearGradient id="e61" gradientUnits="userSpaceOnUse" x1="674.0" y1="239.3" x2="632.4" y2="323.9"><stop offset="0" stop-color="#33a1c2"/><stop offset="1" stop-color="#3697c5"/></linearGradient>
<linearGradient id="e62" gradientUnits="userSpaceOnUse" x1="794.7" y1="427.3" x2="724.0" y2="539.5"><stop offset="0" stop-color="#3e7dcd"/><stop offset="1" stop-color="#4b74ce"/></linearGradient>
<linearGradient id="e63" gradientUnits="userSpaceOnUse" x1="632.4" y1="323.9" x2="794.7" y2="427.3"><stop offset="0" stop-color="#3697c5"/><stop offset="1" stop-color="#3e7dcd"/></linearGradient>
<linearGradient id="e64" gradientUnits="userSpaceOnUse" x1="210.0" y1="412.0" x2="318.3" y2="407.9"><stop offset="0" stop-color="#32a5c1"/><stop offset="1" stop-color="#349ec3"/></linearGradient>
<linearGradient id="e65" gradientUnits="userSpaceOnUse" x1="534.6" y1="674.0" x2="592.7" y2="793.7"><stop offset="0" stop-color="#536fcf"/><stop offset="1" stop-color="#6a5fd2"/></linearGradient>
<linearGradient id="e66" gradientUnits="userSpaceOnUse" x1="724.0" y1="539.5" x2="749.1" y2="617.9"><stop offset="0" stop-color="#4b74ce"/><stop offset="1" stop-color="#596bd0"/></linearGradient>
<linearGradient id="e67" gradientUnits="userSpaceOnUse" x1="362.7" y1="624.2" x2="291.2" y2="705.5"><stop offset="0" stop-color="#407ccd"/><stop offset="1" stop-color="#4877ce"/></linearGradient>
<linearGradient id="e68" gradientUnits="userSpaceOnUse" x1="318.3" y1="407.9" x2="244.4" y2="570.5"><stop offset="0" stop-color="#349ec3"/><stop offset="1" stop-color="#398bc9"/></linearGradient>
<linearGradient id="e69" gradientUnits="userSpaceOnUse" x1="749.1" y1="617.9" x2="534.6" y2="674.0"><stop offset="0" stop-color="#596bd0"/><stop offset="1" stop-color="#536fcf"/></linearGradient>
<linearGradient id="e70" gradientUnits="userSpaceOnUse" x1="362.7" y1="624.2" x2="433.3" y2="760.0"><stop offset="0" stop-color="#407ccd"/><stop offset="1" stop-color="#5a6ad0"/></linearGradient>
<linearGradient id="e71" gradientUnits="userSpaceOnUse" x1="244.4" y1="570.5" x2="362.7" y2="624.2"><stop offset="0" stop-color="#398bc9"/><stop offset="1" stop-color="#407ccd"/></linearGradient>
<linearGradient id="e72" gradientUnits="userSpaceOnUse" x1="534.6" y1="674.0" x2="433.3" y2="760.0"><stop offset="0" stop-color="#536fcf"/><stop offset="1" stop-color="#5a6ad0"/></linearGradient>
<linearGradient id="e73" gradientUnits="userSpaceOnUse" x1="422.2" y1="284.1" x2="632.4" y2="323.9"><stop offset="0" stop-color="#30aac0"/><stop offset="1" stop-color="#3697c5"/></linearGradient>
<linearGradient id="e74" gradientUnits="userSpaceOnUse" x1="632.4" y1="323.9" x2="724.0" y2="539.5"><stop offset="0" stop-color="#3697c5"/><stop offset="1" stop-color="#4b74ce"/></linearGradient>
<linearGradient id="e75" gradientUnits="userSpaceOnUse" x1="422.2" y1="284.1" x2="318.3" y2="407.9"><stop offset="0" stop-color="#30aac0"/><stop offset="1" stop-color="#349ec3"/></linearGradient>
<linearGradient id="e76" gradientUnits="userSpaceOnUse" x1="724.0" y1="539.5" x2="534.6" y2="674.0"><stop offset="0" stop-color="#4b74ce"/><stop offset="1" stop-color="#536fcf"/></linearGradient>
<linearGradient id="e77" gradientUnits="userSpaceOnUse" x1="318.3" y1="407.9" x2="362.7" y2="624.2"><stop offset="0" stop-color="#349ec3"/><stop offset="1" stop-color="#407ccd"/></linearGradient>
<linearGradient id="e78" gradientUnits="userSpaceOnUse" x1="362.7" y1="624.2" x2="534.6" y2="674.0"><stop offset="0" stop-color="#407ccd"/><stop offset="1" stop-color="#536fcf"/></linearGradient>
<linearGradient id="e79" gradientUnits="userSpaceOnUse" x1="422.2" y1="284.1" x2="537.1" y2="463.0"><stop offset="0" stop-color="#30aac0"/><stop offset="1" stop-color="#3a88ca"/></linearGradient>
<linearGradient id="e80" gradientUnits="userSpaceOnUse" x1="537.1" y1="463.0" x2="724.0" y2="539.5"><stop offset="0" stop-color="#3a88ca"/><stop offset="1" stop-color="#4b74ce"/></linearGradient>
<linearGradient id="e81" gradientUnits="userSpaceOnUse" x1="632.4" y1="323.9" x2="537.1" y2="463.0"><stop offset="0" stop-color="#3697c5"/><stop offset="1" stop-color="#3a88ca"/></linearGradient>
<linearGradient id="e82" gradientUnits="userSpaceOnUse" x1="318.3" y1="407.9" x2="537.1" y2="463.0"><stop offset="0" stop-color="#349ec3"/><stop offset="1" stop-color="#3a88ca"/></linearGradient>
<linearGradient id="e83" gradientUnits="userSpaceOnUse" x1="537.1" y1="463.0" x2="362.7" y2="624.2"><stop offset="0" stop-color="#3a88ca"/><stop offset="1" stop-color="#407ccd"/></linearGradient>
<linearGradient id="e84" gradientUnits="userSpaceOnUse" x1="537.1" y1="463.0" x2="534.6" y2="674.0"><stop offset="0" stop-color="#3a88ca"/><stop offset="1" stop-color="#536fcf"/></linearGradient>
</defs>
<rect width="1024" height="1024" fill="#fefefe"/>
<line x1="783.1" y1="578.2" x2="783.4" y2="666.2" stroke="url(#e0)" stroke-width="8.3" stroke-linecap="round"/>
<line x1="783.4" y1="666.2" x2="636.7" y2="789.7" stroke="url(#e1)" stroke-width="8.4" stroke-linecap="round"/>
<line x1="835.6" y1="448.9" x2="783.1" y2="578.2" stroke="url(#e2)" stroke-width="8.4" stroke-linecap="round"/>
<line x1="783.1" y1="578.2" x2="836.5" y2="548.1" stroke="url(#e3)" stroke-width="8.4" stroke-linecap="round"/>
<line x1="734.9" y1="293.1" x2="835.6" y2="448.9" stroke="url(#e4)" stroke-width="8.5" stroke-linecap="round"/>
<line x1="520.6" y1="190.1" x2="426.4" y2="168.1" stroke="url(#e5)" stroke-width="8.5" stroke-linecap="round"/>
<line x1="636.7" y1="789.7" x2="545.6" y2="836.8" stroke="url(#e6)" stroke-width="8.5" stroke-linecap="round"/>
<line x1="520.6" y1="190.1" x2="589.5" y2="173.7" stroke="url(#e7)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="589.5" y1="173.7" x2="734.9" y2="293.1" stroke="url(#e8)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="267.3" y1="260.5" x2="182.7" y2="382.3" stroke="url(#e9)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="836.5" y1="548.1" x2="783.4" y2="666.2" stroke="url(#e10)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="636.7" y1="789.7" x2="708.2" y2="763.4" stroke="url(#e11)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="426.4" y1="168.1" x2="267.3" y2="260.5" stroke="url(#e12)" stroke-width="8.6" stroke-linecap="round"/>
<line x1="182.7" y1="382.3" x2="166.7" y2="566.8" stroke="url(#e13)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="783.4" y1="666.2" x2="708.2" y2="763.4" stroke="url(#e14)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="835.6" y1="448.9" x2="836.5" y2="548.1" stroke="url(#e15)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="734.9" y1="293.1" x2="760.3" y2="319.9" stroke="url(#e16)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="358.4" y1="809.1" x2="545.6" y2="836.8" stroke="url(#e17)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="166.7" y1="566.8" x2="225.8" y2="701.1" stroke="url(#e18)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="734.9" y1="293.1" x2="674.0" y2="239.3" stroke="url(#e19)" stroke-width="8.7" stroke-linecap="round"/>
<line x1="225.8" y1="701.1" x2="358.4" y2="809.1" stroke="url(#e20)" stroke-width="8.8" stroke-linecap="round"/>
<line x1="426.4" y1="168.1" x2="589.5" y2="173.7" stroke="url(#e21)" stroke-width="8.8" stroke-linecap="round"/>
<line x1="708.2" y1="763.4" x2="545.6" y2="836.8" stroke="url(#e22)" stroke-width="8.8" stroke-linecap="round"/>
<line x1="836.5" y1="548.1" x2="708.2" y2="763.4" stroke="url(#e23)" stroke-width="8.8" stroke-linecap="round"/>
<line x1="267.3" y1="260.5" x2="283.5" y2="265.3" stroke="url(#e24)" stroke-width="8.8" stroke-linecap="round"/>
<line x1="283.5" y1="265.3" x2="182.7" y2="382.3" stroke="url(#e25)" stroke-width="8.9" stroke-linecap="round"/>
<line x1="760.3" y1="319.9" x2="835.6" y2="448.9" stroke="url(#e26)" stroke-width="8.9" stroke-linecap="round"/>
<line x1="182.7" y1="382.3" x2="210.0" y2="412.0" stroke="url(#e27)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="426.4" y1="168.1" x2="283.5" y2="265.3" stroke="url(#e28)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="835.6" y1="448.9" x2="794.7" y2="427.3" stroke="url(#e29)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="545.6" y1="836.8" x2="592.7" y2="793.7" stroke="url(#e30)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="426.4" y1="168.1" x2="521.2" y2="187.1" stroke="url(#e31)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="794.7" y1="427.3" x2="836.5" y2="548.1" stroke="url(#e32)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="210.0" y1="412.0" x2="166.7" y2="566.8" stroke="url(#e33)" stroke-width="9.0" stroke-linecap="round"/>
<line x1="589.5" y1="173.7" x2="521.2" y2="187.1" stroke="url(#e34)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="589.5" y1="173.7" x2="674.0" y2="239.3" stroke="url(#e35)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="291.2" y1="705.5" x2="358.4" y2="809.1" stroke="url(#e36)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="225.8" y1="701.1" x2="291.2" y2="705.5" stroke="url(#e37)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="836.5" y1="548.1" x2="749.1" y2="617.9" stroke="url(#e38)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="708.2" y1="763.4" x2="592.7" y2="793.7" stroke="url(#e39)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="433.3" y1="760.0" x2="545.6" y2="836.8" stroke="url(#e40)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="166.7" y1="566.8" x2="244.4" y2="570.5" stroke="url(#e41)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="358.4" y1="809.1" x2="433.3" y2="760.0" stroke="url(#e42)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="244.4" y1="570.5" x2="225.8" y2="701.1" stroke="url(#e43)" stroke-width="9.1" stroke-linecap="round"/>
<line x1="521.2" y1="187.1" x2="283.5" y2="265.3" stroke="url(#e44)" stroke-width="9.2" stroke-linecap="round"/>
<line x1="749.1" y1="617.9" x2="708.2" y2="763.4" stroke="url(#e45)" stroke-width="9.2" stroke-linecap="round"/>
<line x1="674.0" y1="239.3" x2="760.3" y2="319.9" stroke="url(#e46)" stroke-width="9.2" stroke-linecap="round"/>
<line x1="521.2" y1="187.1" x2="674.0" y2="239.3" stroke="url(#e47)" stroke-width="9.2" stroke-linecap="round"/>
<line x1="283.5" y1="265.3" x2="210.0" y2="412.0" stroke="url(#e48)" stroke-width="9.2" stroke-linecap="round"/>
<line x1="760.3" y1="319.9" x2="794.7" y2="427.3" stroke="url(#e49)" stroke-width="9.3" stroke-linecap="round"/>
<line x1="749.1" y1="617.9" x2="592.7" y2="793.7" stroke="url(#e50)" stroke-width="9.4" stroke-linecap="round"/>
<line x1="794.7" y1="427.3" x2="749.1" y2="617.9" stroke="url(#e51)" stroke-width="9.4" stroke-linecap="round"/>
<line x1="433.3" y1="760.0" x2="592.7" y2="793.7" stroke="url(#e52)" stroke-width="9.4" stroke-linecap="round"/>
<line x1="210.0" y1="412.0" x2="244.4" y2="570.5" stroke="url(#e53)" stroke-width="9.4" stroke-linecap="round"/>
<line x1="283.5" y1="265.3" x2="422.2" y2="284.1" stroke="url(#e54)" stroke-width="9.4" stroke-linecap="round"/>
<line x1="291.2" y1="705.5" x2="433.3" y2="760.0" stroke="url(#e55)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="521.2" y1="187.1" x2="422.2" y2="284.1" stroke="url(#e56)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="760.3" y1="319.9" x2="632.4" y2="323.9" stroke="url(#e57)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="244.4" y1="570.5" x2="291.2" y2="705.5" stroke="url(#e58)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="283.5" y1="265.3" x2="318.3" y2="407.9" stroke="url(#e59)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="521.2" y1="187.1" x2="632.4" y2="323.9" stroke="url(#e60)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="674.0" y1="239.3" x2="632.4" y2="323.9" stroke="url(#e61)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="794.7" y1="427.3" x2="724.0" y2="539.5" stroke="url(#e62)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="632.4" y1="323.9" x2="794.7" y2="427.3" stroke="url(#e63)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="210.0" y1="412.0" x2="318.3" y2="407.9" stroke="url(#e64)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="534.6" y1="674.0" x2="592.7" y2="793.7" stroke="url(#e65)" stroke-width="9.5" stroke-linecap="round"/>
<line x1="724.0" y1="539.5" x2="749.1" y2="617.9" stroke="url(#e66)" stroke-width="9.6" stroke-linecap="round"/>
<line x1="362.7" y1="624.2" x2="291.2" y2="705.5" stroke="url(#e67)" stroke-width="9.6" stroke-linecap="round"/>
<line x1="318.3" y1="407.9" x2="244.4" y2="570.5" stroke="url(#e68)" stroke-width="9.6" stroke-linecap="round"/>
<line x1="749.1" y1="617.9" x2="534.6" y2="674.0" stroke="url(#e69)" stroke-width="9.6" stroke-linecap="round"/>
<line x1="362.7" y1="624.2" x2="433.3" y2="760.0" stroke="url(#e70)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="244.4" y1="570.5" x2="362.7" y2="624.2" stroke="url(#e71)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="534.6" y1="674.0" x2="433.3" y2="760.0" stroke="url(#e72)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="422.2" y1="284.1" x2="632.4" y2="323.9" stroke="url(#e73)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="632.4" y1="323.9" x2="724.0" y2="539.5" stroke="url(#e74)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="422.2" y1="284.1" x2="318.3" y2="407.9" stroke="url(#e75)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="724.0" y1="539.5" x2="534.6" y2="674.0" stroke="url(#e76)" stroke-width="9.7" stroke-linecap="round"/>
<line x1="318.3" y1="407.9" x2="362.7" y2="624.2" stroke="url(#e77)" stroke-width="9.8" stroke-linecap="round"/>
<line x1="362.7" y1="624.2" x2="534.6" y2="674.0" stroke="url(#e78)" stroke-width="9.8" stroke-linecap="round"/>
<line x1="422.2" y1="284.1" x2="537.1" y2="463.0" stroke="url(#e79)" stroke-width="9.8" stroke-linecap="round"/>
<line x1="537.1" y1="463.0" x2="724.0" y2="539.5" stroke="url(#e80)" stroke-width="9.8" stroke-linecap="round"/>
<line x1="632.4" y1="323.9" x2="537.1" y2="463.0" stroke="url(#e81)" stroke-width="9.8" stroke-linecap="round"/>
<line x1="318.3" y1="407.9" x2="537.1" y2="463.0" stroke="url(#e82)" stroke-width="9.9" stroke-linecap="round"/>
<line x1="537.1" y1="463.0" x2="362.7" y2="624.2" stroke="url(#e83)" stroke-width="9.9" stroke-linecap="round"/>
<line x1="537.1" y1="463.0" x2="534.6" y2="674.0" stroke="url(#e84)" stroke-width="9.9" stroke-linecap="round"/>
<circle cx="783.1" cy="578.2" r="18.4" fill="#556dcf"/>
<circle cx="520.6" cy="190.1" r="19.1" fill="#2eb2bd"/>
<circle cx="734.9" cy="293.1" r="12.0" fill="#3695c6"/>
<circle cx="636.7" cy="789.7" r="12.3" fill="#6c5dd2"/>
<circle cx="783.4" cy="666.2" r="12.7" fill="#6364d1"/>
<circle cx="267.3" cy="260.5" r="20.9" fill="#2cb7bc"/>
<circle cx="182.7" cy="382.3" r="21.6" fill="#30abbf"/>
<circle cx="835.6" cy="448.9" r="28.8" fill="#4479ce"/>
<circle cx="545.6" cy="836.8" r="13.9" fill="#6e5cd2"/>
<circle cx="166.7" cy="566.8" r="13.9" fill="#3890c7"/>
<circle cx="836.5" cy="548.1" r="29.3" fill="#546ecf"/>
<circle cx="358.4" cy="809.1" r="29.4" fill="#5d68d0"/>
<circle cx="225.8" cy="701.1" r="14.0" fill="#437ace"/>
<circle cx="426.4" cy="168.1" r="22.5" fill="#2bbbba"/>
<circle cx="589.5" cy="173.7" r="14.5" fill="#2fb0be"/>
<circle cx="708.2" cy="763.4" r="31.0" fill="#6d5dd2"/>
<circle cx="283.5" cy="265.3" r="15.7" fill="#2db6bc"/>
<circle cx="760.3" cy="319.9" r="15.8" fill="#388fc8"/>
<circle cx="521.2" cy="187.1" r="15.9" fill="#2eb2bd"/>
<circle cx="674.0" cy="239.3" r="33.5" fill="#33a1c2"/>
<circle cx="592.7" cy="793.7" r="25.8" fill="#6a5fd2"/>
<circle cx="794.7" cy="427.3" r="16.3" fill="#3e7dcd"/>
<circle cx="210.0" cy="412.0" r="16.3" fill="#32a5c1"/>
<circle cx="291.2" cy="705.5" r="34.7" fill="#4877ce"/>
<circle cx="749.1" cy="617.9" r="27.1" fill="#596bd0"/>
<circle cx="433.3" cy="760.0" r="35.8" fill="#5a6ad0"/>
<circle cx="244.4" cy="570.5" r="27.4" fill="#398bc9"/>
<circle cx="422.2" cy="284.1" r="28.3" fill="#30aac0"/>
<circle cx="724.0" cy="539.5" r="17.7" fill="#4b74ce"/>
<circle cx="632.4" cy="323.9" r="28.5" fill="#3697c5"/>
<circle cx="318.3" cy="407.9" r="28.8" fill="#349ec3"/>
<circle cx="362.7" cy="624.2" r="18.2" fill="#407ccd"/>
<circle cx="534.6" cy="674.0" r="18.3" fill="#536fcf"/>
<circle cx="537.1" cy="463.0" r="39.8" fill="#3a88ca"/>
<circle cx="770" cy="770" r="226" fill="#e8821e"/><circle cx="770" cy="770" r="208" fill="#2c3038"/><g transform="translate(690,642)"><polygon fill="#ffffff" points="46,6 46,122 140,64"/></g><text x="770" y="882" text-anchor="middle" font-family="DejaVu Sans, Helvetica, Arial, sans-serif" font-weight="bold" font-size="66.9" fill="#ffffff">STREMIO</text></svg>

After

Width:  |  Height:  |  Size: 28 KiB