Import the MetaMesh app family from Worph/AppStore

23 apps (MetaCore, the library/network/client tiers and 13 MetaFeeder*)
move out of the general-purpose Worph/AppStore into their own store so the
MetaMesh family releases on its own cadence.

- asset URLs repointed to cdn.jsdelivr.net/gh/Worph/MetaAppStore@main
- store scaffolding added (category/recommend/featured lists, licence,
  contributing, gitattributes)
- psd-source/meta-icons-v2 icon generator follows the apps

MetaMCP stays in Worph/AppStore: it is third-party metatool-ai software,
not part of MetaMesh.
This commit is contained in:
Worph
2026-09-13 16:18:29 +00:00
parent 998eba19f4
commit 39f82e1f96
145 changed files with 12964 additions and 1 deletions
+155
View File
@@ -0,0 +1,155 @@
name: metafeedergutenberg
# =============================================================================
# MetaFeeder · Gutenberg — a standalone Project Gutenberg feeder for MetaMesh.
#
# Split out of MetaGateway so you can run only the feeders you want. Headless
# (no enrichment, no config needed): it finds public-domain books and returns
# the records to the MetaGateway core, which stores + announces them. The
# gateway must list this feeder's URL (`http://metafeedergutenberg-feeder:8080`) in
# its feeders config (both on the shared `pcs` network).
# =============================================================================
services:
# ---------------------------------------------------------------------------
# metafeedergutenberg-feeder — the gutenberg feeder. The gateway reaches it on `pcs`
# for discovery/query; it returns records (no meta-core, no enrichment).
# ---------------------------------------------------------------------------
metafeedergutenberg-feeder:
image: ghcr.io/worph/meta-feeder-gutenberg:1.0.2
cpu_shares: 30
container_name: metafeedergutenberg-feeder
hostname: metafeedergutenberg-feeder
restart: unless-stopped
user: "0:0"
expose:
- 8080
environment:
RUST_LOG: "info,meta_feeder=info"
META_FEEDER_STATE_DIR: "/data/meta-feeder"
TZ: "$TZ"
volumes:
# Persist feeder config.json + redb cache so it survives recreate.
- ${DATA_ROOT:-/DATA}/AppData/metafeedergutenberg/state:/data/meta-feeder:rw
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/health"]
interval: 5s
timeout: 3s
retries: 10
start_period: 5s
networks:
- metafeedergutenberg
- pcs
# ---------------------------------------------------------------------------
# AppShield gate — the feeder's config page behind Yundera OIDC SSO.
# container_name == subdomain prefix (the auth-registrar derives the client_id
# from it). The gateway still reaches the feeder directly on `pcs`; index → /config.
# ---------------------------------------------------------------------------
metafeedergutenberg:
image: ghcr.io/yundera/appshield:2.0.9
cpu_shares: 80
container_name: metafeedergutenberg
hostname: metafeedergutenberg
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: "metafeedergutenberg-feeder"
BACKEND_PORT: "8080"
LISTEN_PORT: "80"
labels:
caddy_0: metafeedergutenberg-${APP_DOMAIN}
caddy_0.import: gateway_tls
caddy_0.reverse_proxy: "{{upstreams 80}}"
caddy_1: metafeedergutenberg-${APP_PUBLIC_IP_DASH}.nip.io
caddy_1.import: gateway_tls
caddy_1.reverse_proxy: "{{upstreams 80}}"
caddy_2: metafeedergutenberg-${APP_PUBLIC_IP_DASH}.sslip.io
caddy_2.reverse_proxy: "{{upstreams 80}}"
depends_on:
- metafeedergutenberg-feeder
networks:
- metafeedergutenberg
- pcs
networks:
metafeedergutenberg:
name: metafeedergutenberg
driver: bridge
pcs:
name: ${APP_NET:-pcs}
external: true
x-casaos:
architectures:
- amd64
- arm64
author: Worph Team
category: Media
developer: Aptero Team
main: metafeedergutenberg
webui_port: 80
index: /config
description:
en_us: |
**A standalone Project Gutenberg feeder for the MetaMesh network.**
MetaFeeder · Gutenberg bridges public-domain books from Project Gutenberg into
MetaMesh so they surface across the federation, plus **Open Library** work
cards — the book identity tier that groups editions under one work. Split out of MetaGateway so
you can run only the feeders you want — headless, no setup required.
**Requires (from the store):**
- **MetaGateway** — its meta-core stores the resolved records and announces
them to the swarm. The gateway must list this feeder in its config.
fr_fr: |
**Un feeder Project Gutenberg autonome pour le réseau MetaMesh.**
MetaFeeder · Gutenberg connecte les livres du domaine public de Project
Gutenberg à MetaMesh. Détaché de MetaGateway pour n'exécuter que les feeders
souhaités — sans configuration. **Nécessite** l'app **MetaGateway**.
tagline:
en_us: Project Gutenberg editions + Open Library work cards for MetaMesh
fr_fr: Éditions Project Gutenberg + fiches Open Library pour MetaMesh
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
store_app_id: metafeedergutenberg
is_uncontrolled: false
tips:
before_install:
en_us: |
**Install order:** install **MetaGateway** first.
**After installing this app:** in **MetaGateway**, make sure this feeder
is listed in its feeders config (`http://metafeedergutenberg-feeder:8080`) so
it gets discovered (or add it from the gateway dashboard). No other setup.
**Authentication:** the config UI is protected by Yundera's Authelia (OIDC).
# 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.
# Compose would otherwise create a missing bind source as a root-owned dir.
folders:
- path: /DATA/AppData/metafeedergutenberg/state
user: $PUID
group: $PGID
# Same string as the caddy_0 label, so the tile link and the route agree.
webui-host: metafeedergutenberg-${domain}
webui-path: "/config"
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

+41
View File
@@ -0,0 +1,41 @@
# MetaFeeder · Gutenberg — Rationale
## What deviation / exception is being requested
`metafeedergutenberg-feeder` runs `user: 0:0`.
## Why it is necessary
The feeder publishes its resolved records to the shared MetaCore over HTTP and writes its
own service registration and plugin artwork through MetaCore's WebDAV endpoint. Those
writes land in directories created and owned by MetaCore's root-running container; a
uid-1000 process is refused. The feeder image also runs a small supervised process group
(fetcher + enrichment plugin clients) that expects to be able to signal its children.
## Security mitigations in place
- Public ingress terminates at the AppShield sidecar (`ghcr.io/yundera/appshield:2.0.9`),
which gates every path behind the PCS's Authelia SSO over OIDC. The feeder carries no
Caddy labels and publishes no host port, so it is reachable only from the `pcs` Docker
network.
- The container mounts **no user directories** — not `/DATA/Documents`, `/DATA/Downloads`,
`/DATA/Media` or `/DATA/Gallery`. Its only bind is its own state under
`/DATA/AppData/metafeedergutenberg/`, declared in `x-compose-app.folders` and owned `$PUID:$PGID`.
- `cpu_shares` set on every service; image tags pinned; no `:latest`.
## Alternatives considered and rejected
- **Run as `$PUID:$PGID`.** Writes into MetaCore's root-owned `/meta-core` tree and through
its WebDAV endpoint fail, and the feeder starts but silently publishes nothing.
- **Have MetaCore relax the ownership of its shared directory.** That would loosen
permissions for every MetaMesh app at once, which is strictly worse than one root
container with no user-data mounts.
- **Drop privileges after startup inside the image.** Upstream change; tracked, not
available in the shipped image.
## Data protection
The feeder holds no user media. Its entire state — configuration, cursor position, and
(where applicable) the TMDB cache — lives under `/DATA/AppData/metafeedergutenberg/`, which is the unit
Maison archives on uninstall and restores from backup, so an uninstall/reinstall with "keep
user data" resumes where it left off rather than re-indexing from scratch.
Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB