improved version
This commit is contained in:
@@ -7,8 +7,8 @@ name: ipcr-forge
|
|||||||
# → radicle-gitea-bridge copies repos that commit .gitea/workflows/
|
# → radicle-gitea-bridge copies repos that commit .gitea/workflows/
|
||||||
# → gitea + gitea-runner GitHub-style Actions build the image
|
# → gitea + gitea-runner GitHub-style Actions build the image
|
||||||
# → gitea registry staging: gitea-<domain>/gitea_admin/<app>:1.2.3
|
# → gitea registry staging: gitea-<domain>/gitea_admin/<app>:1.2.3
|
||||||
# ┄ (not wired yet) package webhook → IPCR import
|
# → ipcr-gateway follows Gitea's registry imports every tag into IPFS, publishes IPNS
|
||||||
# → ipcr-kubo / ipcr-registry / ipcr-gateway
|
# → ipcr-kubo / ipcr-registry
|
||||||
# docker pull ipcr.localhost:4767/ipns/<name>:1.2.3 (anyone)
|
# docker pull ipcr.localhost:4767/ipns/<name>:1.2.3 (anyone)
|
||||||
#
|
#
|
||||||
# Every service is copied verbatim from its standalone listing (apps/Radicle, apps/Gitea,
|
# Every service is copied verbatim from its standalone listing (apps/Radicle, apps/Gitea,
|
||||||
@@ -18,9 +18,10 @@ name: ipcr-forge
|
|||||||
# Replaces those four apps; it cannot sit beside them. It uses the same container names,
|
# Replaces those four apps; it cannot sit beside them. It uses the same container names,
|
||||||
# domains (radicle-, radicle-api-, gitea-) and host ports (8776, 4768, 127.0.0.1:4767).
|
# domains (radicle-, radicle-api-, gitea-) and host ports (8776, 4768, 127.0.0.1:4767).
|
||||||
#
|
#
|
||||||
# The handoff from Gitea's registry to IPFS is the one missing link: the runner's jobs run in
|
# The handoff from Gitea's registry to IPFS is a pull, run by IPCR: the runner's jobs run in a
|
||||||
# a nested Docker that cannot reach ipcr.localhost (it is the *host's* loopback), so the
|
# nested Docker that cannot reach ipcr.localhost (the *host's* loopback), so CI never pushes to
|
||||||
# import has to run on IPCR's side, triggered by Gitea's "package published" webhook.
|
# IPCR. Instead ipcr-gateway polls gitea:3000 over gitea-internal, with a read-only token the
|
||||||
|
# bridge-credentials step mints. Gitea does not know IPCR exists.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ═══ Radicle — the source of truth ═════════════════════════════════════════════
|
# ═══ Radicle — the source of truth ═════════════════════════════════════════════
|
||||||
@@ -326,7 +327,7 @@ services:
|
|||||||
# ipcrd: TLS front door on 127.0.0.1:4767. Passes /ipfs/<cid> through to the stock nerdctl
|
# ipcrd: TLS front door on 127.0.0.1:4767. Passes /ipfs/<cid> through to the stock nerdctl
|
||||||
# registry below, resolves /ipns/<name>:<tag> itself, and pins every image it serves.
|
# registry below, resolves /ipns/<name>:<tag> itself, and pins every image it serves.
|
||||||
ipcr-gateway:
|
ipcr-gateway:
|
||||||
image: ghcr.io/yundera/ipcr:0.1.0
|
image: ghcr.io/yundera/ipcr:1.1.0
|
||||||
container_name: ipcr-gateway
|
container_name: ipcr-gateway
|
||||||
# Root for one reason: it writes its CA into the host's Docker trust store (the narrow
|
# Root for one reason: it writes its CA into the host's Docker trust store (the narrow
|
||||||
# bind below), which is root-owned. See rationale.md.
|
# bind below), which is root-owned. See rationale.md.
|
||||||
@@ -343,8 +344,25 @@ services:
|
|||||||
CA_EXPORT: /certs.d/ipcr.localhost:4767/ca.crt
|
CA_EXPORT: /certs.d/ipcr.localhost:4767/ca.crt
|
||||||
# Pin every image this host pulls, so the node keeps — and re-shares — what it runs.
|
# Pin every image this host pulls, so the node keeps — and re-shares — what it runs.
|
||||||
AUTO_PIN: "true"
|
AUTO_PIN: "true"
|
||||||
|
# Optional: follow a registry. Every tag of every repository it lists (or of
|
||||||
|
# IPCR_IMPORT_REPOS) is copied into IPFS and published as /ipns/<owner-repo>:<tag>;
|
||||||
|
# a tag is re-imported when it moves. Empty = off. IPCR_IMPORT_AUTH is user:token,
|
||||||
|
# a read-only (read:package) token is enough.
|
||||||
|
# Forge: watch this app's own Gitea, over gitea-internal (not through Caddy).
|
||||||
|
IMPORT_WATCH: ${IPCR_IMPORT_WATCH:-http://gitea:3000}
|
||||||
|
IMPORT_AUTH: ${IPCR_IMPORT_AUTH:-}
|
||||||
|
# Forge: a read:package token the bridge-credentials step mints. Re-read every poll
|
||||||
|
# and preferred over IMPORT_AUTH, so it may appear after the gateway is up.
|
||||||
|
IMPORT_AUTH_FILE: /data/secrets/registry-auth
|
||||||
|
IMPORT_REPOS: ${IPCR_IMPORT_REPOS:-}
|
||||||
|
IMPORT_INTERVAL: 60s
|
||||||
|
STATE_DIR: /data/state
|
||||||
volumes:
|
volumes:
|
||||||
- ${DATA_ROOT:-/DATA}/AppData/$AppID/ipcr/tls:/data/tls
|
- ${DATA_ROOT:-/DATA}/AppData/$AppID/ipcr/tls:/data/tls
|
||||||
|
# What the watcher already imported (tag → manifest digest).
|
||||||
|
- ${DATA_ROOT:-/DATA}/AppData/$AppID/ipcr/state:/data/state
|
||||||
|
# Forge only: the credential above. Read-only here.
|
||||||
|
- ${DATA_ROOT:-/DATA}/AppData/$AppID/ipcr/secrets:/data/secrets:ro
|
||||||
# The host's Docker trust store, so the CA above can be dropped into it: no daemon
|
# The host's Docker trust store, so the CA above can be dropped into it: no daemon
|
||||||
# reload, no daemon.json edit. The parent is mounted because Compose cannot create a
|
# reload, no daemon.json edit. The parent is mounted because Compose cannot create a
|
||||||
# bind source whose name contains a colon (ipcr.localhost:4767). ipcrd writes exactly
|
# bind source whose name contains a colon (ipcr.localhost:4767). ipcrd writes exactly
|
||||||
@@ -364,6 +382,8 @@ services:
|
|||||||
start_period: 10s
|
start_period: 10s
|
||||||
networks:
|
networks:
|
||||||
- ipcr-internal
|
- ipcr-internal
|
||||||
|
# Forge only: reaches gitea:3000 for the import poller above.
|
||||||
|
- gitea-internal
|
||||||
cpu_shares: 50
|
cpu_shares: 50
|
||||||
deploy:
|
deploy:
|
||||||
resources:
|
resources:
|
||||||
@@ -373,7 +393,7 @@ services:
|
|||||||
# ── Stock nerdctl IPFS registry ─────────────────────────────────────────────
|
# ── Stock nerdctl IPFS registry ─────────────────────────────────────────────
|
||||||
# `nerdctl ipfs registry serve`, unmodified: translates the registry API into IPFS reads.
|
# `nerdctl ipfs registry serve`, unmodified: translates the registry API into IPFS reads.
|
||||||
ipcr-registry:
|
ipcr-registry:
|
||||||
image: ghcr.io/yundera/ipcr:0.1.0
|
image: ghcr.io/yundera/ipcr:1.1.0
|
||||||
container_name: ipcr-registry
|
container_name: ipcr-registry
|
||||||
# Root because nerdctl run as any other uid assumes rootless mode and refuses to start
|
# Root because nerdctl run as any other uid assumes rootless mode and refuses to start
|
||||||
# without a rootless containerd — which `ipfs registry serve` never uses. The service has
|
# without a rootless containerd — which `ipfs registry serve` never uses. The service has
|
||||||
@@ -515,8 +535,9 @@ x-casaos:
|
|||||||
|
|
||||||
**Ports.** TCP 8776 (Radicle peers) and 4768 TCP+UDP (IPFS peers) are published.
|
**Ports.** TCP 8776 (Radicle peers) and 4768 TCP+UDP (IPFS peers) are published.
|
||||||
|
|
||||||
**Not wired yet:** images reach Gitea's registry automatically, but publishing them to
|
**Images reach IPFS on their own.** IPCR follows this app's Gitea registry: about a
|
||||||
IPFS is still a manual `ipcr push` (see the IPCR README).
|
minute after a build pushes `gitea_admin/<repo>:<tag>`, it can be pulled as
|
||||||
|
`ipcr.localhost:4767/ipns/gitea_admin-<repo>:<tag>`.
|
||||||
fr_fr: |
|
fr_fr: |
|
||||||
**Remplace quatre applications.** Désinstallez d'abord Radicle, Gitea, Radicle Gitea
|
**Remplace quatre applications.** Désinstallez d'abord Radicle, Gitea, Radicle Gitea
|
||||||
Bridge et IPCR : cette application utilise les mêmes adresses et ports.
|
Bridge et IPCR : cette application utilise les mêmes adresses et ports.
|
||||||
@@ -530,8 +551,9 @@ x-casaos:
|
|||||||
|
|
||||||
**Ports.** TCP 8776 (pairs Radicle) et 4768 TCP+UDP (pairs IPFS) sont publiés.
|
**Ports.** TCP 8776 (pairs Radicle) et 4768 TCP+UDP (pairs IPFS) sont publiés.
|
||||||
|
|
||||||
**Pas encore relié :** les images arrivent automatiquement dans le registre Gitea, mais
|
**Les images arrivent sur IPFS d'elles-mêmes.** IPCR suit le registre Gitea de cette
|
||||||
leur publication sur IPFS reste un `ipcr push` manuel (voir le README d'IPCR).
|
application : environ une minute après qu'un build a poussé `gitea_admin/<dépôt>:<tag>`,
|
||||||
|
elle se tire avec `ipcr.localhost:4767/ipns/gitea_admin-<dépôt>:<tag>`.
|
||||||
index: /
|
index: /
|
||||||
webui_port: 8080
|
webui_port: 8080
|
||||||
store_app_id: ipcr-forge
|
store_app_id: ipcr-forge
|
||||||
@@ -580,6 +602,11 @@ x-compose-app:
|
|||||||
- path: /DATA/AppData/$AppID/ipcr/init.d
|
- path: /DATA/AppData/$AppID/ipcr/init.d
|
||||||
user: $PUID
|
user: $PUID
|
||||||
group: $PGID
|
group: $PGID
|
||||||
|
# Written by bridge-credentials as $PUID, read by ipcr-gateway (root).
|
||||||
|
- path: /DATA/AppData/$AppID/ipcr/secrets
|
||||||
|
user: $PUID
|
||||||
|
group: $PGID
|
||||||
|
mode: "0700"
|
||||||
files:
|
files:
|
||||||
# Each entry and its reason are in the standalone listing it comes from.
|
# Each entry and its reason are in the standalone listing it comes from.
|
||||||
- path: /DATA/AppData/$AppID/radicle/home/config.json
|
- path: /DATA/AppData/$AppID/radicle/home/config.json
|
||||||
@@ -649,10 +676,12 @@ x-compose-app:
|
|||||||
network: $APP_NET
|
network: $APP_NET
|
||||||
volumes:
|
volumes:
|
||||||
- /DATA/AppData/$AppID/bridge/secrets:/secrets
|
- /DATA/AppData/$AppID/bridge/secrets:/secrets
|
||||||
|
- /DATA/AppData/$AppID/ipcr/secrets:/ipcr-secrets
|
||||||
|
# Also mints IPCR's read-only token for following Gitea's registry.
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- GITEA_PASSWORD="$APP_DEFAULT_PASSWORD" bridge-init
|
- GITEA_PASSWORD="$APP_DEFAULT_PASSWORD" IPCR_AUTH_FILE=/ipcr-secrets/registry-auth bridge-init
|
||||||
when: absent:/DATA/AppData/$AppID/bridge/secrets/gitea-token
|
when: absent:/DATA/AppData/$AppID/bridge/secrets/gitea-token
|
||||||
webui-host: radicle-${domain}
|
webui-host: radicle-${domain}
|
||||||
webui-path: /
|
webui-path: /
|
||||||
|
|||||||
Reference in New Issue
Block a user