diff --git a/Apps/MetaShare/docker-compose.yml b/Apps/MetaShare/docker-compose.yml index 4eaa064..e8bbdee 100644 --- a/Apps/MetaShare/docker-compose.yml +++ b/Apps/MetaShare/docker-compose.yml @@ -6,12 +6,14 @@ services: # # meta-share is the protocol-agnostic hull since 2.0.0: HTTP API + dashboard, # material index, seed manifest, eviction, playback focus, meta-core. The - # byte-moving protocols run as the three transport plugins below (the - # `meta_feeder_sdk::transport` contract) and share its data volume: + # byte-moving protocols are transport plugins — each its OWN store app since + # 2.1.0 (MetaTransportTorrent / MetaTransportNzb / MetaTransportIpfs), found + # by hostname (`metashare-:3000`) and managed live from the dashboard's + # Plugins view. A plugin app that isn't installed is simply skipped. # - 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.0.1 + image: ghcr.io/worph/meta-share:2.1.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 @@ -30,21 +32,18 @@ services: - 3001 # plugin callback API (internal) volumes: - # Operator settings (META_SHARE_CONFIG_DIR): settings.json holds the NNTP - # credentials and network endpoints. MUST be persisted (else lost on every - # image bump). The nzb and ipfs plugins mount it read-only. + # Operator settings (META_SHARE_CONFIG_DIR): settings.json holds the + # network endpoints and the plugin list. MUST be persisted (else lost on + # every image bump). Plugins keep their own settings in their own app. - ${DATA_ROOT:-/DATA}/AppData/metashare/config:/config:rw # The shared data volume (META_SHARE_DATA): cache/, tmp/, seeds.json and # material.redb are the hull's; bt-temp/ (torrent), tmp/ jobs (nzb) - # and ipfs/blocks.redb (ipfs) are the plugins' corners of the SAME mount — - # one mount, so the tmp/ → cache/ rename(2) stays atomic. Layout unchanged - # from the monolith: existing caches carry over. + # and ipfs/blocks.redb (ipfs) are the plugin apps' corners of the SAME + # 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 environment: - - META_SHARE_PLUGIN_TORRENT_URL=http://metashare-torrent:3000 - - META_SHARE_PLUGIN_NZB_URL=http://metashare-nzb:3000 - - META_SHARE_PLUGIN_IPFS_URL=http://metashare-ipfs:3000 # Service registration / neighbour announce. - BASE_URL=https://metashare-$APP_DOMAIN # meta-core ingestion — the local archivist's library. @@ -66,118 +65,6 @@ services: networks: - pcs - # BitTorrent tier (librqbit, streaming-only fork). Its peer listener must be - # host-published so the swarm can dial in (idle seeding without a dial storm). - metashare-torrent: - image: ghcr.io/worph/meta-transport-torrent:1.0.1 - container_name: metashare-torrent - hostname: metashare-torrent - restart: unless-stopped - mem_limit: 1g - memswap_limit: 1g - cpu_shares: 20 - stop_grace_period: 30s - expose: - - 3000 - ports: - - "4240:4240" - volumes: - - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw - environment: - - META_SHARE_HULL_URL=http://metashare-app:3001 - - TZ=$TZ - user: 0:0 - healthcheck: - test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] - interval: 10s - timeout: 3s - retries: 10 - start_period: 30s - networks: - - pcs - - # Usenet tier (NNTP, yEnc, par2/RAR). Reads the NNTP credentials from the - # hull's settings.json; the hull restarts it when they change. - metashare-nzb: - image: ghcr.io/worph/meta-transport-nzb:1.0.1 - container_name: metashare-nzb - hostname: metashare-nzb - restart: unless-stopped - mem_limit: 3g - memswap_limit: 3g - cpu_shares: 20 - stop_grace_period: 30s - expose: - - 3000 - volumes: - - ${DATA_ROOT:-/DATA}/AppData/metashare/config:/config:ro - - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw - environment: - - META_SHARE_HULL_URL=http://metashare-app:3001 - - TZ=$TZ - user: 0:0 - healthcheck: - test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] - interval: 10s - timeout: 3s - retries: 10 - start_period: 30s - networks: - - pcs - - # IPFS tier: the libp2p host (identify/kad/mdns/bitswap), the blockstore and - # bitswap ingress. libp2p TCP must be host-published — Caddy can't proxy it and - # other peers' kad lookups dial the public multiaddr directly. - metashare-ipfs: - image: ghcr.io/worph/meta-transport-ipfs:1.0.1 - container_name: metashare-ipfs - hostname: metashare-ipfs - restart: unless-stopped - # The blockstore's redb page cache + the swarm live here now. - mem_limit: 2g - memswap_limit: 2g - cpu_shares: 20 - stop_grace_period: 30s - expose: - - 3000 - ports: - - "4001:4001" - volumes: - - ${DATA_ROOT:-/DATA}/AppData/metashare/config:/config:ro - - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw - environment: - - META_SHARE_HULL_URL=http://metashare-app:3001 - - P2P_LISTEN=/ip4/0.0.0.0/tcp/4001 - # Advertise the routable address so kad provider records + identify carry - # a dialable multiaddr. ${APP_PUBLIC_IPV4}, NOT ${APP_PUBLIC_IP}: on an - # IPv6-primary PCS the latter is v6 and `/ip4//…` won't parse (the - # plugin refuses to start rather than announce a lie). - - PUBLIC_ADDR=/ip4/${APP_PUBLIC_IPV4}/tcp/4001 - # Public IPFS DHT bootstraps by explicit /dns4/…/tcp/4001 (the nested - # dnsaddr form resolves to wss-only in some container resolvers), plus - # mars.i.ipfs.io — the four IPFS-Foundation bootstrappers can refuse an - # individual IP (watch.nsl.sh 2026-09-01: 2 connections → 126 with a fifth). - - KAD_BOOTSTRAP_PEERS=/dns4/sg1.bootstrap.libp2p.io/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt,/dns4/sv15.bootstrap.libp2p.io/tcp/4001/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN,/dns4/ny5.bootstrap.libp2p.io/tcp/4001/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa,/dns4/am6.bootstrap.libp2p.io/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb,/dns4/mars.i.ipfs.io/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ - # Seed fallbacks when the hull's settings.json doesn't exist yet. - - META_CORE_URL=http://metacore-app:80 - - INTERNAL_BASE_URL=https://metashare-$APP_DOMAIN - - TZ=$TZ - user: 0:0 - # The hull migrates its material index out of ipfs/blocks.redb on its first - # 2.x boot; redb is single-process, so the plugin waits for it. - depends_on: - metashare-app: - condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] - interval: 10s - timeout: 3s - retries: 10 - start_period: 30s - networks: - - pcs - - # OIDC perimeter for the MetaShare dashboard. Self-registers as an OIDC client # with the platform's auth-registrar on first login (no secrets to manage). # @@ -280,7 +167,7 @@ x-casaos: # `needs-public-ip` is the reserved functional tag: this app publishes a raw # libp2p TCP port that remote peers must dial inbound. Behind CGNAT or the # mesh-router tunnel it still installs and starts, but peers cannot reach it. - tags: ["media", "needs-public-ip"] + tags: ["media"] developer: Aptero Team description: @@ -348,16 +235,19 @@ x-casaos: en_us: | **Requires MetaCore** - Install MetaCore first. - **Port 4001 must be reachable from the public internet.** MetaShare's libp2p - TCP listener is host-published on port 4001 so other archivists' peers - (and the public IPFS kad-DHT) can dial this node directly. If your Yundera - host is behind a strict firewall, open TCP/4001 inbound — without it, this - peer can still *find* others but won't be findable by them. + **Then install the transport plugins you want** — each is its own app: + **MetaTransport · IPFS** (the mesh: peers, seeding — install this one), + **MetaTransport · BitTorrent** and **MetaTransport · Usenet**. MetaShare + picks each up within ~10 s; see and configure them in the dashboard's + **Plugins** view. Without any plugin MetaShare can fetch nothing. + + **Ports** are published by the plugin apps, not here: 4001 (IPFS) must be + reachable from the internet so other peers can dial you; 4240 (BitTorrent) + for seeding. **Cohort scoping (optional).** Out of the box, MetaShare joins the global `metamesh-share-default` cohort. To run a private group of archivists, - change `KAD_NAMESPACE` to a shared secret string on every node in the - group — only nodes with the matching namespace will see each other. + set the same namespace on every node: **Plugins → ipfs → configure**. **POC status.** v0.2 has an in-memory record store (rebuilt from MetaCore on every restart, ~2.5s for ~500 records) and no announcement signing yet. diff --git a/Apps/MetaTransportIpfs/docker-compose.yml b/Apps/MetaTransportIpfs/docker-compose.yml new file mode 100644 index 0000000..b2e29a3 --- /dev/null +++ b/Apps/MetaTransportIpfs/docker-compose.yml @@ -0,0 +1,176 @@ +name: metatransportipfs + +# One of MetaShare's transport plugins (meta-transport-ipfs). MetaShare (the +# hull) reaches it at http://metashare-ipfs:3000 over `pcs` — the default entry +# in its plugin list — and probes it every 10 s, so installing or removing this +# app takes effect with no other step. Manage it from MetaShare → Plugins. +# +# It shares MetaShare's data volume (same /data layout the monolith used: the +# `tmp/` → `cache/` promote is one rename(2), and the hull reads plugin-written +# files directly). Its own settings live in its state dir (config.json), edited +# through MetaShare's dashboard. + +services: + metashare-ipfs: + image: ghcr.io/worph/meta-transport-ipfs:1.1.0 + container_name: metashare-ipfs + hostname: metashare-ipfs + restart: unless-stopped + cpu_shares: 20 + # Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of swap. + mem_limit: 2g + memswap_limit: 2g + # Clean redb / session shutdown on SIGTERM before docker escalates. + stop_grace_period: 30s + # Root, like MetaShare: the shared data volume is root-owned. + user: 0:0 + expose: + - 3000 # transport contract (internal, reached by MetaShare only) + # libp2p TCP must be host-published: other peers' kad-DHT lookups dial + # the public multiaddr directly, and Caddy cannot proxy it (not HTTP). + ports: + - "4001:4001" + volumes: + - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw + - ${DATA_ROOT:-/DATA}/AppData/metatransportipfs/state:/state:rw + environment: + - META_SHARE_HULL_URL=http://metashare-app:3001 + # Advertise the routable address so provider records + identify carry a + # dialable multiaddr. ${APP_PUBLIC_IPV4}, NOT ${APP_PUBLIC_IP}: on an + # IPv6-primary PCS the latter holds a v6 address, and /ip4//… is not a + # parseable multiaddr (the plugin refuses to start rather than announce a lie). + - PUBLIC_ADDR=/ip4/${APP_PUBLIC_IPV4}/tcp/4001 + # Public IPFS DHT bootstraps by explicit /dns4/.../tcp/4001 (the nested + # dnsaddr default resolves to wss-only in some container resolvers), plus + # mars.i.ipfs.io as a fifth in case the foundation four refuse this IP. + # Editable later from MetaShare → Plugins → ipfs → configure. + - KAD_BOOTSTRAP_PEERS=/dns4/sg1.bootstrap.libp2p.io/tcp/4001/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt,/dns4/sv15.bootstrap.libp2p.io/tcp/4001/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN,/dns4/ny5.bootstrap.libp2p.io/tcp/4001/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa,/dns4/am6.bootstrap.libp2p.io/tcp/4001/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb,/dns4/mars.i.ipfs.io/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ + - TZ=$TZ + healthcheck: + test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] + interval: 10s + timeout: 3s + retries: 10 + start_period: 30s + networks: + - metatransportipfs + - pcs + + # OIDC perimeter in front of the plugin's own config page (the tile link). + # MetaShare's dashboard embeds the same page through its own proxy. + metatransportipfs: + image: ghcr.io/yundera/appshield:2.0.9 + cpu_shares: 80 + container_name: metatransportipfs + hostname: metatransportipfs + restart: unless-stopped + user: "0:0" + 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" + BACKEND_HOST: "metashare-ipfs" + BACKEND_PORT: "3000" + LISTEN_PORT: "80" + labels: + caddy_0: metatransportipfs-${APP_DOMAIN} + caddy_0.import: gateway_tls + caddy_0.reverse_proxy: "{{upstreams 80}}" + caddy_1: metatransportipfs-${APP_PUBLIC_IP_DASH}.nip.io + caddy_1.import: gateway_tls + caddy_1.reverse_proxy: "{{upstreams 80}}" + caddy_2: metatransportipfs-${APP_PUBLIC_IP_DASH}.sslip.io + caddy_2.reverse_proxy: "{{upstreams 80}}" + depends_on: + - metashare-ipfs + networks: + - metatransportipfs + - pcs + +networks: + metatransportipfs: + name: metatransportipfs + driver: bridge + pcs: + name: ${APP_NET:-pcs} + external: true + +x-casaos: + architectures: + - amd64 + - arm64 + author: Worph Team + category: Media + tags: ["media", "needs-public-ip"] + developer: Aptero Team + main: metatransportipfs + webui_port: 80 + index: /config + + description: + en_us: | + **IPFS transport for MetaShare — the mesh itself.** + + Runs MetaShare's libp2p node: peer discovery (public IPFS DHT, mDNS on the + LAN), bitswap block exchange, and seeding of your library and of what you + fetched, without a second copy on disk. It is also how MetaShare finds the + gateways on the mesh. + + **One of MetaShare's transport plugins** — without it MetaShare can still + use BitTorrent and Usenet, but has no swarm. Configure it from + **MetaShare → Plugins → ipfs → configure** (cohort namespace, bootstrap + peers, DHT announce). + + **Requires:** **MetaShare** (it shares MetaShare's storage). + + **Port 4001 must be reachable from the internet** so other peers can dial + you. Behind CGNAT it still works, but peers cannot reach you. + + fr_fr: | + **Transport IPFS pour MetaShare — le mesh lui-même.** + + Fait tourner le nœud libp2p de MetaShare : découverte des pairs (DHT IPFS + public, mDNS sur le LAN), échange de blocs bitswap et partage de votre + bibliothèque sans seconde copie. C'est aussi par lui que MetaShare trouve les + passerelles du mesh. + + **Un des plugins de transport de MetaShare.** Réglages dans + **MetaShare → Plugins → ipfs → configure**. + + **Nécessite :** **MetaShare**. Le **port 4001** doit être joignable depuis + Internet. + + tagline: + en_us: IPFS for MetaShare — find and share content with peers by CID + fr_fr: IPFS pour MetaShare — trouver et partager du contenu par CID + + 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 + + store_app_id: metatransportipfs + is_uncontrolled: false + + tips: + before_install: + en_us: | + **Install MetaShare first** — this plugin shares its storage and is + driven by it. MetaShare picks it up automatically within ~10 s; check + **MetaShare → Plugins**, where it shows as *live*. + + Settings: **MetaShare → Plugins → ipfs → configure** (or this app's own + tile). Saving restarts the plugin to apply. + +# Maison (Yundera dashboard) configuration. Read in preference to x-casaos. +x-compose-app: + schema_version: 2 + folders: + - path: /DATA/AppData/metatransportipfs/state + user: $PUID + group: $PGID + # Same string as the caddy_0 label, so the tile link and the route agree. + webui-host: metatransportipfs-${domain} + webui-path: "/config" diff --git a/Apps/MetaTransportIpfs/icon.png b/Apps/MetaTransportIpfs/icon.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportIpfs/icon.png differ diff --git a/Apps/MetaTransportIpfs/thumbnail.png b/Apps/MetaTransportIpfs/thumbnail.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportIpfs/thumbnail.png differ diff --git a/Apps/MetaTransportNzb/docker-compose.yml b/Apps/MetaTransportNzb/docker-compose.yml new file mode 100644 index 0000000..9542491 --- /dev/null +++ b/Apps/MetaTransportNzb/docker-compose.yml @@ -0,0 +1,158 @@ +name: metatransportnzb + +# One of MetaShare's transport plugins (meta-transport-nzb). MetaShare (the +# hull) reaches it at http://metashare-nzb:3000 over `pcs` — the default entry +# in its plugin list — and probes it every 10 s, so installing or removing this +# app takes effect with no other step. Manage it from MetaShare → Plugins. +# +# It shares MetaShare's data volume (same /data layout the monolith used: the +# `tmp/` → `cache/` promote is one rename(2), and the hull reads plugin-written +# files directly). Its own settings live in its state dir (config.json), edited +# through MetaShare's dashboard. + +services: + metashare-nzb: + image: ghcr.io/worph/meta-transport-nzb:1.1.0 + container_name: metashare-nzb + hostname: metashare-nzb + restart: unless-stopped + cpu_shares: 20 + # Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of swap. + mem_limit: 3g + memswap_limit: 3g + # Clean redb / session shutdown on SIGTERM before docker escalates. + stop_grace_period: 30s + # Root, like MetaShare: the shared data volume is root-owned. + user: 0:0 + expose: + - 3000 # transport contract (internal, reached by MetaShare only) + volumes: + - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw + - ${DATA_ROOT:-/DATA}/AppData/metatransportnzb/state:/state:rw + environment: + - META_SHARE_HULL_URL=http://metashare-app:3001 + - TZ=$TZ + healthcheck: + test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] + interval: 10s + timeout: 3s + retries: 10 + start_period: 30s + networks: + - metatransportnzb + - pcs + + # OIDC perimeter in front of the plugin's own config page (the tile link). + # MetaShare's dashboard embeds the same page through its own proxy. + metatransportnzb: + image: ghcr.io/yundera/appshield:2.0.9 + cpu_shares: 80 + container_name: metatransportnzb + hostname: metatransportnzb + restart: unless-stopped + user: "0:0" + 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" + BACKEND_HOST: "metashare-nzb" + BACKEND_PORT: "3000" + LISTEN_PORT: "80" + labels: + caddy_0: metatransportnzb-${APP_DOMAIN} + caddy_0.import: gateway_tls + caddy_0.reverse_proxy: "{{upstreams 80}}" + caddy_1: metatransportnzb-${APP_PUBLIC_IP_DASH}.nip.io + caddy_1.import: gateway_tls + caddy_1.reverse_proxy: "{{upstreams 80}}" + caddy_2: metatransportnzb-${APP_PUBLIC_IP_DASH}.sslip.io + caddy_2.reverse_proxy: "{{upstreams 80}}" + depends_on: + - metashare-nzb + networks: + - metatransportnzb + - pcs + +networks: + metatransportnzb: + name: metatransportnzb + driver: bridge + pcs: + name: ${APP_NET:-pcs} + external: true + +x-casaos: + architectures: + - amd64 + - arm64 + author: Worph Team + category: Media + tags: ["media"] + developer: Aptero Team + main: metatransportnzb + webui_port: 80 + index: /config + + description: + en_us: | + **Usenet (NZB) transport for MetaShare.** + + Streams Usenet releases progressively over **your NNTP provider** (yEnc, + par2 repair, RAR sets), so playback starts before the download ends. + + **One of MetaShare's transport plugins.** Configure your provider from + **MetaShare → Plugins → nzb → configure** (host, port, user, password, + connections). Without a provider it stays installed but idle, and MetaShare + forwards Usenet requests to a gateway on the mesh instead. An existing + MetaShare's provider settings are imported automatically on first start. + + **Requires:** **MetaShare** (it shares MetaShare's storage). Usenet is + fetch-only: this plugin does not seed. Uses up to ~3 GB RAM while a + release downloads. + + fr_fr: | + **Transport Usenet (NZB) pour MetaShare.** + + Lit les releases Usenet progressivement via **votre fournisseur NNTP** (yEnc, + réparation par2, archives RAR). + + **Un des plugins de transport de MetaShare.** Le fournisseur se configure dans + **MetaShare → Plugins → nzb → configure**. Les réglages d'un MetaShare existant + sont importés au premier démarrage. + + **Nécessite :** **MetaShare**. Jusqu'à ~3 Go de RAM pendant un téléchargement. + + tagline: + en_us: Usenet for MetaShare — stream NZB releases from your provider + fr_fr: Usenet pour MetaShare — lecture des releases NZB depuis votre fournisseur + + 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 + + store_app_id: metatransportnzb + is_uncontrolled: false + + tips: + before_install: + en_us: | + **Install MetaShare first** — this plugin shares its storage and is + driven by it. MetaShare picks it up automatically within ~10 s; check + **MetaShare → Plugins**, where it shows as *live*. + + Settings: **MetaShare → Plugins → nzb → configure** (or this app's own + tile). Saving restarts the plugin to apply. + +# Maison (Yundera dashboard) configuration. Read in preference to x-casaos. +x-compose-app: + schema_version: 2 + folders: + - path: /DATA/AppData/metatransportnzb/state + user: $PUID + group: $PGID + # Same string as the caddy_0 label, so the tile link and the route agree. + webui-host: metatransportnzb-${domain} + webui-path: "/config" diff --git a/Apps/MetaTransportNzb/icon.png b/Apps/MetaTransportNzb/icon.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportNzb/icon.png differ diff --git a/Apps/MetaTransportNzb/thumbnail.png b/Apps/MetaTransportNzb/thumbnail.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportNzb/thumbnail.png differ diff --git a/Apps/MetaTransportTorrent/docker-compose.yml b/Apps/MetaTransportTorrent/docker-compose.yml new file mode 100644 index 0000000..7c95dd9 --- /dev/null +++ b/Apps/MetaTransportTorrent/docker-compose.yml @@ -0,0 +1,167 @@ +name: metatransporttorrent + +# One of MetaShare's transport plugins (meta-transport-torrent). MetaShare (the +# hull) reaches it at http://metashare-torrent:3000 over `pcs` — the default entry +# in its plugin list — and probes it every 10 s, so installing or removing this +# app takes effect with no other step. Manage it from MetaShare → Plugins. +# +# It shares MetaShare's data volume (same /data layout the monolith used: the +# `tmp/` → `cache/` promote is one rename(2), and the hull reads plugin-written +# files directly). Its own settings live in its state dir (config.json), edited +# through MetaShare's dashboard. + +services: + metashare-torrent: + image: ghcr.io/worph/meta-transport-torrent:1.1.0 + container_name: metashare-torrent + hostname: metashare-torrent + restart: unless-stopped + cpu_shares: 20 + # Hard RAM cap, swap disabled (memswap_limit == mem_limit) → OOM instead of swap. + mem_limit: 1g + memswap_limit: 1g + # Clean redb / session shutdown on SIGTERM before docker escalates. + stop_grace_period: 30s + # Root, like MetaShare: the shared data volume is root-owned. + user: 0:0 + expose: + - 3000 # transport contract (internal, reached by MetaShare only) + # BitTorrent peer port (librqbit). Must stay published on the host so + # other peers can connect for the torrents this node seeds. + ports: + - "4240:4240" + volumes: + - ${DATA_ROOT:-/DATA}/AppData/metashare/data:/data:rw + - ${DATA_ROOT:-/DATA}/AppData/metatransporttorrent/state:/state:rw + environment: + - META_SHARE_HULL_URL=http://metashare-app:3001 + - TZ=$TZ + healthcheck: + test: ["CMD", "curl", "-sf", "http://localhost:3000/health"] + interval: 10s + timeout: 3s + retries: 10 + start_period: 30s + networks: + - metatransporttorrent + - pcs + + # OIDC perimeter in front of the plugin's own config page (the tile link). + # MetaShare's dashboard embeds the same page through its own proxy. + metatransporttorrent: + image: ghcr.io/yundera/appshield:2.0.9 + cpu_shares: 80 + container_name: metatransporttorrent + hostname: metatransporttorrent + restart: unless-stopped + user: "0:0" + 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" + BACKEND_HOST: "metashare-torrent" + BACKEND_PORT: "3000" + LISTEN_PORT: "80" + labels: + caddy_0: metatransporttorrent-${APP_DOMAIN} + caddy_0.import: gateway_tls + caddy_0.reverse_proxy: "{{upstreams 80}}" + caddy_1: metatransporttorrent-${APP_PUBLIC_IP_DASH}.nip.io + caddy_1.import: gateway_tls + caddy_1.reverse_proxy: "{{upstreams 80}}" + caddy_2: metatransporttorrent-${APP_PUBLIC_IP_DASH}.sslip.io + caddy_2.reverse_proxy: "{{upstreams 80}}" + depends_on: + - metashare-torrent + networks: + - metatransporttorrent + - pcs + +networks: + metatransporttorrent: + name: metatransporttorrent + driver: bridge + pcs: + name: ${APP_NET:-pcs} + external: true + +x-casaos: + architectures: + - amd64 + - arm64 + author: Worph Team + category: Media + tags: ["media"] + developer: Aptero Team + main: metatransporttorrent + webui_port: 80 + index: /config + + description: + en_us: | + **BitTorrent transport for MetaShare.** + + Lets MetaShare fetch torrent content **by byte range**, so a video starts + playing in seconds and seeks without downloading the whole file first. What + a viewer genuinely watches is completed in the background and **seeded** + back to the swarm (watch-commit). + + **One of MetaShare's transport plugins** — each protocol is its own app, so + you install only the ones you want, and a competing implementation can + replace this one. MetaShare finds it automatically once installed; manage + and configure it from **MetaShare → Plugins** (watch-commit, disk floor, + timeouts). + + **Requires:** **MetaShare** (it shares MetaShare's storage). + + **Port 4240 (TCP)** is published so other peers can reach the torrents + you seed. + + fr_fr: | + **Transport BitTorrent pour MetaShare.** + + Permet à MetaShare de récupérer un torrent **par plages d'octets** : la vidéo + démarre en quelques secondes et se parcourt sans tout télécharger. Ce qui est + réellement regardé est complété en arrière-plan puis **partagé** sur le swarm. + + **Un des plugins de transport de MetaShare** — chaque protocole est une app à + part. MetaShare le détecte dès l'installation ; gestion et réglages dans + **MetaShare → Plugins**. + + **Nécessite :** **MetaShare** (il partage son stockage). Le **port 4240** est + publié pour les pairs distants. + + tagline: + en_us: BitTorrent for MetaShare — stream torrents by range, seed what you watch + fr_fr: BitTorrent pour MetaShare — lecture de torrents par plages, partage de ce que vous regardez + + 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 + + store_app_id: metatransporttorrent + is_uncontrolled: false + + tips: + before_install: + en_us: | + **Install MetaShare first** — this plugin shares its storage and is + driven by it. MetaShare picks it up automatically within ~10 s; check + **MetaShare → Plugins**, where it shows as *live*. + + Settings: **MetaShare → Plugins → torrent → configure** (or this app's own + tile). Saving restarts the plugin to apply. + +# Maison (Yundera dashboard) configuration. Read in preference to x-casaos. +x-compose-app: + schema_version: 2 + folders: + - path: /DATA/AppData/metatransporttorrent/state + user: $PUID + group: $PGID + # Same string as the caddy_0 label, so the tile link and the route agree. + webui-host: metatransporttorrent-${domain} + webui-path: "/config" diff --git a/Apps/MetaTransportTorrent/icon.png b/Apps/MetaTransportTorrent/icon.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportTorrent/icon.png differ diff --git a/Apps/MetaTransportTorrent/thumbnail.png b/Apps/MetaTransportTorrent/thumbnail.png new file mode 100644 index 0000000..3595cad Binary files /dev/null and b/Apps/MetaTransportTorrent/thumbnail.png differ