Compare commits

..

75 commits

Author SHA1 Message Date
Hernâni Marques
4f74662202
pepsi: host-net highports + ensure mon-* users 2026-10-29 07:55:14 +01:00
Hernâni Marques
8370ad2e33
tor: CachyOS CTR CookieAuth same FP (TODO=704) 2026-10-21 03:32:38 +02:00
Hernâni Marques
eb4349085d
docs: forgejo host RO users rabbithole/amanita/firecuda-ro 2026-10-21 02:51:00 +02:00
Hernâni Marques
fe0c1e2b53
feat/dossiers-ngi: add Caddy handle docs for cascade sticky bar 2026-10-10 00:49:58 +02:00
Hernâni Marques
37ac6a2171
feat/dossiers-ngi: dated tip/at bar keeps caller path on edition switch 2026-10-10 00:49:11 +02:00
Hernâni Marques
197e0ab19a
fix/dossiers-ngi: update README and scripts for branch status 2026-10-01 12:09:29 +02:00
Hernâni Marques
8ad49de231
fix/dossiers-ngi: update README and scripts for branch status 2026-10-01 11:46:56 +02:00
Hernâni Marques
c14e215ad8
feat/dossiers-ngi: sticky bar vs-parent loc-on-roots split plus/minus 45rem 2026-09-30 23:56:51 +02:00
Hernâni Marques
8cb55e57e8
feat/dossiers-ngi: sticky bar vs-main compact dates tabular wider tree 2026-09-30 23:26:26 +02:00
Hernâni Marques
3feb694084
feat/dossiers-ngi: inject-editions-bar.sh for freeze HTML missing include 2026-09-30 22:15:38 +02:00
Hernâni Marques
b24dd17ee9
feat/dossiers-ngi: sticky bar + JSON diffstat vs parent tip 2026-09-30 22:07:06 +02:00
Hernâni Marques
c2bf7a4263
feat/dossiers-ngi: sticky bar vs-main +green/−red diffstat 2026-09-30 16:21:28 +02:00
Hernâni Marques
ce5269b745
fix/dossiers-ngi: Caddy explicit edition_dir map (cookie placeholder 404) 2026-09-30 16:13:42 +02:00
Hernâni Marques
686a9fb906
ops/dossiers-ngi: Caddy Vary Cookie + no-cache for edition-pure CSS 2026-09-30 16:07:49 +02:00
Hernâni Marques
84623b7c9a
ops/dossiers-ngi: cascade bar dates, center/mobile, soft refresh; serve /cascade 2026-09-30 15:54:46 +02:00
Hernâni Marques
737d37a76d
ops/dossiers-ngi: edition tree bar, 10min tip-skip rebuild, cleanup 2026-09-30 15:36:49 +02:00
Hernâni Marques
e35205b6cd
scripts/dossiers-ngi/README.md: update branch-status-hourly.py reference 2026-09-30 13:08:46 +02:00
Hernâni Marques
8a09314eaf
docs: update README.md with new content 2026-09-30 13:01:15 +02:00
Hernâni Marques
ff934ce5e9
ops/dossiers-ngi: hourly branch-status emit tip fields only 2026-09-30 03:48:19 +02:00
Hernâni Marques
f2a0d533b8
sites/dossiers.ngi: strip meta keep links and last-built 2026-09-30 03:44:42 +02:00
Hernâni Marques
9035b9600b
docs: daylog tech-dossier Freeze cascade tip correction 2026-09-30 01:16:45 +02:00
Hernâni Marques
6e57fceb19
ops/dossiers-ngi: hourly branch-status builder + systemd timer 2026-09-29 23:26:13 +02:00
Hernâni Marques
83998499da
sites/dossiers.ngi: EN ASCII cascade landing with tip cites 2026-09-30 03:41:53 +02:00
Hernâni Marques
c38d3c900a
docs: daylog tech-dossier Freeze cascade 2026-09-30 03:41:53 +02:00
Hernâni Marques
9fa5ce19b6
sites/dossiers.ngi: blank cascade landing with path-root stubs 2026-09-30 03:41:53 +02:00
Hernâni Marques
0b009b2717
docs: daylog tech-dossier Freeze cascade 2026-09-29 04:33:46 +02:00
Hernâni Marques
fcc2024045
docs: daylog tech-dossier Freeze cascade 2026-09-28 23:05:45 +02:00
Hernâni Marques
4c3b8f526f
docs: daylog tech-dossier Freeze cascade 2026-09-28 23:05:06 +02:00
Hernâni Marques
d7e0fae6f0
docs: daylog tech-dossier Freeze cascade 2026-09-28 20:08:33 +02:00
Hernâni Marques
3643e54456
ops: amanita-probe default host .7 (RTL8125) 2026-09-26 16:37:26 +02:00
Hernâni Marques
08b1676b19
docs: daylog 2026-09-25 qbittorrent bt-net + scripts/prime apply-koopa-bt-fix wrappers 2026-09-26 12:04:07 +02:00
Hernâni Marques
e01fbedcd8
ops: amanita-probe ref/edge fields + README Verify 2026-09-24 20:42:33 +02:00
Hernâni Marques
a10de8f0a9
ops: caddy dossiers try_files path/index.html 2026-09-23 13:23:32 +02:00
Hernâni Marques
43a8b4037b
docs: daylog 2026-09-23 goa merchant terms privacy + mon green 2026-09-23 13:23:22 +02:00
Hernâni Marques
986e9a3090
docs: update goa-regio-ng login-health monitoring 2026-09-20 23:41:26 +02:00
Hernâni Marques
0348f4025a
docs: goa-regio-ng login-health monitoring update 2026-09-19 07:09:20 +02:00
Hernâni Marques
44c6a870a6
docs: hernani-home path map GOA landings backups 2026-09-19 02:28:03 +02:00
Hernâni Marques
8c588742dd
docs: daylog 2026-09-19 goa-regio-ng login-health monitoring 2026-09-19 02:18:26 +02:00
Hernâni Marques
74aa6e5ecf
docs: ISSUES I-07 host Tor not koopa-tor-relay 2026-09-19 02:05:47 +02:00
Hernâni Marques
50d461379a
docs: README shorten single-CTR GOA + host Tor 2026-09-19 01:52:14 +02:00
Hernâni Marques
4974032188
docs: ports + koopa-setup goa-regio-ng pasta map 2026-09-19 01:38:51 +02:00
Hernâni Marques
82879637b6
ops: host tor.service SoT drop configs/tor CTR 2026-09-19 01:22:33 +02:00
Hernâni Marques
b9e2541941
docs: remove host/overview LIVE services inventory 2026-09-19 01:05:09 +02:00
Hernâni Marques
c68e4a50cb
docs: login-health README single-CTR GOA inventory 2026-09-19 00:48:42 +02:00
Hernâni Marques
fb3ca7be10
ops: login-health CRITICAL goa-regio-ng drop legacy CTRs 2026-09-19 00:31:17 +02:00
Hernâni Marques
1650571b36
fix: update README with new deployment instructions 2026-09-18 16:31:54 +02:00
Hernâni Marques
3ba9f02bb9
Merge remote-tracking branch 'refs/remotes/origin/master' 2026-09-18 15:50:23 +02:00
Hernâni Marques
8d9bfc1512
fix paths 2026-09-18 15:50:04 +02:00
Hernâni Marques
d27c7254af
feat: amanita external probe (timer + vx-only key) 2026-09-18 15:11:54 +02:00
Hernâni Marques
7691ac3065
ops: taler-bank auto-confirm + systemd units + README 2026-09-18 13:05:31 +02:00
Hernâni Marques
281873a955
ops: GOA auto-confirm DB-selected withdrawals + debt-headroom filter 2026-09-18 12:18:47 +02:00
Hernâni Marques
65bcddc185
ops: goa-regio-ng default CTR for ensure/systemd bank+merchant apps 2026-09-18 11:52:23 +02:00
Hernâni Marques
06ce2c58d1
docs: taler-landing how to trigger --ssh/--deploy publish 2026-09-17 18:48:03 +02:00
Hernâni Marques
60f917fc31
ops: taler-landing scripts add laptop --ssh deploy path and --deploy chain 2026-09-17 18:47:38 +02:00
Hernâni Marques
83b1616ed6
ops: GOA regio-ng AIO restore scripts + wire post-restore helper 2026-09-17 00:40:27 +02:00
Hernâni Marques
337d253691
ops: GOA vanilla landings stats wdGet + collect greening 2026-09-16 23:55:47 +02:00
Hernâni Marques
0d881cd726
ops: GOA merchant-first 2026-09-15 daylog + lab-hosts + APPLY driver 2026-09-16 02:48:57 +02:00
Hernâni Marques
2eb44c95d9
config: update READMEs and compose files for various services 2026-09-12 21:37:05 +02:00
Hernâni Marques
b19b1d3cf6
docs: forgejo/ht default_branch = master (not main) 2026-09-09 04:22:13 +02:00
Hernâni Marques
5196ac5db8
ops: Forgejo tip=master unify + silverbucket rename note 2026-09-09 01:31:47 +02:00
Hernâni Marques
56f814a6de
ops: paivana and caddy config refresh 2026-09-09 00:52:54 +02:00
Hernâni Marques
d8dbc6242b
admin-log: adapt clementine tip/vs content onto main 2026-09-07 17:43:45 +02:00
Hernâni Marques
ba863f8a93
admin-log: add conflict-free clementine/vs-only paths onto main 2026-09-07 17:17:10 +02:00
Hernâni Marques
a2300b617b
koopa: apt-src ubuntu noble container (Freigabe) 2026-09-05 09:07:44 +02:00
Hernâni Marques
9b53012556
lab: mytops-local on koopa and koopa-setup entry 2026-09-05 09:07:44 +02:00
Hernâni Marques
e29c01c8e3
goa: lab-local regio-ng config and loopback ports 2026-09-05 09:07:44 +02:00
Hernâni Marques
9618387e31
docs: secret-languages local repo; drop secret UI branches 2026-09-05 09:07:44 +02:00
Hernâni Marques
5febae5bf3
docs: share includes full ~/.grok (dot-grok), cross-machine rules 2026-09-05 09:07:44 +02:00
Hernâni Marques
cf5c672cf7
docs: share payload = all local-only never-pushed repos 2026-09-05 09:07:44 +02:00
Hernâni Marques
346a14d8d2
docs: clementine-magikoopa-share crypto + EXPECTED-REPOS after unlock 2026-09-05 09:07:44 +02:00
Hernâni Marques
f62e866eed
lab: mytops-local on koopa and koopa-setup entry 2026-09-04 21:44:14 +02:00
Hernâni Marques
0450f3738f
goa: lab-local regio-ng config and loopback ports 2026-09-04 16:18:08 +02:00
Hernâni Marques
a2eac75dd3
goa: backup docs under backups/goa before regio-ng 2026-09-04 14:40:19 +02:00
Hernâni Marques
12f9f76834
tor: change from bookworm-slim to stable-slim; w/ old id online again 2026-09-02 23:15:06 +02:00
Hernâni Marques
9ae0dfa429
decidim: mirror koopa-decidim setup (9027, docs for /sm showcase) 2026-08-24 08:49:26 +02:00
217 changed files with 13040 additions and 1331 deletions

View file

@ -3,3 +3,8 @@
- **Caddy mon bare paths:** `redir /path/ 302` inside `handle` → Location `302` → merchant code 21; fix `redir * /path/ 302` - **Caddy mon bare paths:** `redir /path/ 302` inside `handle` → Location `302` → merchant code 21; fix `redir * /path/ 302`
- **apply-monitoring-live.sh:** smoke for-loop syntax (missing `\`); use absolute `/home/hernani/koopa-caddy/…` (root `~` = `/root`) - **apply-monitoring-live.sh:** smoke for-loop syntax (missing `\`); use absolute `/home/hernani/koopa-caddy/…` (root `~` = `/root`)
- Re-apply: `sudo /home/hernani/koopa-caddy/apply-monitoring-live.sh` - Re-apply: `sudo /home/hernani/koopa-caddy/apply-monitoring-live.sh`
- **clementine-magikoopa-share** (`~/clementine-magikoopa-share/`): openssl AES-256-CBC + PBKDF2 iter 600000; `lock.sh`/`unlock.sh` + `ANLEITUNG.md` (usage). Inventory only after decrypt: `EXPECTED-REPOS.md` (includes vecigate-admin-log/secrets expected from magikoopa). Usage mirror in `koopa-admin-secrets/docs/clementine-magikoopa-share.md`.
- **Share payload = all local-only / never-pushed repos:** canonical list in `koopa-admin-secrets/docs/share-payload-dirs.txt` (+ `local-only-share-repos.md`). On clementine archived: `taler-monitoring-env`, `llm`, `grok-work-log`, **`koopa-admin-secrets`**, **`francpaysan-secrets`**, **`dot-grok`** (`~/.grok` full profile); still MISSING until magikoopa locks them: `vecigate-admin-log`, `vecigate-admin-secrets`.
- **Share README:** other machine must treat `dot-grok` / profile rules **system-wide** (install to `~/.grok`, same operator rules on clementine and magikoopa).
- **secret-languages:** extracted from local branches `local/merchant-secret-ui` / `local/secret-ui-scrub` into standalone local-only repo `~/src/koopa/secret-languages` (never push). Those branches deleted on this clone. Pack via clementine-magikoopa-share.

View file

@ -0,0 +1,97 @@
# 2026-09-04 — GOA backup (pre regio-ng)
## Live (koopa)
| Container | Ports | Site |
|-----------|-------|------|
| `taler-hacktivism-exchange-ansible` | 9011/9014 | exchange.hacktivism.ch |
| `taler-hacktivism-bank` | 9012/9013 | bank.hacktivism.ch |
| `taler-hacktivism` | 9010/9015 | taler.hacktivism.ch |
| `koopa-paivana` | 9025 | paivana.hacktivism.ch |
Currency **GOA**. Master pub (public): `TW6K5FXF81VYCAH0YWYX0SX98KBBSJ42VX27WAX01FTFH400QG10`.
Probes 2026-09-04: exchange/bank/taler `/config` **200**. Monitoring user units mostly failed (apps/ladder) — separate.
**Risk:** exchange/bank/merchant data sit in container **overlay** (no named volumes). Offline key: `/var/lib/taler-exchange/offline/master.priv` inside exchange container.
## Backup location (ERPNext-style `backups/` + stamp + `current`)
| Host | Path |
|------|------|
| koopa | `~/backups/goa/<stamp>/` · `~/backups/goa/current` |
| magikoopa | `~/backups/goa/<stamp>/` · `~/backups/goa/current` |
| **secrets** (keys + `*.secret.conf` + host_vars/paivana) | `koopa-admin-secrets/backups/goa/<stamp>/` · `…/current` |
Stamp taken: **`20260904T1238Z`**.
### Non-secret dumps (`~/backups/goa/`)
`exchange/` `bank/` `merchant/` TGZs (PG + etc), `meta/`, optional `images/` (~2.2G).
### Secrets (`koopa-admin-secrets/backups/goa/current/`)
| Path | Content |
|------|---------|
| `exchange-offline/master.priv` | offline master (pub TW6K5…) |
| `exchange-offline/secm_tofus.pub` | secmod TOFU |
| `exchange/secrets/*.secret.conf` | DB + wire account creds |
| `merchant/secrets/merchant-db.secret.conf` | merchant DB |
| `ansible/host_vars/` | public.yml + secrets.yml |
| `paivana/secrets/` | merchant-access-token, paivana-secret |
Never Forgejo push for `koopa-admin-secrets`. Magikoopa: `~/git/admin-logs/koopa-admin-secrets` (symlink `~/src/koopa/koopa-admin-secrets`).
## Local reproduce (magikoopa) — **one** container, few unprivileged ports
Not the three `goa-local-*` snapshot containers. Use **`regio-local`** only:
| Bind | Role |
|------|------|
| `127.0.0.1:9080` | nginx HTTP (`Host: *.goa.local`) |
| `127.0.0.1:9222` | SSH ansible |
Optional: `REGIO_PUBLISH_KOOPA_PORTS=1` also binds `9010–9012` (still unprivileged).
Tree: `~/src/regio-local/` — see `RESTORE.md`, `README.md`.
### koopa lab ports (2026-09-04)
Same stack **on koopa** without touching live **9010–9015** or **9080** (nym):
| Bind | Role |
|------|------|
| `127.0.0.1:9180` | `goa-regio-ng` HTTP |
| `127.0.0.1:9322` | `goa-regio-ng` SSH |
| `127.0.0.1:8288` | `mytops-local` HTTP |
Canonical config: **`configs/lab-local/`** (`goa-regio-ng-koopa.yml`, `mytops-local.toml`, README).
### `taler-deployment` branches
```
dev/hernani/regio-ng-apt-refresh
└─ dev/hernani/regio-ng-ensure-postgresql
└─ regio-goa-explorational-currency # GOA profile + master pin/import + TCP 901x
```
Example inventory: `regional-currency-ng/examples/goa-explorational.yml`
(imports `master.priv` from admin-secrets; refuses greenfield when pub pinned).
### Restore flow
```bash
podman stop goa-local-exchange goa-local-bank goa-local-merchant # free 901x; leave koopa live alone
cd ~/src/regio-local
./scripts/01-build-run.sh
./scripts/02-inventory.sh
./scripts/03-deploy.sh # ansible; master from admin-secrets
./scripts/05-restore-data.sh # optional PG dumps from ~/backups/goa/current
./scripts/04-probe.sh # expect 200 on :9010 :9011 :9012
```
## Push
`koopa-admin-log` Push nötig — nur mit Freigabe / User-Push.
`taler-deployment` branch `regio-goa-explorational-currency` likewise Freigabe.
Live wipe: **no**.

View file

@ -0,0 +1,47 @@
# mytops-local on koopa (podman lab)
**2026-09-04** — merchant http lab next to live goa (not 901x / nym 9080).
## status
| where | port | `/config` |
|-------|------|-----------|
| koopa | `127.0.0.1:8288` | 200 (`mytops-local` Up) |
| magikoopa (ref) | `127.0.0.1:8088` | 200 |
container: `mytops-local` · image `localhost/mytops-debian-systemd:trixie` ·
bind `~/src/mytops-admin-log` (rsync from laptop; `.git` optional).
docs/run: `mytops-admin-log` branch `mytops-local` → entry `mytops-local` /
`mytops-local.md`. `STAGE_ENV` unused on this path.
## setup (koopa)
```bash
rsync -az --delete --exclude .git --exclude .DS_Store \
~/git/mytops-admin-log/ hernani@koopa:src/mytops-admin-log/
ssh hernani@koopa
cd ~/src/mytops-admin-log
podman build -t localhost/mytops-debian-systemd:trixie -f Containerfile.mytops-local .
MYTOPS_LOCAL_HTTP_PORT=8288 ./scripts/taler-merchant/apply-local-base-url.sh
podman rm -f mytops-local 2>/dev/null || true
podman run -d --name mytops-local --hostname mytops-local \
--systemd=always --cap-add SYS_ADMIN --security-opt label=disable \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw --tmpfs /run --tmpfs /run/lock \
-p 127.0.0.1:8288:80 \
-v "$HOME/src/mytops-admin-log:/root/mytops-admin-log:rw" \
localhost/mytops-debian-systemd:trixie /sbin/init
podman exec mytops-local bash -lc \
'cd /root/mytops-admin-log && MYTOPS_LOCAL_HTTP_PORT=8288 ./scripts/taler-merchant/setup-local.sh'
```
if dbconfig fails (`policy-rc.d`): start `postgresql`, then dbconfig + `taler-merchant.target`.
## links
| what | where |
|------|--------|
| koopa-setup | `koopa-setup` |
| lab-local | `configs/lab-local/` · `configs/ports.md` |
| mytops-admin-log | branch `mytops-local` |
| regio lab | `configs/lab-local/goa-regio-ng-koopa.yml` · `~/src/regio-local/` |

View file

@ -0,0 +1,24 @@
# taler apt-src ubuntu (noble) on koopa
**2026-09-05** — Freigabe: create Ubuntu track next to existing trixie apt-src pods.
## container
| name | base | suite | image |
|------|------|-------|-------|
| `koopa-taler-deploy-test-apt-src-ubuntu` | `ubuntu:24.04` | `noble` @ `deb.taler.net/apt/ubuntu` | `localhost/…:setup` after commit |
ensure: `~/src/taler-monitoring/host-agent/ensure-apt-deploy-test-containers.sh ubuntu`
(branch `llm-lightweight-monitoring` / tip after `v1.27.0`)
## verify
```bash
podman ps -a --filter name=koopa-taler-deploy-test-apt-src-ubuntu
ANSIBLE_SMOKE_PODMAN=1 ANSIBLE_SMOKE_REQUIRE_UBUNTU=1 \
./taler-monitoring.sh ansible-smoke
```
## notes
Debian trixie×4 unchanged. Spam mailbox secrets / durable monitord still separate Freigabe items.

View file

@ -0,0 +1,55 @@
# `$HOME/git/` meta-repo origin on git.hacktivism.ch (2026-09-07)
## Remote
| Item | Value |
|------|--------|
| Host | **Forgejo rootless** `https://git.hacktivism.ch/` |
| Repo | **hernani/git** (meta-repo: non-secret globals only) |
| Visibility | **private** (`DEFAULT_PRIVATE` template is public — create with `private:true`) |
| Default branch | `master` (forgejo/ht SoT — never `main`) |
| SSH clone (FQDN form) | `git@git.hacktivism.ch:hernani/git.git` |
| SSH URL (API form) | `ssh://git@git.hacktivism.ch:9200/hernani/git.git` |
| Local tree | `$HOME/git/` (`PATH[git-root]`) |
Unauth HTTPS browse of a private repo → **404** (expected).
## Local setup (done 2026-09-07 ~14:21)
```bash
cd "$HOME/git"
git remote add origin git@git.hacktivism.ch:hernani/git.git
git push -u origin master
```
SSH Host `git.hacktivism.ch`: `HostName 127.0.0.1`, `Port 9200`, `User git`, `ProxyJump hernani@koopa`, `IdentityFile ~/.ssh/id_ed25519`.
## Create via One-Shot-Token (on koopa)
Do **not** use xAI / host-expert-ssh mutate for this. SSH as `hernani` → local HTTP **9024**.
```bash
# unique token name (default gitea-admin may already exist)
podman exec koopa-forgejo gitea admin user generate-access-token \
--username hernani \
--token-name "oneshot-git-meta-$(date +%s)" \
--scopes write:repository,write:admin \
--raw
# → TOKEN (never log / never commit)
curl -sS -X POST \
-H "Authorization: token ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name":"git","private":true,"auto_init":false,"default_branch":"master"}' \
http://127.0.0.1:9024/api/v1/admin/users/hernani/repos
# expect HTTP 201, full_name=hernani/git
```
Token delete via API often **403** with those scopes — purge leftover `oneshot-*` in Forgejo UI if needed.
## Related
- This admin-log’s own origin: `2026-07-10--admin-log-origin-forgejo.md` (public)
- Forgejo install: `2026-07-10--forgejo-rootless.md`
- Host skill quirk: private repos need explicit `private:true`
- Meta Must: no secrets / no child worktrees in this Forgejo repo

View file

@ -0,0 +1,31 @@
# Forgejo HT tip = `master` only (2026-09-09)
## Rule
On `git.hacktivism.ch` every hernani tip is **`master` only** — no dual `main`+`master`, no tip named `main`.
- Instance: `[repository] DEFAULT_BRANCH = master` in Forgejo `app.ini` (live after container restart).
- Sync/clone/push defaults: `origin/master`.
- Docs: `llm-configs` → `git-skills.md`, `ESYNC-RULE.md`, `REPOS-INDEX.md`, `forgejo-llm-config.md`.
## Unify (done)
Authenticated inventory: 32 hernani repos. Mutated 15 NEED → verify **OK 32 / BAD 0**.
Notable:
| Case | Repos |
|------|--------|
| MAIN_ONLY → master + drop main | `_grok_sync`, admin-logs, `elelmon` (kept `main-legacy`), `silverbucket` (ex-`freenotes` space), `grok-work-log`, `llm-work-output-enc`, `openkknd-ng`, `taler-monitoring`, `taler-wallets-enc`, `vecirex-www`, … |
| EMPTY | `vecigate-admin-log` (PATCH default only) |
| DUAL_DIFF (stale master dropped; tip from former main) | `git`, `llm-configs` |
Feature branches left in place where present (`koopa-admin-log`, `taler-monitoring`, …).
## Rename (same day)
Forgejo space repo **`hernani/freenotes` → `hernani/silverbucket`** (tip `master`). Local clone: `~/git/freenotes-space` → origin `silverbucket`. **Not** the FreeNotes tool/apps tree (`~/git/freenotes`).
## Local clones
Retarget checkout/tracking to `origin/master` on magikoopa trees that had `origin`.

View file

@ -0,0 +1,55 @@
# 2026-09-11 — Forgejo/ht gitleaks + *enc.git Klartext-Sperre (TODO320)
**Status:** live on koopa Forgejo (`koopa-forgejo` / `git.hacktivism.ch`)
**Freigabe:** Auftrag `TODO=320` this session (host mutation ht)
**Analog:** firefly/taler `admin-log/firefly/28-gitolite-enc-gitleaks.md` + `hooks/common/pre-receive.d-gitleaks`
**Tip:** k stays **319** (no tip-advance)
## What
1. **gitleaks** pre-receive on non-`*enc.git` — reject pushes with detected secrets.
2. **Skip** `*enc.git` for gitleaks (ciphertext / FP).
3. **`git-crypt-enforce`** on `*enc.git` — require `.gitattributes` + `.git-crypt/`; reject blobs under `filter=git-crypt` missing `\0GITCRYPT` (9-byte header).
## Live paths (koopa)
| Item | Path |
|------|------|
| Data root | `~/koopa-forgejo/data` → container `/var/lib/gitea` |
| Binary | `data/custom/bin/gitleaks` (v8.21.2 linux_x64) |
| Shared hooks | `data/custom/hooks/pre-receive.d/{gitleaks,git-crypt-enforce}` |
| Smoke | `data/custom/bin/smoke-todo320.sh` (run **inside** container) |
| Per-repo | `data/git/repositories/*/*.git/hooks/pre-receive.d/` → symlinks to shared hooks (container paths) |
| Staging / installer SoT | laptop `PATH[llm-configs]/bin/forgejo-hooks/` + koopa `~/koopa-forgejo/hooks-staging/` |
Installer: `install-hooks-ht.sh` (idempotent; podman; does not restart container).
After install: **~32** repos linked. **New repos:** re-run installer (custom/hooks alone not relied on for auto-sync into every bare repo).
## Smoke (Done-when a/b/c) — PASSED 2026-09-11
```bash
podman exec koopa-forgejo /var/lib/gitea/custom/bin/smoke-todo320.sh
# ALL SMOKES PASSED
# (a) secret push denied — private-key fixture (not AWS EXAMPLE keys)
# (b) enc ciphertext allowed
# (c) enc plaintext denied
```
Fixes needed during smoke: park incoming objects on `refs/tmp/*` (not `refs/heads/*`, else `rev-list tip --not --branches` is empty); magic check `head -c 9` for `\0GITCRYPT`.
## Rollback
```bash
# Per repo or all: remove custom hooks from pre-receive.d (keep Forgejo `gitea` hook)
rm -f ~/koopa-forgejo/data/git/repositories/*/*.git/hooks/pre-receive.d/gitleaks
rm -f ~/koopa-forgejo/data/git/repositories/*/*.git/hooks/pre-receive.d/git-crypt-enforce
# Optional: remove shared copies under data/custom/hooks/pre-receive.d/
```
## Ops notes
- Use **podman** (not docker sock) for `koopa-forgejo`.
- Symlink targets must be **container** paths (`/var/lib/gitea/custom/...`).
- Hook logs redact via gitleaks `--redact`; do not echo secrets.
- Laptop SSH: `Host git.hacktivism.ch` ProxyJump koopa, Port 9200, User git.
- Local SoT scripts: `$HOME/git/llm/llm-configs/bin/forgejo-hooks/`.

View file

@ -0,0 +1,60 @@
# 2026-09-12 — *enc inventur → rewrite → hooks smoke (REPORT ONLY)
**Status:** report only — **no** admin-log / firefly / Taler push this stretch
**Freigabe:** YES rewrite / force-with-lease / hooks; admin-log = report only
**Host:** magikoopa (ops) + koopa Forgejo (`koopa-forgejo`)
**Credit stand:** PCT=0.0 @14:29 renew (authoritative); host `/c` also 0%
**Inventur park:** `$HOME/git/llm/llm-work-input/tmp/enc-inventur-20260912-STATUS.txt`
## Priority table (tip)
| Priority | Repo | Outcome |
|----------|------|---------|
| 1 | `grok-work-log-credit-enc` | **DONE** — was Klartext; git-crypt + orphan tip `877d3e7`; force-with-lease to `hernani/grok-work-log-credit-enc.git` (`e21c1fe`→`877d3e7`). Subject: `git-crypt: encrypt *enc tree (attrs+keys; wipe plain remote next)`. Dirty parked on `backup/pre-crypt-20260912` (`7f00501`). |
| 2 | `llm-work-output-enc` | **ORIGIN FIXED** — was empty index + wrong origin `hernani/git.git`. Reattached: clone correct `hernani/llm-work-output-enc.git`, unlock, overlay live. Tip `f853969` already `\0GITCRYPT`. `ORIGIN_OK` `LAYOUT_OK`. Local dirty overlay ≈2090 (not pushed this turn). |
| 2 | `llm-control-data-enc` | **LOCAL CRYPT ONLY** — wrong origin cleared; `git init` + sibling attrs + both GPG users; tip `6aec2c7` (encrypted `status.json`/`stats.json`/sqlite). Origin URL set to `hernani/llm-control-data-enc.git`. **Forgejo repo MISSING** — **no push** until create Freigabe. |
| 3 | `osaurus-work-log-enc` | **OPEN** — tree at `$HOME/git/llm/llm-work-logs/osaurus-work-log-enc`; no commits, no attrs/crypt, no usable remote. |
| 3 | `freenotes-data-enc` | **OPEN** — tree at `$HOME/git/src/freenotes-data-enc`; has `.gitattributes` + `.git-crypt`; **NO_REMOTE**. |
| tip OK | `dot-grok-enc`, `secrets-enc` family, `buerokratie-enc`, `llm-work-db-data-enc`, `grok-work-log-enc`, (+ credit-enc now) | tip encrypted; history-clean handoff list unchanged for remaining. |
## Wrong origin (cleared)
Both control + output previously pointed at **`hernani/git.git`** (ASC board). Cleared. **HALT** remains: never force-push *enc content to `hernani/git.git`.
## Hooks (TODO320) — reinstall + smoke 2026-09-12
Installer SoT: `$HOME/git/llm/llm-configs/bin/forgejo-hooks/`
Synced → koopa `~/koopa-forgejo/hooks-staging/` → `install-hooks-ht.sh`
```
OK gitleaks=8.21.2 repos_linked=32
podman exec koopa-forgejo /var/lib/gitea/custom/bin/smoke-todo320.sh
ALL SMOKES PASSED
(a) secret push denied
(b) enc ciphertext allowed
(c) enc plaintext denied
```
`grok-work-log-credit-enc.git` bare has `pre-receive.d/{gitleaks,git-crypt-enforce}` symlinks.
Bare `hernani/llm-control-data-enc.git` **absent** on Forgejo (matches ls-remote MISSING).
**Re-smoke 2026-09-12T15:37Z:** `ALL SMOKES PASSED` again (a deny secret / b allow ciphertext / c deny plaintext).
Inventur STATUS close block appended same turn.
## GPG recipients (credit + control)
- `31733E0C598D3A1CF70955D6CB5738652768F7E9` (pep)
- `8DB88672C5C9FD08373194B6EA1C30038C1D6498` (magikoopa)
## Blocked / needs next Freigabe
1. **Create** Forgejo `hernani/llm-control-data-enc` (private) → then first push of `6aec2c7` + re-run installer for new bare hooks.
2. Optional: commit/push work-output dirty overlay (2090) after review.
3. P3: osaurus init+crypt+remote; freenotes add correct remote + push policy.
4. Admin-log **push** of this file (report-only until Freigabe).
## HALT (unchanged)
- No ladder restart `@START_N=333`
- No admin-log / firefly / Taler push without Freigabe
- No force-push to `hernani/git.git`

View file

@ -0,0 +1,124 @@
# 2026-09-15 — GOA Ansible Merchant-first
**Freigabe:** Live-Stop / Caddy = nein bis Chat-OK.
**Feed:** `taler-deployment` `origin/dev/hernani/regio-goa-explorational-currency`
**Work branch:** `dev/hernani/goa-regio-ng-vanilla`
## Naming
| | |
|--|--|
| **vanilla** | Ansible Vollkomposition (Merchant+Exchange+Bank+nginx/pg); GOA-Ersatz-Kandidat |
| **local** | Lab only: loopback / `goa.local` |
`configs/lab-local/goa-regio-ng` = **vanilla** @ **local**. Nie `REGIO_PUBLISH_KOOPA_PORTS=1` neben Live.
## Ist (lab green)
```bash
ssh hernani@koopa 'podman ps --format "{{.Names}} {{.Status}} {{.Ports}}" | grep -E "goa-regio|taler-hacktivism"'
# taler-hacktivism* Up 9010–9015
# goa-regio-ng Up 127.0.0.1:9180→80, 127.0.0.1:9322→22
ssh hernani@koopa "podman exec goa-regio-ng sh -c '
for u in nginx postgresql libeufin-bank taler-merchant-httpd taler-exchange-httpd taler-merchant.target; do
printf \"%s=\"; systemctl is-active \$u
done'"
# all=active
ssh hernani@koopa 'for h in bank.goa.local exchange.goa.local backend.goa.local; do
curl -sS -o /dev/null -w "$h %{http_code}\n" -H "Host: $h" http://127.0.0.1:9180/config
done'
# all 200
ssh hernani@koopa 'curl -sS -H "Host: exchange.goa.local" http://127.0.0.1:9180/keys' \
| python3 -c 'import sys,json;d=json.load(sys.stdin);print(d["master_public_key"],d["currency"],len(d.get("denominations",[])))'
# TW6K5… GOA 27
```
| Piece | Live | Lab vanilla@local |
|-------|------|-------------------|
| Merchant | :9010 | **active** · instance `default` |
| Exchange | :9011 | **active** · master TW6K5 · 27 denoms |
| Bank | :9012 | libeufin-bank OK |
| MASTER | TW6K5… | sha256 match enc `current/exchange-offline/master.priv` |
Playbook: `ok=92 changed=20 failed=0` after `/etc/hosts` pin (bank.goa.local NXDOMAIN once).
## Lab hosts (ephemeral)
Container recreate drops hosts. Re-pin:
```bash
cd $HOME/git/admin-logs/local/koopa-admin-log/configs/lab-local
ansible-playbook -i goa-regio-ng-koopa.yml lab-hosts.yml
# unsafe_writes — /etc/hosts EBUSY on atomic rename inside podman
```
## Merchant token (lab)
SoT: `koopa-admin-secrets-enc/backups/goa/lab-local/merchant/secrets/merchant-default-access-token`
passwd = PLAIN; Bearer = file value as-is (`secret-token:…`). `/instances/default/private/products` **200**.
`/config` `"currency":"CHF"` = tip dual-merchant; GOA under `currencies.GOA`.
## t2 — wire + order + withdraw + pay (lab) **done**
Bank acct `lab-merchant` via `libeufin-bank create-account`; secrets under `…/lab-local/merchant/secrets/`. Wire `x-taler-bank`.
```bash
# POST /instances/default/private/accounts → 200 salt/h_wire
# POST orders GOA:1 → 200 unpaid
# create-token labwallet; POST withdrawals; wallet-cli withdraw; POST confirm → 204
# handle-uri --yes "$taler_pay_uri"
```
| | |
|--|--|
| WID | `1eab9b0d-a3a8-41a8-b070-d7645b25ab25` |
| withdraw | `txn:withdrawal:2EBFWF7GK415A151KP56MWCVK2CYMDHMR55Q9BG11VT6NR55YC80` final |
| pay | `txn:payment:D4H75B5YDNJ52G8T6ADBDCXVWXCVZBG5HVSGE7G4S0XBQ6K8H3Y0` done |
| order | `2026.257-6E75WGDBR32M4` **paid** |
| wallet | GOA:9 (GOA:10 − GOA:1); CLI 1.6.43 **inside** `goa-regio-ng` |
## Zielbild
Ansible = SoT. Zwei Formen, gleiche Playbooks: **Full-stack Podman** · **Recreate-Fabrik**.
Branch: **master = stage**; anderer = **prod**. Kein `STAGE_ENV`.
**Reihenfolge:** **1 GOA** → **2 FP/Stage** (zwei Stacks) → **3 mytops-***. Merchant-Probleme → mytops vorziehen.
Gate: elelmon moderate → purse/withdraw → lab harden → Live-Merchant cutover nur wenn 1–3 grün → restore-back. Greenfield `*.2.*` PARK.
## APPLY 20260915T0013Z
BACKUP+APT+COMMIT OK. APPLY_SMOKE_FAIL was `sm=$(smoke)` capture; driver now `if smoke; then` → **APPLY_OK**. Smoke endpoints 200. Live bank/exchange/merchant Up; lab `goa-regio-ng` Up. Images retagged `:live` / `:landing`.
## Arbeit 1 — live confirm overflow (2026-09-16) **FAIL**
Smoke: `$HOME/git/llm/llm-work-input/goa-confirm-smoke.sh` (fresh scratch wallet; WCLI `$HOME/.local/bin/taler-wallet-cli.mjs`).
| | |
|--|--|
| user | `cfm18923` 2026-09-16T00:35:23Z |
| max_debt | acct#1=1e12 · **#2=1e8** · #3=1e12 |
| credit | GOA:4798.5 **200** |
| TOS | `exchanges add` + `update` + `accept-tos` **OK** |
| GOA:20 WID | `062e3112-e235-4fea-95d1-644773100224` |
| create | body `amount` + `exchange_url` → **200** |
| force-select | rpub + epayto from `/keys` → **200** `selected` |
| confirm | POST `/accounts/{user}/withdrawals/{wid}/confirm` → **500** code **5110** P0001 `amount value overflowed` |
| GOA:4200 | same scratch rpub → **409** code **5114** Reserve pub already used (script; skip until GOA:20 green) |
`CONFIRM_SMOKE_FAIL`. Select+TOS+RPUB green for GOA:20; overflow still at confirm. Next: dump `make_incoming` / `bank_wire_transfer` for that WID; lower remaining 1e12 if dump confirms.
## Pointers
| | |
|--|--|
| inventory | `configs/lab-local/goa-regio-ng-koopa.yml` |
| lab hosts | `configs/lab-local/lab-hosts.yml` |
| Lab README | `configs/lab-local/README.md` |
| backup daylog | `2026/2026-09-04--goa-backup-regio-ng.md` |
| APPLY driver | `scripts/taler-shared/goa-live-backup-upgrade.sh` |
| dumps | koopa `~/backups/goa/current` → `20260904T1238Z` |
| Caddy | taler→9010 · exchange→9011 · bank→9012 |
Leave-off: t1+t2 lab green. Live confirm **5110**. No Live-Stop / no Caddy.

View file

@ -0,0 +1,39 @@
# 2026-09-18 — koopa as external amanita probe logger
## Why
Amanita hard hangs leave no panic; internal heartbeat stops with the box.
External ICMP+SSH from **koopa** records last-alive independently so hang vs
power/PSU can be separated after the next freeze.
## Live (hernani@koopa)
| Piece | Detail |
|-------|--------|
| Key | `~/.ssh/id_ed25519_amanita_probe` — fingerprint `SHA256:R2i2nZfI1svR6Ts3DaSw5eZj2fvnGgm1R9PoMFS4Jj0` |
| SSH Host | `amanita-probe` → `vx@192.168.100.6`, IdentityFile that key only |
| Script | `~/.local/bin/koopa-amanita-probe` (SoT: `scripts/amanita-probe/`) |
| Timer | user `koopa-amanita-probe.timer` ~15 s, linger yes |
| Log | `~/.local/state/amanita-probe/amanita-probe.{log,last,meta}` — owned by hernani, mode 644 |
## amanita vx (only)
Restricted `authorized_keys` line (not on root):
```text
from="192.168.100.95",no-agent-forwarding,no-port-forwarding,no-X11-forwarding,no-pty,command="/bin/cat /var/lib/amanita/heartbeat.last" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBeMenvp0D9EarfAEUtu49Q7bCbGhw+R/E1nJPQSSmZc koopa-amanita-probe@hernani-koopa
```
Forced command only cats the world-readable HB mirror. No shell, no agent/X11/port forward.
## Verify (2026-09-18 ~15:09 CEST)
- `systemctl --user is-active koopa-amanita-probe.timer` → active
- `ssh amanita-probe` → EXIT 0, one HB line
- meta: `icmp=ok ssh=ok gap_s≈15`
- hernani can read the probe log dir on koopa (owner)
## Docs / install
`scripts/amanita-probe/README.md` + `install-amanita-probe.sh`.
Do **not** put this key on root AK; do **not** bare `modprobe ramoops`.

View file

@ -0,0 +1,46 @@
# 2026-09-19 — GOA single-CTR: login-health + monitoring
## Why
`koopa-login-health` FAIL×3 on dead `taler-hacktivism*` + WARN `koopa-tor-relay`.
Live stack is **`goa-regio-ng`** (pasta 9010–9015) + host **`tor.service`** (ORPort 8080).
## Live SoT (hernani@koopa)
| Piece | Detail |
|-------|--------|
| GOA CTR | `goa-regio-ng` — image `localhost/goa-regio-ng:empty-current` |
| Scripts | `~/scripts/taler-shared/goa-regio-ng/` · `goa-all-in-one.sh` |
| Bak | `~/backups/goa/current` |
| Landings | host `/var/www/*-landing/` + `~/goa-landing-deploy` · Caddy outside CTR |
| Tor | host `tor.service` — **not** container `koopa-tor-relay` |
| Forgejo | `:9024/:9200` · edge Caddy `:9000/:9001` |
## Repo changes (magikoopa, no push yet)
**koopa-admin-log**
- `scripts/login-health/`: CRITICAL/EXPECT → `goa-regio-ng` (+ forgejo); drop legacy + tor-relay; host `tor.service` check; probes 9010–9012
- delete `host/overview/{LIVE,services}.*` · delete `configs/tor/*`
- rewrite `host/tor/README.md` · shorten README / ports / koopa-setup / login-health README
- ISSUES I-07 → host Tor SoT
**elelmon + taler-monitoring** (EQ scripts mirrored)
- BANK=EX=MER=`goa-regio-ng`; drop nginx-in-bank; host stats.json fallback
- `check_{server,inside,urls,versions,e2e,sanity}.sh` · `metrics.sh` · `lib.sh` · docs
## Verify (after deploy on koopa — Freigabe)
```bash
koopa-login-health show -v
# expect: goa-regio-ng OK · no taler-hacktivism* · tor.service OK|WARN
```
STATE dir name `taler-hacktivism-monitoring` kept (host-agent path, not CTR).
## Follow-up (same day) — elelmon-only SoT
- Forgejo `hernani/taler-monitoring` **archived**; push fails. Do not maintain twin.
- Parity leftover (mail-deliverability) → **elelmon** only (`check_mail_deliverability.sh`,
`mail_deliv_probe.py`, host-agent timer, wrapper phase `mail-deliverability|maildeliv`).
- Canonical clone/install path: `~/src/elelmon` — see `scripts/taler-monitoring/README.md`.
- Modular Python rewrite scaffold under elelmon package `elelmon/` (not flat TM `check_*.sh` layout).

View file

@ -0,0 +1,32 @@
# 2026-09-23 — GOA merchant /terms+/privacy + mon green
## Why
Public merchant `taler.hacktivism.ch` lacked `/terms` + `/privacy` (501).
elelmon still assumed legacy multi-CTR `taler-hacktivism*`; live SoT is single
CTR **`goa-regio-ng`** (pasta 9010–9015).
## Live (hernani@koopa)
| Piece | Detail |
|-------|--------|
| CTR | `goa-regio-ng` · BANK=EX=MER same |
| Terms | `TERMS_ETAG=merchant-tos-dual-v2` · en under `/var/lib/taler-merchant/terms/` |
| Privacy | `PRIVACY_ETAG=merchant-pp-swiss-v0` |
| Drop-in | `/etc/taler-merchant/conf.d/terms-privacy.conf` · httpd restart |
| Public | `https://taler.hacktivism.ch/{terms,privacy}` → **200** |
| Mon stamp | `20260923T075931Z` · LOG `~/.local/state/elelmon-runs/hacktivism-full-….log` |
| Mon result | EXIT=0 · 182 OK · 0 ERROR · 21 WARN · 21 INFO |
| Public mon | staging → `/var/www/monitoring-sites/{host}/monitoring/` |
## Repo SoT (magikoopa)
**koopa-admin-log** — profile/scripts already had ETAGs + install helpers;
runtime apply on CTR today. Caddyfile dossiers `try_files` → `{path} {path}/ {path}/index.html`
(separate commit).
**elelmon** — laptop tip goa-aware (clean); koopa WT may still need SSH pull.
## Hold
Cutover locked. No `taler-deployment` master push. Next: T3 vanilla Ansible lokal → T2 APT (Freigabe).

View file

@ -0,0 +1,39 @@
# 2026-09-25 — qBittorrent BT net (flame / firewalled)
## Goal
Inbound BT listen **6881** tcp+udp reachable so WebUI connection status leaves the firewalled (flame) state.
## Live on koopa
- CTR `koopa-prime-qbittorrent` (linuxserver): host **6881** tcp+udp, WebUI **9023**→8080 → `bt.hacktivism.ch`
- Conf: `Session\Port=6881`, `PortForwardingEnabled=true`, `Connection\UPnP=true`
- Temp: `/downloads/incomplete/` (abc / host uid 100999)
- Durable apply: `scripts/prime/apply-qbittorrent-bt-net.sh` (+ wrapper `koopa-bt-fix.sh`)
- Clone on host: `~/koopa-admin-log/scripts/prime/`
## firewalld
- Doc: `configs/firewalld/public-ports.md` — **6881/tcp+udp**
- Agent cannot list without sudo/polkit; human opens with:
```bash
sudo firewall-cmd --permanent --add-port=6881/tcp
sudo firewall-cmd --permanent --add-port=6881/udp
sudo firewall-cmd --reload
```
- WAN probe success (below) implies the path through host firewall is open.
## VeciGate (2026-09-25)
- wan `dstnat` tcp+udp **6881** → `192.168.100.95:6881`
- hairpin LAN `192.168.100.0/24` and LAN2 `192.168.88.0/24` → `212.51.151.254:6881` tcp+udp
- Comments: `koopa: qBittorrent BT …` / `hairpin: LAN[2] qBittorrent BT …`
- Detail: vecigate-admin-log `2026/2026-09-25--qbittorrent-bt-dnat.md`
## Verify (2026-09-25, from magikoopa)
| Probe | Result |
|-------|--------|
| `nc -vz 192.168.100.95 6881` | LAN_TCP_OK |
| `nc -vz 212.51.151.254 6881` | WAN_TCP_OK |
| `nc -zu 212.51.151.254 6881` | WAN_UDP_OK |
WebUI API (`/api/v2/…`) still auth-gated from agent — human glance at connection icon on `bt.hacktivism.ch`.
## Freigabe
Session Freigabe covered podman conf/restart + VeciGate NAT. No git push of admin-log unless asked.

View file

@ -0,0 +1,51 @@
# tech-dossier Freeze cascade — 2026-09-28
Repo: `$HOME/git/src/ngi/tech-dossier-project-data`
Ladder (each tip autonomously `make html`; each depends on the previous):
| # | Branch | Tip | Local serve | Live ht root |
|---|--------|-----|-------------|--------------|
| 1 | `main` | `d2fbd79` | http://127.0.0.1:8101/ | — |
| 2 | `feat/sm-content` | `089ef1f` | http://127.0.0.1:8102/ | `dossiers.3.ngi.hacktivism.ch` (optional) |
| 3 | `feat/website-features` | `53a3176` | http://127.0.0.1:8103/ | `dossiers.2.ngi.hacktivism.ch` (optional) |
| 4 | `feat/website-design` | `2e26c80` | http://127.0.0.1:8104/ | — (no public host after views deploy) |
| 5 | `feat/website-views` | `bbafc38` (origin tip; local soft-reset dropped bad `1b2fcf7`/`7aca0e8`) | http://127.0.0.1:8105/ | path roots under blank landing (see Live) |
Caddy roots (SoT `scripts/caddy/Caddyfile.koopa-live-wdGet`):
- `/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch`
- `/var/www/monitoring-sites/dossiers.2.ngi.hacktivism.ch`
- `/var/www/monitoring-sites/dossiers.3.ngi.hacktivism.ch`
basic_auth: `scripts/caddy/apply-dossiers-ngi-basicauth.sh`
## Local cascade links
- [main](http://127.0.0.1:8101/)
- [feat/sm-content](http://127.0.0.1:8102/)
- [feat/website-features](http://127.0.0.1:8103/)
- [feat/website-design](http://127.0.0.1:8104/)
- [feat/website-views](http://127.0.0.1:8105/)
## Live
- [dossiers.ngi](https://dossiers.ngi.hacktivism.ch/) ← **blank cascade landing** (kal `sites/dossiers.ngi.hacktivism.ch/`; EN + ASCII ladder; views tip cite `bbafc38`)
- Path editions: `/main/`, `/feat-sm-content/`, `/feat-website-features/`, `/feat-website-design/`, `/feat-website-views/`
- Hourly branch-status builder: **kal** `scripts/dossiers-ngi/branch-status-hourly.py` → `sites/…/branch-status.json` (+ user timer); **not** inside tdpd
- tdpd `feat/website-views` local HEAD = origin = `bbafc38` (NO_PUSH; bad tips discarded locally)
- [dossiers.2.ngi](https://dossiers.2.ngi.hacktivism.ch/) ← website-features (optional)
- [dossiers.3.ngi](https://dossiers.3.ngi.hacktivism.ch/) ← sm-content (optional)
## Deploy (Freigabe 2026-09-28 design; Freigabe 2026-09-29 views; Freigabe blank landing same day)
Earlier primary: rsync `website/build/` from tip `feat/website-views` →
`hernani@koopa:/var/www/monitoring-sites/dossiers.ngi.hacktivism.ch/`
(`--delete`, exclude `.DS_Store`).
**Result 2026-09-28 ~22:25+02 (design @ `2e26c80`):** `RSYNC_OK` — ~2698 files / ~27M; live `dossier/sm/index.html` 41693 bytes.
**Result 2026-09-29 ~04:30+02 (views-era freeze):** `RSYNC_OK` — live `/` HTTP 200. Local tdpd later briefly carried wrong tips `1b2fcf7` → `7aca0e8` (ladder rewrite + hourly in tdpd); those were **dropped** locally back to `bbafc38` (TODO=430). Never push those tips.
**Result 2026-09-29 (blank landing kal @ `56ee97a`):** `RSYNC_OK` — live `/` HTTP 200 SIZE=3505 title `cascade landing`; path-root editions owned by koopa-admin-log `sites/dossiers.ngi.hacktivism.ch/`; NO_PUSH.
**TODO=430 follow-up (local, NO_PUSH):** kal landing EN/ASCII + tip cite `bbafc38`; hourly builder + systemd under kal; daylog tip table corrected. Deploy landing / enable timer on koopa needs Freigabe.

View file

@ -0,0 +1,57 @@
# Forgejo host RO users (rabbithole-ro, amanita-ro, firecuda-ro)
Created 2026-10-20 on koopa Forgejo for targeted **read-only** clones of selected `hernani/*` repos (replace host-local tree copies via git, no rsync/scp of SoT).
## Users
| Username | ID | Email | Flags |
|----------|----|-------|-------|
| `rabbithole-ro` | 182 | `rabbithole-ro@hosts.hacktivism.ch` | active, restricted, not admin |
| `amanita-ro` | 183 | `amanita-ro@hosts.hacktivism.ch` | active, restricted, not admin |
| `firecuda-ro` | 184 | `firecuda-ro@hosts.hacktivism.ch` | active, restricted, not admin |
## Repo access
- Collaborator **read** on `hernani/waldpfad` (all three).
- SSH user keys titled `*-host-ro` (ed25519) uploaded via oneshot admin token.
## Secrets (enc only)
Laptop SoT (git-crypt):
`PATH[koopa-admin-secrets-enc]/koopa/home-hernani/koopa-forgejo/hosts/{rabbithole,amanita,firecuda}-ro/`
Per host: `password.txt` (600), `ssh/id_ed25519` (+ `.pub`), `README.md`. Never commit plaintext; never grant write collab.
## Create recipe (idempotent)
On koopa as `hernani`, Forgejo HTTP **9024**:
```bash
podman exec koopa-forgejo gitea admin user create \
--username USER --email USER@hosts.hacktivism.ch \
--random-password --must-change-password=false --restricted
```
SSH key + read collab via oneshot token (`write:admin,write:repository,write:user`) against `http://127.0.0.1:9024/api/v1`:
- `POST /admin/users/USER/keys` with `{"title","key"}`
- `PUT /repos/hernani/waldpfad/collaborators/USER` with `{"permission":"read"}`
Purge leftover `oneshot-*` tokens in Forgejo UI (API delete often 403). Wipe `/tmp/*.pub` / oneshot scripts after use.
## Clone pattern (on target host)
```bash
GIT_SSH_COMMAND='ssh -i /path/to/id_ed25519 -o IdentitiesOnly=yes -o BatchMode=yes' \
git clone --depth 1 --single-branch --branch master \
ssh://git@git.hacktivism.ch:9200/hernani/waldpfad.git
```
Or Host stanza with `IdentityFile` for that RO key and `User git` / Port 9200 (ProxyJump as needed).
## Related
- Forgejo rootless: `2026-07-10--forgejo-rootless.md`
- Oneshot token pattern: `2026-09-07--git-meta-origin-forgejo.md`
- Host skill: Forgejo ports 9200 SSH / 9024 HTTP; secrets always `*enc`

View file

@ -0,0 +1,13 @@
# Castopod stays off
Rechecked 2026-10-21 after the stop note. Web unit container-koopa-castopod.service is disabled, inactive, dead. Container koopa-castopod is exited, finished 2026-10-21 22:48:06 +0200. Nothing listens on :9020. MariaDB and Redis user units stay loaded and active. No second stop. Caddy vhost unchanged.
Log review found no sign of a successful remote code execution. Overlay file /tmp/fw-cp.php (1448 bytes, mode 600, sha256 7bb279bffa12dbb81787183108a2641b78a6657b069cbef7967950d80e13b5bc, mtime 2026-09-07 03:25:59 +0200) is a local database script for cp_users, outside the docroot, not a web shell. /tmp/os-dry.out is an apt dry-run. Five theme files differ by one branding line from 2026-07-13. Media volume has no scripts. Access logs run 2026-10-17 through the stop and show no 2xx on a non-index script. Critical lines on 2026-09-07 match other days.
Limits: access logs start 2026-10-17, so HTTP from 2026-09-07 is absent. A memory-only or already rotated request is not ruled out. Whether the local script ran is not in the logs. MariaDB was not opened.
Stays down until an image ships PHP newer than 8.4.18. Hub tag :1 from 2026-02-24 is not that image. Parent 537, slug castopod-restart-after-php-fix.
Restore only then:
systemctl --user enable --now container-koopa-castopod.service

View file

@ -0,0 +1,23 @@
# Castopod PHP stopped
Checked 2026-10-21. Host has no php-fpm and no php package. The only PHP process was Castopod FrankenPHP in container koopa-castopod.
| Item | Value |
|------|--------|
| image | docker.io/castopod/castopod:1 |
| repo digest | sha256:4e4f0440520f45257bfeac7be4347defd20048b4efef8f53d73ec9ed3a4f7966 |
| amd64 digest | sha256:757f3c2a96b31b81753c23bc092dfcf05039d9df4d13cc12c428bb752fce882b |
| image created | 2026-02-24 |
| hub tags 1 / latest / 1.15.5 | same digest, pushed 2026-02-24 |
| PHP | 8.4.18 (12 Feb 2026) |
| FrankenPHP | v2.10.2 |
| listen | 0.0.0.0:9020 -> 8080 |
| public | https://castopod.hacktivism.ch/ |
Stable Hub tags have not moved since 2026-02-24. develop last push 2026-06-05 and is not a stable security update. php.net lists 8.4.26 (24 Sep 2026) and 8.4.27 (22 Oct 2026) after 8.4.18, with a banner to update for critical remote code execution. Pulling :1 repeats the same image. FrankenPHP ships its own PHP binary.
Stopped and disabled user unit container-koopa-castopod.service. ExecStop is `podman stop -t 30 koopa-castopod`. Container status after stop: Exited (0). :9020 not listening. MariaDB and Redis units left running. Caddy vhost unchanged.
Bring the web container back only when a newer image exists:
systemctl --user enable --now container-koopa-castopod.service

View file

@ -0,0 +1,41 @@
# TODO=704 Tor CachyOS CTR + CookieAuth (koopa)
Relay was down (stale PIDFile / start-timeout on forking unit), keys intact. Recreated **same identity** on CachyOS container; CookieAuth for ControlPort; host tor disabled.
## Stand after APPLY (2026-10-24 ~21:47–21:51 Europe/Zurich)
| Item | Value |
|------|--------|
| CTR | `koopa-tor-relay` Up, image `localhost/koopa-tor-relay:latest` (=`:cachyos`) |
| Tor | 0.4.9.14 (CachyOS/Arch extra) |
| Unit | `container-koopa-tor-relay.service` Type=simple, active |
| Host tor | `tor.service` disabled + failed/inactive |
| FP | `02C7EECCDF7814FBA2DB1CBAED000D06E8A32EE8` (keys mtime 2024-11-14) |
| ORPort | 8080 |
| ControlPort | 127.0.0.1:9051 CookieAuthentication=1, CookieAuthFile=/var/lib/tor/control_auth_cookie |
| Bootstrap | PROGRESS=100 done; status/circuit-established=1 |
| Unauth ControlPort | 514 Authentication required |
| Cookie AUTH | 250 OK |
## Steps
1. Dry-run `/tmp/tor.sh` on koopa → STATUS=dry-run-ok; NEXT=`sudo APPLY=1 /tmp/tor.sh` (host tor was still enabled).
2. Human: `systemctl disable --now tor.service`, then `sudo APPLY=1 /tmp/tor.sh`.
3. APPLY: wrote CachyOS Containerfile, pulled `docker.io/cachyos/cachyos:latest`, build (cache hit), `podman create --replace --network host --user 1000:1000 --userns keep-id`, torrc bak `torrc.bak-cookie-20261024-214720`, CookieAuth on.
4. First APPLY hit dbus fail under sudo (`$DBUS_SESSION_BUS_ADDRESS` / `$XDG_RUNTIME_DIR` unset). Unit rewrite + enable finished with XDG/DBUS set; script path re-exec as SUDO_USER for later runs.
5. Verify from magikoopa SSH: unit active, CTR Up, FP match, circuit-established=1, unauth 514.
## Live paths
- `~/koopa-tor-relay/{torrc,data,log,build/Containerfile}`
- `~/.config/systemd/user/container-koopa-tor-relay.service`
- Driver: `/tmp/tor.sh` (TARGET=koopa); upgrade later: `~/upgrade-containers.sh --apply --rebuild-local --only koopa-tor-relay`
## Akte mirrors
- `configs/tor/torrc`
- `configs/tor/build/Containerfile`
- `configs/systemd/user/container-koopa-tor-relay.service`
- `host/tor/README.md` updated (was stale host `tor.service`)
Sibling: firecuda brew tor CookieAuth same day (FP `52BB94DDC1292F950CF728708AC48523E018A718`, MyFamily both ways). Parent TODO=704.

5
AGENTS.md Normal file
View file

@ -0,0 +1,5 @@
# AGENTS.md
Session Must / Must not: `$HOME/.grok/AGENTS.md` only — do not duplicate.
**Sync (must-sync trees / wenn Git allein nicht reicht):** siehe [SYNC.md](SYNC.md).

View file

@ -12,7 +12,7 @@ Stand **2026-07-18** (koopa, live). Keine Secrets.
| [I-04](#i-2026-07-16-04) | low | open | Stray `kind_taussig` | | [I-04](#i-2026-07-16-04) | low | open | Stray `kind_taussig` |
| [I-05](#i-2026-07-16-05) | low | open | Alte exited Podman-Container | | [I-05](#i-2026-07-16-05) | low | open | Alte exited Podman-Container |
| [I-06](#i-2026-07-16-06) | low–medium | open | Nym HTTP API `*:9080` | | [I-06](#i-2026-07-16-06) | low–medium | open | Nym HTTP API `*:9080` |
| [I-07](#i-2026-07-16-07) | medium | **fixed** | Tor host vs `koopa-tor-relay` | | [I-07](#i-2026-07-16-07) | medium | **fixed** | Tor = host `tor.service` (not container) |
| [I-08](#i-2026-07-17-08) | medium | open | Landing-stats → standalone `taler-landing-stats` | | [I-08](#i-2026-07-17-08) | medium | open | Landing-stats → standalone `taler-landing-stats` |
| [I-09](#i-2026-07-18-09) | high | open | Monitoring-HTML öffentlich: Caddy/www (code 21) | | [I-09](#i-2026-07-18-09) | high | open | Monitoring-HTML öffentlich: Caddy/www (code 21) |
@ -36,7 +36,7 @@ sudo ~/koopa-caddy/apply-monitoring-live.sh
``` ```
Details: `2026/2026-07-18--monitoring-public-caddy.md` Details: `2026/2026-07-18--monitoring-public-caddy.md`
Suite: https://git.hacktivism.ch/hernani/taler-monitoring (v1.7.1+) Suite: https://git.hacktivism.ch/hernani/elelmon (`taler-monitoring.sh`; archived twin not SoT)
### I-2026-07-16-01 ### I-2026-07-16-01
@ -134,24 +134,18 @@ Hinweis: `nym-node` startet intern mit `--http-bind-address [::]:8080` (Containe
### I-2026-07-16-07 ### I-2026-07-16-07
**`koopa-tor-relay` vs host `tor.service` (Port-Clash)** **Tor = host `tor.service` (ORPort 8080)**
Severity: medium · Host: koopa · Status: **fixed** 2026-07-16 Severity: medium · Host: koopa · Status: **fixed** (SoT 2026-09)
**War:** Nach Reboot crash-loopte `koopa-tor-relay` — Host-`tor.service` hielt **8080**/**9051**. **Live:** host **`tor.service`** · ORPort **8080** · ControlPort **9051** · non-exit.
**Soll:** nur Container (`KoopaRelay`, ORPort **8080**, VeciGate WAN→koopa:8080). Legacy CTR `koopa-tor-relay` / `configs/tor/` removed from inventory (git history keeps them).
**Fix:** Host-Tor gestoppt/disabled; ggf. hängenden Prozess gekillt; User-Unit:
```bash ```bash
sudo systemctl disable --now tor systemctl status tor
sudo systemctl mask tor # optional
systemctl --user enable --now container-koopa-tor-relay.service
ss -lntp | grep -E '8080|9051' ss -lntp | grep -E '8080|9051'
podman ps --filter name=koopa-tor-relay # login-health: WARN if tor.service not active
``` ```
**Live (nach Fix):** Host-`tor` inactive/disabled; `koopa-tor-relay` Up; 8080 + 127.0.0.1:9051 vom Relay-Prozess.
--- ---
### I-2026-07-17-08 ### I-2026-07-17-08
@ -177,4 +171,4 @@ Severity: medium · Host: koopa · Status: open · **TODO (noch nicht umsetzen a
- Prod-Container mit Boot-Autostart: Up - Prod-Container mit Boot-Autostart: Up
- Taler-Ports 9010–9015 antworten (401/302 OK) - Taler-Ports 9010–9015 antworten (401/302 OK)
- Linger=yes, container-*-Units enabled - Linger=yes, container-*-Units enabled
- Tor-OR: Container-Pfad (I-07 fixed) - Tor-OR: host `tor.service` (I-07)

View file

@ -6,6 +6,10 @@ Ops log and config mirror for host **koopa** (openSUSE Tumbleweed).
**Secrets:** not in this repo — see **`SECRETS.md`** and sibling **`koopa-admin-secrets`**. **Secrets:** not in this repo — see **`SECRETS.md`** and sibling **`koopa-admin-secrets`**.
## FIND / setup entry
Plain file **`koopa-setup`** — lab + host pointers (goa-regio-ng, ports, daylogs). Start there.
## Open issues ## Open issues
**Visible issue list:** [`ISSUES.md`](ISSUES.md) **Visible issue list:** [`ISSUES.md`](ISSUES.md)
@ -23,69 +27,32 @@ Hosted on **Forgejo rootless** (this host). See `2026/2026-07-10--admin-log-orig
## Layout ## Layout
``` ```
host/ # openSUSE host-level config + overview koopa-setup # FIND: lab/host setup pointers
overview/services.md # graphical service map host/ # openSUSE host-level (caddy, tor, systemd, …)
systemd/ firewalld/ caddy/ network/ configs/ # mirrored app configs (caddy, forgejo, …)
configs/ # mirrored app configs (caddy, taler, forgejo, …) scripts/ # login-health, GOA helpers, …
taler-hacktivism/ # merchant container taler-hacktivism login-health/ # SSH login snapshot
taler-hacktivism-bank/ # bank container (image …-banking) taler-shared/goa-regio-ng/ # live GOA SoT
taler-exchange/ # exchange conf (inside ansible container)
taler-exchange-ansible/ # container taler-hacktivism-exchange-ansible
forgejo/ # rootless git.hacktivism.ch
castopod/ bonfire/ lemmy/ prime/ # compose mirrors (no secret values)
tops/ # koopa-tops-ng1…ng3 + autostart unit
tor/ # KoopaRelay ORPort 8080
scripts/ # merchant, exchange, monitoring helpers
taler-merchant/ # merchant-model start scripts
taler-exchange/ # same model; archive/ = greenfield bootstrap
2026/ # day logs + dated topic notes 2026/ # day logs + dated topic notes
``` ```
## Live containers (podman) ## Live GOA + public stack
**Authoritative snapshot of host koopa:** [`host/overview/LIVE.md`](host/overview/LIVE.md) (refreshed from live). | Name | Role | Host ports |
|------|------|------------|
| Name (podman) | Role | Host port | | **`goa-regio-ng`** | bank + exchange + merchant (one CTR, pasta) | **9010–9012** APIs · **9013–9015** landings (host nginx) |
|---------------|------|-----------|
| `taler-hacktivism` | merchant | **9010** (+ landing **9015**) |
| **`taler-hacktivism-exchange-ansible`** | exchange (Ansible/systemd) | **9011** (+ landing **9014**) |
| `taler-hacktivism-bank` | libeufin-bank (GOA) | **9012** (+ landing **9013**) |
| `koopa-castopod` (+ mariadb/redis) | Castopod | **9020** |
| `koopa-bonfire` (+ postgres) | Bonfire | **9021** |
| `koopa-lemmy-proxy` (+ lemmy/ui/pictrs/db) | Lemmy | **9026** |
| `koopa-prime-jellyfin` | Jellyfin | **9022** |
| `koopa-prime-qbittorrent` | qBittorrent | **9023** |
| `koopa-forgejo` (+ postgres) | Forgejo rootless | **9024** + SSH **9200** | | `koopa-forgejo` (+ postgres) | Forgejo rootless | **9024** + SSH **9200** |
| `koopa-tops-ng1` … `ng3` | static nginx | **9090**–**9092** | | `koopa-castopod` / bonfire / lemmy / decidim / … | optional apps | **9020+** |
| `koopa-tops-ng1`…`ng3` | static nginx | **9090–9092** |
| host **`tor.service`** | Tor relay | ORPort **8080** · ControlPort **9051** |
Start model (Taler merchant/bank): **root** `start_base_services_*` → `/usr/local/bin/start_*.sh`. Start GOA: `scripts/taler-shared/goa-regio-ng/` · bak `~/backups/goa/current` · landings `~/goa-landing-deploy`.
Start model (exchange): `~/ansible-taler-exchange/` → `run-container-koopa.sh` + `deploy-hacktivism-goa.sh`. Edge: Caddy **9000/9001** → 127.0.0.1 backends.
Start model (user apps): `hernani` → `cd ~/koopa-* && podman-compose up -d`. Login snapshot: `scripts/login-health/` (`koopa-login-health`).
Start model (tops): user unit `container-koopa-tops.service` (linger).
Public hosts: `taler.` / `exchange.` / `bank.` / `castopod.` / `bonfire.` / `prime.` / `bt.` / **`git.hacktivism.ch`** / `lemmy.` / `tops.ng1`–`ng3`.hacktivism.ch
(Caddy → 9010–9015 / 9020–**9026** / **9090–9092**; git-SSH host **9200** direct).
Service **details**: `configs/taler-hacktivism*`, `configs/taler-exchange*`, `configs/forgejo/`, `configs/tops/`, `scripts/*`.
Host-wide picture: **`host/overview/services.md`**.
Port table: **`configs/ports.md`**. Port table: **`configs/ports.md`**.
Tor: **`host/tor/README.md`**.
Router: **`../vecigate-admin-log`**. Router: **`../vecigate-admin-log`**.
**Benchmarks** (drive from the local machine, measure on koopa): **`benchmarks/`** **Benchmarks:** `benchmarks/`
→ amount ladder: `benchmarks/amount-ladder/`. **Forgejo:** `2026/2026-07-10--forgejo-rootless.md` → https://git.hacktivism.ch/
**Exchange snapshot/restore (GOA, local images only):**
→ `2026/2026-07-09--exchange-snapshot-and-restore.md`
**Exchange `/keys` + Wire + bank account (diagram):**
`configs/taler-exchange/README.md` (section “/keys, Wire and Account”).
**Castopod (stack/accounts/boot — not podcast content):**
`2026/2026-07-09--castopod-content.md` → https://castopod.hacktivism.ch/
**Bonfire FEDERATE + guest public (2026-07-10):**
`2026/2026-07-10--bonfire-federate.md` → https://bonfire.hacktivism.ch/
(ground zero: `2026/2026-07-09--bonfire-ground-zero.md`)
**Forgejo rootless (git.hacktivism.ch, no free registration, SSH :9200):**
`2026/2026-07-10--forgejo-rootless.md` → https://git.hacktivism.ch/

View file

@ -1,12 +1,12 @@
# Secrets — not stored in this repo # Secrets — not stored in this repo
Live passwords/keys live in sibling **`koopa-admin-secrets`**. Live passwords/keys live in sibling **`koopa-admin-secrets-enc-enc`**.
## Map ## Map
### Taler — host `/root` ### Taler — host `/root`
| What | Mirror (`koopa-admin-secrets/…`) | Live | | What | Mirror (`koopa-admin-secrets-enc/…`) | Live |
|------|----------------------------------|------| |------|----------------------------------|------|
| Bank admin/exchange/explorer/demo/bench | `koopa/host-root/taler-bank/*.txt` | `/root/bank-*-password.txt` | | Bank admin/exchange/explorer/demo/bench | `koopa/host-root/taler-bank/*.txt` | `/root/bank-*-password.txt` |
| Merchant instance goa-demo | `koopa/host-root/taler-merchant/…` | `/root/merchant-*-password.txt` | | Merchant instance goa-demo | `koopa/host-root/taler-merchant/…` | `/root/merchant-*-password.txt` |
@ -19,7 +19,6 @@ Live passwords/keys live in sibling **`koopa-admin-secrets`**.
|------|--------|------| |------|--------|------|
| Castopod | `koopa/home-hernani/koopa-castopod/{.env,users.env}` (+ compose mirror in admin-log `configs/castopod/`) | `~/koopa-castopod/` | | Castopod | `koopa/home-hernani/koopa-castopod/{.env,users.env}` (+ compose mirror in admin-log `configs/castopod/`) | `~/koopa-castopod/` |
| Lemmy | host-only `~/koopa-lemmy/{.env,lemmy.hjson}` (compose mirror in admin-log `configs/lemmy/`) | `~/koopa-lemmy/` | | Lemmy | host-only `~/koopa-lemmy/{.env,lemmy.hjson}` (compose mirror in admin-log `configs/lemmy/`) | `~/koopa-lemmy/` |
| Decidim | host-only `~/koopa-decidim/{.env,users.env}` (compose mirror in admin-log `configs/decidim/`) | `~/koopa-decidim/` |
| Bonfire (`FEDERATE=true`) | `koopa/home-hernani/koopa-bonfire/{.env,users.env,compose.yml}` | `~/koopa-bonfire/` | | Bonfire (`FEDERATE=true`) | `koopa/home-hernani/koopa-bonfire/{.env,users.env,compose.yml}` | `~/koopa-bonfire/` |
| Prime (Jellyfin + qBittorrent) | `koopa/home-hernani/koopa-prime/{.env,users.env}` | `~/koopa-prime/` | | Prime (Jellyfin + qBittorrent) | `koopa/home-hernani/koopa-prime/{.env,users.env}` | `~/koopa-prime/` |
| Forgejo (**rootless**, git.hacktivism.ch) | `koopa/home-hernani/koopa-forgejo/{.env,users.env,compose.yml}` | `~/koopa-forgejo/` | | Forgejo (**rootless**, git.hacktivism.ch) | `koopa/home-hernani/koopa-forgejo/{.env,users.env,compose.yml}` | `~/koopa-forgejo/` |
@ -29,8 +28,8 @@ Live passwords/keys live in sibling **`koopa-admin-secrets`**.
## Rules ## Rules
- **koopa-admin-log**: paths only; `@inline-secret@` in configs, never password/key material. - **koopa-admin-log**: paths only; `@inline-secret@` in configs, never password/key material.
- Pull/deploy: `koopa-admin-secrets/scripts/{pull,deploy}-from-koopa.sh` - Pull/deploy: `koopa-admin-secrets-enc/scripts/{pull,deploy}-from-koopa.sh`
- Full inventory: `koopa-admin-secrets/MAP.md` - Full inventory: `koopa-admin-secrets-enc/MAP.md`
## Public (OK here) ## Public (OK here)

146
SYNC.md Normal file
View file

@ -0,0 +1,146 @@
# SYNC.md — must-sync (pull.sh / push.sh)
**SoT:** Git tip auf ht/Forgejo (`hernani/*`), nicht grok-all-Pack, nicht ASC-only.
**Dieses Set:** Profile `grok` + `llm` (=`combo`) + `hernani`.
**Nicht in diesem Set:** `taler` / `admin-logs/taler/` (eigenes Profil).
**Parties (local crossover):** magikoopa · clementine · koopatroopa (plus weitere Hosts unter `admin-logs/local/`).
**Meta-Skripte:** `$HOME/git/pull.sh` · `$HOME/git/push.sh` · `$HOME/git/profiles/*.repos`
Agents sollen diese Bäume **laufend** auf dem gleichen Tip halten (pull oft; push nur mit Freigabe).
---
## 1. Schnell: was Agents tun
| Wann | Aktion | Freigabe? |
|------|--------|-----------|
| Session-Start / Host-Wechsel / „sync“ | `$HOME/git/pull.sh grok llm hernani` | nein (read/ff) |
| Repo fehlt auf Disk | gleiches `pull.sh` (cloned + unlock) | nein |
| Nur Status / Dry-Run | `$HOME/git/pull.sh --list grok llm hernani` bzw. `--dry-run …` | nein |
| Commits hoch | `$HOME/git/push.sh grok llm hernani` (oder `--dry-run`) | **ja** Push-Freigabe |
| Dirty tree committen | `/g` bzw. git-worker — **kein** Push aus Worker | Commit-Freigabe ≠ Push |
`combo` ≡ `llm` (Alias). Nie `$HOME/git/dot-grok-enc` anlegen — Live-SoT ist flat `$HOME/.grok`.
---
## 2. Wenn Git allein nicht reicht
Reines `git pull` / `git clone` reicht oft **nicht**, weil: Profile-DEST, git-crypt, ff-only-Policy, ACCESS_DENIED, retired grok-all.
### A) Clone / Update über Profile (bevorzugt)
```bash
$HOME/git/pull.sh grok llm hernani
# optional:
$HOME/git/pull.sh --dry-run grok llm hernani
$HOME/git/pull.sh --list grok llm hernani # zeigt u.a. ACCESS_DENIED
```
- Existierendes Repo: fetch + **ff-only** pull (kein stilles Merge).
- `--force`: fetch + `reset --hard` auf Remote (tracked überschreiben; untracked bleiben). **Nur mit Absicht / Freigabe**, nie blind auf dirty Work.
- Kein `.git`: init + fetch + reset, dann Unlock.
### B) git-crypt (*-enc und `$HOME/.grok`)
Nach erfolgreichem Git-Stand kann der Tree noch **Ciphertext** sein:
```bash
cd "$DEST" && git-crypt unlock
# oder: git-crypt status -e # noch encrypted?
```
| Symptom | Ursache | Fix |
|---------|---------|-----|
| Dateien sind Blob/binär / `git-crypt status` zeigt encrypted | Key fehlt / nie unlocked | `git-crypt unlock` mit GPG-Key der Collaborators |
| Unlock schlägt fehl, Tree dirty | Unlock überspringt dirty+already-unlocked Policy in pull.sh | erst commit/stash/clean klären, dann unlock |
| Agent liest Müll / leere Secrets | Unlock vergessen | unlock, dann erneut lesen — nicht raten |
| „Permission denied“ SSH ht | Key/ACL | SSH-Agent laden; ACL auf Forgejo — nicht Pfade erfinden |
### C) Push / Divergenz
```bash
$HOME/git/push.sh --dry-run grok llm hernani
$HOME/git/push.sh grok llm hernani # nur mit Freigabe
```
| Farbe/Lage (push.sh) | Bedeutung | Agent |
|----------------------|-----------|-------|
| GREEN | synced / push ok | weiter |
| YELLOW | behind / mergeable | erst `pull.sh` (ff); diverged → Human |
| RED | conflict / diverged hard | **HALT** — kein force ohne Freigabe |
| INFO blue | Repo fehlt auf Disk | `pull.sh` clone |
### D) Explizit verboten / retired
- **grok-all / pack-push / passphrase-Pack** — retired. `magikoopa-unlock-enc.sh unlock` → exit 2.
- ASC-Board (`SYNC-TODO.md.asc`) optional; Sync läuft über Git-Tip + diese SYNC.md.
- `taler`-Profile hier **nicht** mitziehen (außer Human sagt explizit taler).
- Keine Secrets in Klartext-Chat; *enc nur nach unlock lesen.
---
## 3. DEST-Übersicht (dieses Set)
### Profile `grok`
| DEST | Remote (kurz) |
|------|----------------|
| `$HOME/.grok` | `hernani/dot-grok-enc` |
| `$HOME/git/src/_hernani-private/grokd` | `hernani/grokd` |
### Profile `llm` (= `combo`)
Alles unter `$HOME/git/llm/…` laut `profiles/llm.repos` (configs, knowledge-mirror, work-*-enc, input, control-data-enc, work-logs).
### Profile `hernani` (local crossover — **nicht** taler)
| DEST-Bereich | Inhalt |
|--------------|--------|
| `$HOME/git/admin-logs/local/*` | Host admin-logs + `*-secrets-enc` (amanita, clementine, firecuda, koopa, koopatroopa, magikoopa, vecigate, …) + `hernani-common-secrets-enc` |
| `$HOME/git/buerokratie-enc` | Bürokratie *enc |
firefly-Vault-Pfad laut HOSTS: unter shared secrets (`admin-secrets-enc/firefly/` bzw. common) — **nicht** Clem-only Blob; Host-Zeile in `$HOME/git/llm/HOSTS.md`. SSH Host+Key für firefly braucht Freigabe / ACL, nicht nur Sync-Datei.
---
## 4. Dauerbetrieb — Ansätze (llm-controld · grokd · hernanid · …)
Agents halten Tips **laufend**; dafür gibt es (bzw. sollen) Host-Daemons/`ensure`-Hooks geben. **Nicht verwechseln:** Git-Tip-Sync (`pull.sh`) ≠ Controld-Snapshots ≠ Statusline-Keepalive ≠ Combo-Write-Push.
| Name | Rolle | SoT / Bin | Start-Ansatz | Freigabe? |
|------|--------|-----------|--------------|-----------|
| **llm-controld** | Fleet/Letter-Probes → `status.json` (Statusline-Daten) | `$HOME/git/llm/llm-configs/bin/llm-controld` · DATA `llm-control-data-enc` | **Mit Tunnel**, nicht Boot: Tunnel-Skripte → `llm-controld ensure`. Nach Unlock ggf. `llm-control-data-peel.sh` (Doppel-*enc*). Stats: `$HOME/.local/state/llm-controld/` | `ensure` ok; dauerhafte Boot-Units nur mit Freigabe |
| **grokd** | Grok-Statusline keep-alive (`ensure-statusline.sh`) | `$HOME/git/src/_hernani-private/grokd` (Profil `grok`) | `grokd ensure` (auch via `ensure-statusline`). Optional Scheduler: `install-grokd.sh --load` — macOS LaunchAgent `ai.hernani.grokd`; Clementine/Linux user-crontab `* * * * * grokd ensure` | Dateien/`--link-local` ok; **`--load` braucht Freigabe** |
| **hernanid** | **Ansatz / Stub:** laufend Tip für Profil `hernani` (`admin-logs/local/*`, `buerokratie-enc`) | noch kein festes Bin — Muster wie grokd: `hernanid ensure` → `$HOME/git/pull.sh hernani` (+ unlock laut §2B) | Gleiches Host-Muster: magikoopa LaunchAgent `ai.hernani.hernanid`; Clementine crontab `hernanid ensure`. Bis es existiert: Agents/`pull.sh hernani` manuell bzw. Session-Start | Scheduler-Install / `--load` nur mit Freigabe |
| **combo-git-sync** | Combo **Write-Trees** commit+push (OpenPGP+SSH), ≠ Tip-Pull | `$HOME/git/llm/llm-configs/bin/combo-git-sync.py` · LaunchAgent `ai.llm-configs.combo-git-sync-hourly` | `install-combo-git-sync-hourly.sh` (macOS LaunchAgent / Clem crontab stündlich). Quit-on-conflict → `--clear-quit` | Install/Load + jeder Push-Pfad nur mit Freigabe-Policy der Settings |
### Agent-Regeln zu Daemons
1. Vor Arbeit: wenn Controld/Statusline/Grok nötig → `llm-controld ensure` / `grokd ensure` (billig, Singleton/flock).
2. Tip-Sync weiter über `pull.sh grok llm hernani` — Controld ersetzt das **nicht**.
3. Keine neuen LaunchAgents/crontab-Zeilen ohne Freigabe; Soft-Park = Dateien + `ensure` on-demand.
4. Clementine (sysvinit): **kein** systemctl — user crontab wie in den `install-*.sh`.
5. `hernanid` fehlt noch als Binary: nicht erfinden; Ansatz oben dokumentieren / Human+Clem abstimmen; bis dahin Session-`pull.sh`.
---
## 5. Agent-Pflicht (laufend)
1. Vor Arbeit an diesen Bäumen: Tip prüfen (`pull.sh` oder `git status` + behind).
2. Nach lokalen Commits: Human auf Push ansprechen; **kein** eigenmächtiger `git push`.
3. Bei Ciphertext / fehlendem Unlock: SYNC.md §2B befolgen, nicht Inhalt erfinden.
4. Neuer technischer Ordner in diesem Set: SYNC.md + AGENTS-Verweis auf SYNC.md mitziehen.
5. Katalog/Index-Refresh und SSH-Mutationen: nur mit Freigabe.
6. Dauerbetrieb: §4 — `ensure` nutzen; Scheduler nur mit Freigabe; `hernanid` als Ansatz bis Binary da ist.
---
## 6. Verweise
- Profile: `$HOME/git/profiles/{grok,llm,combo,hernani}.repos`
- Session Must: `$HOME/.grok/AGENTS.md` (Freigabe, §7 Git)
- Hosts: `$HOME/git/llm/HOSTS.md`
- grokd docs: `$HOME/git/src/_hernani-private/grokd/docs/README.md`
- llm-controld / peel: host skill magikoopa · `llm-configs/bin/llm-controld` · `llm-control-data-peel.sh`
- Diese Datei: neben `AGENTS.md` in jedem technischen Ordner dieses Sets

View file

@ -9,12 +9,13 @@ Directories are named to match **live podman container names** where possible.
| `taler-exchange/` | conf inside exchange container | (see exchange-ansible) | | `taler-exchange/` | conf inside exchange container | (see exchange-ansible) |
| `taler-exchange-ansible/` | **`taler-hacktivism-exchange-ansible`** | `taler-hacktivism-exchange-ansible:landing` | | `taler-exchange-ansible/` | **`taler-hacktivism-exchange-ansible`** | `taler-hacktivism-exchange-ansible:landing` |
| `bank-landing/` `exchange-landing/` `merchant-landing/` | nginx landing snippets | ports 9013–9015 | | `bank-landing/` `exchange-landing/` `merchant-landing/` | nginx landing snippets | ports 9013–9015 |
| `koopa-*` apps | `koopa-castopod`, `koopa-bonfire`, `koopa-lemmy`, … | compose mirrors | | `koopa-*` apps | `koopa-castopod`, `koopa-bonfire`, `koopa-lemmy`, `koopa-decidim`, … | compose mirrors |
| `tops/` | `koopa-tops-ng1` … `ng3` | `nginxinc/nginx-unprivileged:1.27-alpine` (non-root, :8080) | | `tops/` | `koopa-tops-ng1` … `ng3` | `nginxinc/nginx-unprivileged:1.27-alpine` (non-root, :8080) |
| `caddy/` `firewalld/` `systemd/` | host services | | | `caddy/` `firewalld/` `systemd/` | host services | |
| `tor/` | **`koopa-tor-relay`** (podman host net) | `localhost/koopa-tor-relay:latest` (**non-root** uid 1000) | | `tor/` | **`koopa-tor-relay`** (podman host net) | `localhost/koopa-tor-relay:latest` (**non-root** uid 1000) |
| `nym/` | **`koopa-nym`** (nym.com nym-node) | `localhost/koopa-nym:latest` (**non-root** uid 1000) | | `nym/` | **`koopa-nym`** (nym.com nym-node) | `localhost/koopa-nym:latest` (**non-root** uid 1000) |
| `paivana/` | **`koopa-paivana`** (+ upstream) | `localhost/koopa-paivana:latest` (**non-root**); upstream unprivileged nginx | | `paivana/` | **`koopa-paivana`** + paywalls + upstream | `localhost/koopa-paivana:latest` (**non-root**); public **9025/9028–9030** |
| `notes/` | **`koopa-silverbullet`** (SilverBullet) | `localhost/koopa-silverbullet:cachyos` (backend **127.0.0.1:19128**; paywall **9028**) |
| `forgejo/` | **`koopa-forgejo`** | rootless image + `user: 1000` + `userns keep-id` | | `forgejo/` | **`koopa-forgejo`** | rootless image + `user: 1000` + `userns keep-id` |
| `prime/` | jellyfin / qbittorrent | linuxserver **PUID/PGID=1000** | | `prime/` | jellyfin / qbittorrent | linuxserver **PUID/PGID=1000** |

View file

@ -1118,12 +1118,18 @@
<script src="/intro/qrcode.min.js"></script> <script src="/intro/qrcode.min.js"></script>
</head> </head>
<body data-shop-theme="bank"> <body data-shop-theme="bank">
<p class="stack-bar" role="note" title="Taler software on this bank service (links → git.taler.net tags)"> <!-- stack-bar -->
<p class="stack-bar" role="note" title="Taler software on this bank service (goa-regio-ng vanilla)">
<strong>stack</strong><span class="sep">·</span> <strong>stack</strong><span class="sep">·</span>
<a href="https://git.taler.net/taler/libeufin/commit/ab00480dd9b3be50704fb449b750c764fd4c1de0.html" target="_blank" rel="noopener noreferrer" title="libeufin tag v1.6.6">libeufin-bank&nbsp;1.6.6</a> <a href="https://git.taler.net/taler-deployment.git/tree/?h=dev/hernani/goa-regio-ng-vanilla" target="_blank" rel="noopener noreferrer" title="taler-deployment branch dev/hernani/goa-regio-ng-vanilla">vanilla</a>
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/libeufin/commit/ab00480dd9b3be50704fb449b750c764fd4c1de0.html" target="_blank" rel="noopener noreferrer" title="libeufin tag v1.6.6">libeufin-common&nbsp;1.6.6</a> libeufin-bank&nbsp;1.6.10
<span class="sep">·</span>
libeufin-common&nbsp;1.6.10
<span class="sep">·</span>
libeufin-bank-webui&nbsp;1.6.38
</p> </p>
<!-- /stack-bar -->
<main> <main>
<header class="hero"> <header class="hero">
<span class="badge">Intergalactic · GOA · no IBAN</span> <span class="badge">Intergalactic · GOA · no IBAN</span>
@ -1558,10 +1564,10 @@ tw run-until-done &amp;&amp; tw balance</pre>
<a href="https://bank.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>. <a href="https://bank.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>.
</p> </p>
<!-- landing-rev --> <!-- landing-rev -->
<p class="landing-rev" data-landing-site="bank" data-landing-version="44" data-landing-commit="689ee59"> <p class="landing-rev" data-landing-site="bank" data-landing-version="45" data-landing-commit="0d881cd">
Bank landing <strong>v44</strong> Bank landing <strong>v45</strong>
· content <time datetime="2026-07-17T18:31:49+02:00">2026-07-17 18:31 CEST</time> · content <time datetime="2026-09-16T23:19:33+02:00">2026-09-16 23:19 CEST</time>
· <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/689ee595e08f3880c1e4068aac8e972574e20d21" title="koopa-admin-log 689ee595e08f3880c1e4068aac8e972574e20d21">689ee59</a> · <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/0d881cd726da8d298c98114678253e3cbb7aa5e6" title="koopa-admin-log 0d881cd726da8d298c98114678253e3cbb7aa5e6">0d881cd</a>
</p> </p>
<!-- /landing-rev --> <!-- /landing-rev -->
</footer> </footer>

View file

@ -49,6 +49,16 @@ server {
add_header Cache-Control "no-store" always; add_header Cache-Control "no-store" always;
add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Origin * always;
} }
# FP pattern: GET Integration via demo-api (inject suggested/required_exchange)
# Caddy @wdGet → :9013 → here → :19096; POST/other Integration stays on :9012
location /taler-integration/withdrawal-operation/ {
proxy_pass http://127.0.0.1:19096;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 70s;
add_header Cache-Control "no-store" always;
add_header Access-Control-Allow-Origin * always;
}
location /intro/ { location /intro/ {
alias /var/www/bank-landing/; alias /var/www/bank-landing/;
} }

36
configs/bbb/Containerfile Normal file
View file

@ -0,0 +1,36 @@
# koopa-bbb-front — BigBlueButton front (Ubuntu)
# Exception to CachyOS policy: BBB packages and install scripts target Ubuntu.
# Build: bash ~/koopa-admin-log/scripts/bbb/build.sh → localhost/koopa-bbb-front:ubuntu
#
# Placeholder reverse-proxy target (nginx) until Greenlight and/or BBB core
# (bbb-install on Ubuntu) is chosen. Not production BBB media.
ARG UBUNTU_IMAGE=docker.io/library/ubuntu:24.04
FROM ${UBUNTU_IMAGE}
ENV DEBIAN_FRONTEND=noninteractive \
TZ=Europe/Zurich
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates curl nginx tini \
&& rm -rf /var/lib/apt/lists/*
RUN printf '%s\n' \
'server {' \
' listen 80 default_server;' \
' root /var/www/html;' \
' index index.html;' \
' location = /health { access_log off; default_type text/plain; return 200 "ok\n"; }' \
' location / { try_files $uri $uri/ =404; }' \
'}' > /etc/nginx/sites-available/default \
&& printf '%s\n' \
'<!doctype html><meta charset=utf-8><title>bbb.hacktivism.ch</title>' \
'<p>BBB front stub (Ubuntu 24.04). Full BigBlueButton / Greenlight is a separate Ubuntu install step.</p>' \
> /var/www/html/index.html
COPY entrypoint.sh /docker-entrypoint.sh
RUN chmod 755 /docker-entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/usr/bin/tini", "--", "/docker-entrypoint.sh"]

38
configs/bbb/README.md Normal file
View file

@ -0,0 +1,38 @@
# BBB (BigBlueButton) — Ubuntu container (koopa)
CachyOS exception: BBB packages and `bbb-install` target **Ubuntu**. Front stub image is Ubuntu 24.04.
| Item | Value |
|------|--------|
| Stack | BigBlueButton (front stub → core later) |
| Image | `localhost/koopa-bbb-front:ubuntu` (`FROM docker.io/library/ubuntu:24.04`) |
| Live dir | `/home/hernani/koopa-bbb/` |
| Container | `koopa-bbb-front` |
| Host port | **9032** |
| Public site | `bbb.hacktivism.ch` |
## Phases
1. **Front stub (this tree)** — nginx placeholder on `:9032` so Caddy + DNS can land.
2. **Greenlight (optional)** — Rails UI talking to a real BBB API; still Ubuntu-based images.
3. **BBB core** — FreeSWITCH / mediasoup / akka-apps. Prefer official Ubuntu install (`bbb-install.sh`) on a dedicated Ubuntu host/VM, or a known multi-container BBB compose. Not CachyOS.
Media UDP/TCP and TURN are documented when core is chosen — not in this stub.
## Build + up (koopa)
```bash
bash /path/to/koopa-admin-log/scripts/bbb/build.sh
mkdir -p ~/koopa-bbb && cp -a /path/to/koopa-admin-log/configs/bbb/{compose.yml,Containerfile,entrypoint.sh} ~/koopa-bbb/
cd ~/koopa-bbb && HOST_PORT=9032 podman-compose up -d
```
## Caddy
```bash
sudo bash /path/to/koopa-admin-log/scripts/caddy/caddy-apply.sh \
--snippet /path/to/koopa-admin-log/configs/caddy/bbb.hacktivism.ch.caddy \
--site bbb.hacktivism.ch --port 9032 --label bbb
```
DNS + VeciGate for the hostname after apply Freigabe.

31
configs/bbb/compose.yml Normal file
View file

@ -0,0 +1,31 @@
# koopa-bbb — BigBlueButton front on Ubuntu (exception to CachyOS)
# Live: /home/hernani/koopa-bbb/
# Build: bash ~/koopa-admin-log/scripts/bbb/build.sh → localhost/koopa-bbb-front:ubuntu
#
# HOST_PORT: 9032 → Caddy bbb.hacktivism.ch
# Core BBB / Greenlight: separate follow-up (Ubuntu), not this stub.
services:
bbb-front:
image: localhost/koopa-bbb-front:ubuntu
build:
context: .
dockerfile: Containerfile
container_name: koopa-bbb-front
restart: unless-stopped
environment:
- TZ=Europe/Zurich
ports:
- "${HOST_PORT:-9032}:80"
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
labels:
org.hacktivism.service: bbb
org.hacktivism.host_port: "${HOST_PORT:-9032}"
org.hacktivism.site: bbb.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.port_status: allocated-9032
org.hacktivism.image_base: ubuntu

3
configs/bbb/entrypoint.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
set -euo pipefail
exec nginx -g 'daemon off;'

View file

@ -0,0 +1,27 @@
# koopa BBB Ubuntu VM — lean defaults (host ~15 Gi / 4 cores)
# Override before sourcing: RAM_MIB=4096 VCPUS=2 …
VM_NAME=koopa-bbb
# Official prod=16G; local-dev floor=8G. Koopa lean default=6G + guest swap.
RAM_MIB=6144
VCPUS=2
DISK_GB=50
# Ubuntu 22.04 LTS (bbb-install 3.0). 24.04 only if docs for your branch say so.
OS_VARIANT=ubuntu22.04
CLOUD_IMAGE_URL=https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img
HOSTNAME=bbb.hacktivism.ch
# Bridged LAN (preferred for media DNAT). Set BRIDGE= after host-prep creates br0.
BRIDGE=
# Fallback: libvirt default NAT (media harder; ok for first boot/ssh)
NETWORK_SOURCE=default
# Guest swap (MiB) — important when RAM_MIB < 8192
SWAP_MIB=4096
# SSH pubkey injected via cloud-init (path on koopa host)
SSH_PUBKEY_FILE=/home/hernani/.ssh/id_ed25519.pub
# Disk pool
POOL_DIR=/var/lib/libvirt/images
# bbb-install branch + Greenlight
BBB_INSTALL_BRANCH=v3.0.x-release
BBB_INSTALL_EXTRA=-g
# After VM has IP: Caddy may stay on :9032 stub until cutover, or point at VM:80
CADDY_BACKEND_HINT=VM_HTTP_80_OR_DNAT

View file

@ -1,7 +1,7 @@
# Internal only (not in the browser URL): # Internal only (not in the browser URL):
# 9010 merchant API | 9011 exchange API | 9012 bank API # 9010 merchant API | 9011 exchange API | 9012 bank API
# 9013 bank landing | 9014 exchange landing | 9015 merchant landing # 9013 bank landing | 9014 exchange landing | 9015 merchant landing
# 9020 castopod | 9021 bonfire | 9022 prime | 9023 bt | 9024 forgejo | 9025 paivana | 9026 lemmy | 9027 decidim | 9200 forgejo-ssh # 9020 castopod | 9021 bonfire | 9022 prime | 9023 bt | 9024 forgejo | 9025 paivana | 9026 lemmy | 9027 decidim | 9029 galene | 9030 cryptpad | 9031 meet | 9032 bbb | 9028 silverbullet | 9200 forgejo-ssh
# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3 # 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3
{ {
@ -204,6 +204,19 @@ bank.hacktivism.ch {
} }
} }
# FP pattern (francpaysan-admin-log files/caddy/Caddyfile @wdGet):
# GET withdrawal-operation → landing :9013 → demo-api :19096
# (injects suggested_exchange / required_exchange for Android/iOS)
@wdGet {
method GET
path /taler-integration/withdrawal-operation/*
}
handle @wdGet {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
reverse_proxy 127.0.0.1:9012 { reverse_proxy 127.0.0.1:9012 {
import proxy_public import proxy_public
} }
@ -332,7 +345,101 @@ decidim.hacktivism.ch {
} }
} }
http://taler.hacktivism.ch, http://exchange.hacktivism.ch, http://bank.hacktivism.ch, http://castopod.hacktivism.ch, http://bonfire.hacktivism.ch, http://prime.hacktivism.ch, http://bt.hacktivism.ch, http://git.hacktivism.ch, http://paivana.hacktivism.ch, http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch, http://lemmy.hacktivism.ch, http://decidim.hacktivism.ch { # 9028 silverbullet / SilverBullet — allocated 2026-09-08
# Merge into /etc/caddy/Caddyfile (sudo).
# Also add http://silverbullet.hacktivism.ch to the shared ACME/redirect list.
silverbullet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9028 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9029 galene — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site galene.hacktivism.ch --port 9029 --label galene
galene.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9029 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9030 cryptpad — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site cryptpad.hacktivism.ch --port 9030 --label cryptpad
# CryptPad also needs sandbox subdomain (cryptpad-ui / sandbox) — wire after first boot.
cryptpad.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9030 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9031 meet (Jitsi) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site meet.hacktivism.ch --port 9031 --label meet
# WebRTC media (UDP/JVB) is separate from this HTTPS vhost — VeciGate/firewall later.
meet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9031 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9032 bbb (BigBlueButton) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site bbb.hacktivism.ch --port 9032 --label bbb
# Stack image base: Ubuntu (not CachyOS). Media/UDP ports TBD with install.
bbb.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9032 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
http://taler.hacktivism.ch, http://exchange.hacktivism.ch, http://bank.hacktivism.ch, http://castopod.hacktivism.ch, http://bonfire.hacktivism.ch, http://prime.hacktivism.ch, http://bt.hacktivism.ch, http://git.hacktivism.ch, http://paivana.hacktivism.ch, http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch, http://lemmy.hacktivism.ch, http://decidim.hacktivism.ch, http://galene.hacktivism.ch, http://cryptpad.hacktivism.ch, http://meet.hacktivism.ch, http://bbb.hacktivism.ch {
handle /.well-known/acme-challenge/* { handle /.well-known/acme-challenge/* {
root * /var/www/acme root * /var/www/acme
file_server file_server

View file

@ -0,0 +1,343 @@
# Internal only (not in the browser URL):
# 9010 merchant API | 9011 exchange API | 9012 bank API
# 9013 bank landing | 9014 exchange landing | 9015 merchant landing
# 9020 castopod | 9021 bonfire | 9022 prime | 9023 bt | 9024 forgejo | 9025 paivana | 9026 lemmy | 9027 decidim | 9200 forgejo-ssh
# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3
{
email info+koopa@hacktivism.ch
http_port 9000
https_port 9001
auto_https disable_redirects
# Caddy listens on 9001 behind VeciGate/https-proxy :443.
# Default HTTP/3 would send Alt-Svc: h3=":9001" — break public HTTPS on :443.
servers {
protocols h1 h2
}
}
(proxy_public) {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
header_down Location "^https?://[^/]+:90[0-9]{2}(.*)$" "https://{host}$1"
}
taler.hacktivism.ch {
tls /etc/caddy/certs/taler.hacktivism.ch/fullchain.pem /etc/caddy/certs/taler.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9015 {
import proxy_public
}
}
# surface + aptdeploy HTML (taler.hacktivism.ch only)
handle /taler-monitoring-surface_err {
redir /taler-monitoring-surface_err/ 302
}
handle /taler-monitoring-surface_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-surface {
redir /taler-monitoring-surface/ 302
}
handle /taler-monitoring-surface* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy_err {
redir /taler-monitoring-aptdeploy_err/ 302
}
handle /taler-monitoring-aptdeploy_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy {
redir /taler-monitoring-aptdeploy/ 302
}
handle /taler-monitoring-aptdeploy* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost_err {
redir /taler-monitoring-mattermost_err/ 302
}
handle /taler-monitoring-mattermost_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost {
redir /taler-monitoring-mattermost/ 302
}
handle /taler-monitoring-mattermost* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail_err {
redir /taler-monitoring-mail_err/ 302
}
handle /taler-monitoring-mail_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail {
redir /taler-monitoring-mail/ 302
}
handle /taler-monitoring-mail* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# SPA: /webui → /webui/
redir /webui /webui/ 302
# Merchant API + WebUI (nginx :9010 → unix socket)
reverse_proxy https://127.0.0.1:9010 {
transport http {
tls_insecure_skip_verify
}
import proxy_public
}
}
exchange.hacktivism.ch {
tls /etc/caddy/certs/exchange.hacktivism.ch/fullchain.pem /etc/caddy/certs/exchange.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9014 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
reverse_proxy 127.0.0.1:9011 {
import proxy_public
}
}
bank.hacktivism.ch {
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
# Static terms/privacy on landing nginx :9013
handle /terms* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
handle /privacy* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
reverse_proxy 127.0.0.1:9012 {
import proxy_public
}
}
castopod.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9020 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
bonfire.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9021 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
prime.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9022 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
bt.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9023 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
# 9024 forgejo HTTP (SSH :9200 host-direct, not via Caddy)
git.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9024 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# Taler Operations design previews (static nginx)
tops.ng1.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9090 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng2.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9091 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng3.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9092 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# 9025 paivana-httpd (GOA paywall)
paivana.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9025 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
}
}
# 9026 lemmy (+ ui/pictrs via internal nginx)
lemmy.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9026 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9027 decidim (rails)
decidim.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9027 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
http://taler.hacktivism.ch, http://exchange.hacktivism.ch, http://bank.hacktivism.ch, http://castopod.hacktivism.ch, http://bonfire.hacktivism.ch, http://prime.hacktivism.ch, http://bt.hacktivism.ch, http://git.hacktivism.ch, http://paivana.hacktivism.ch, http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch, http://lemmy.hacktivism.ch, http://decidim.hacktivism.ch {
handle /.well-known/acme-challenge/* {
root * /var/www/acme
file_server
}
handle {
redir https://{host}{uri} permanent
}
}

View file

@ -0,0 +1,399 @@
# Internal only (not in the browser URL):
# 9010 merchant API | 9011 exchange API | 9012 bank API
# 9013 bank landing | 9014 exchange landing | 9015 merchant landing
# 9020 castopod | 9021 bonfire | 9022 prime | 9023 bt | 9024 forgejo | 9025 paivana | 9026 lemmy | 9027 decidim | 9029 galene | 9030 cryptpad | 9031 meet | 9200 forgejo-ssh
# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3
{
email info+koopa@hacktivism.ch
http_port 9000
https_port 9001
auto_https disable_redirects
# Caddy listens on 9001 behind VeciGate/https-proxy :443.
# Default HTTP/3 would send Alt-Svc: h3=":9001" — break public HTTPS on :443.
servers {
protocols h1 h2
}
}
(proxy_public) {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
header_down Location "^https?://[^/]+:90[0-9]{2}(.*)$" "https://{host}$1"
}
taler.hacktivism.ch {
tls /etc/caddy/certs/taler.hacktivism.ch/fullchain.pem /etc/caddy/certs/taler.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9015 {
import proxy_public
}
}
# surface + aptdeploy HTML (taler.hacktivism.ch only)
handle /taler-monitoring-surface_err {
redir /taler-monitoring-surface_err/ 302
}
handle /taler-monitoring-surface_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-surface {
redir /taler-monitoring-surface/ 302
}
handle /taler-monitoring-surface* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy_err {
redir /taler-monitoring-aptdeploy_err/ 302
}
handle /taler-monitoring-aptdeploy_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy {
redir /taler-monitoring-aptdeploy/ 302
}
handle /taler-monitoring-aptdeploy* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost_err {
redir /taler-monitoring-mattermost_err/ 302
}
handle /taler-monitoring-mattermost_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost {
redir /taler-monitoring-mattermost/ 302
}
handle /taler-monitoring-mattermost* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail_err {
redir /taler-monitoring-mail_err/ 302
}
handle /taler-monitoring-mail_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail {
redir /taler-monitoring-mail/ 302
}
handle /taler-monitoring-mail* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# SPA: /webui → /webui/
redir /webui /webui/ 302
# Merchant API + WebUI (nginx :9010 → unix socket)
reverse_proxy https://127.0.0.1:9010 {
transport http {
tls_insecure_skip_verify
}
import proxy_public
}
}
exchange.hacktivism.ch {
tls /etc/caddy/certs/exchange.hacktivism.ch/fullchain.pem /etc/caddy/certs/exchange.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9014 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
reverse_proxy 127.0.0.1:9011 {
import proxy_public
}
}
bank.hacktivism.ch {
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
# Static terms/privacy on landing nginx :9013
handle /terms* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
handle /privacy* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
reverse_proxy 127.0.0.1:9012 {
import proxy_public
}
}
castopod.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9020 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
bonfire.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9021 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
prime.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9022 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
bt.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9023 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
# 9024 forgejo HTTP (SSH :9200 host-direct, not via Caddy)
git.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9024 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# Taler Operations design previews (static nginx)
tops.ng1.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9090 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng2.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9091 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng3.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9092 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# 9025 paivana-httpd (GOA paywall)
paivana.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9025 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
}
}
# 9026 lemmy (+ ui/pictrs via internal nginx)
lemmy.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9026 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9027 decidim (rails)
decidim.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9027 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9029 galene — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site galene.hacktivism.ch --port 9029 --label galene
galene.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9029 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9030 cryptpad — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site cryptpad.hacktivism.ch --port 9030 --label cryptpad
# CryptPad also needs sandbox subdomain (cryptpad-ui / sandbox) — wire after first boot.
cryptpad.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9030 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9031 meet (Jitsi) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site meet.hacktivism.ch --port 9031 --label meet
# WebRTC media (UDP/JVB) is separate from this HTTPS vhost — VeciGate/firewall later.
meet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9031 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
http://taler.hacktivism.ch, http://exchange.hacktivism.ch, http://bank.hacktivism.ch, http://castopod.hacktivism.ch, http://bonfire.hacktivism.ch, http://prime.hacktivism.ch, http://bt.hacktivism.ch, http://git.hacktivism.ch, http://paivana.hacktivism.ch, http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch, http://lemmy.hacktivism.ch, http://decidim.hacktivism.ch, http://galene.hacktivism.ch, http://cryptpad.hacktivism.ch, http://meet.hacktivism.ch {
handle /.well-known/acme-challenge/* {
root * /var/www/acme
file_server
}
handle {
redir https://{host}{uri} permanent
}
}

View file

@ -0,0 +1,418 @@
# Internal only (not in the browser URL):
# 9010 merchant API | 9011 exchange API | 9012 bank API
# 9013 bank landing | 9014 exchange landing | 9015 merchant landing
# 9020 castopod | 9021 bonfire | 9022 prime | 9023 bt | 9024 forgejo | 9025 paivana | 9026 lemmy | 9027 decidim | 9029 galene | 9030 cryptpad | 9031 meet | 9032 bbb | 9200 forgejo-ssh
# 9090 tops ng1 | 9091 tops ng2 | 9092 tops ng3
{
email info+koopa@hacktivism.ch
http_port 9000
https_port 9001
auto_https disable_redirects
# Caddy listens on 9001 behind VeciGate/https-proxy :443.
# Default HTTP/3 would send Alt-Svc: h3=":9001" — break public HTTPS on :443.
servers {
protocols h1 h2
}
}
(proxy_public) {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
header_down Location "^https?://[^/]+:90[0-9]{2}(.*)$" "https://{host}$1"
}
taler.hacktivism.ch {
tls /etc/caddy/certs/taler.hacktivism.ch/fullchain.pem /etc/caddy/certs/taler.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9015 {
import proxy_public
}
}
# surface + aptdeploy HTML (taler.hacktivism.ch only)
handle /taler-monitoring-surface_err {
redir /taler-monitoring-surface_err/ 302
}
handle /taler-monitoring-surface_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-surface {
redir /taler-monitoring-surface/ 302
}
handle /taler-monitoring-surface* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy_err {
redir /taler-monitoring-aptdeploy_err/ 302
}
handle /taler-monitoring-aptdeploy_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-aptdeploy {
redir /taler-monitoring-aptdeploy/ 302
}
handle /taler-monitoring-aptdeploy* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost_err {
redir /taler-monitoring-mattermost_err/ 302
}
handle /taler-monitoring-mattermost_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mattermost {
redir /taler-monitoring-mattermost/ 302
}
handle /taler-monitoring-mattermost* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail_err {
redir /taler-monitoring-mail_err/ 302
}
handle /taler-monitoring-mail_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /taler-monitoring-mail {
redir /taler-monitoring-mail/ 302
}
handle /taler-monitoring-mail* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/taler.hacktivism.ch
file_server
}
# SPA: /webui → /webui/
redir /webui /webui/ 302
# Merchant API + WebUI (nginx :9010 → unix socket)
reverse_proxy https://127.0.0.1:9010 {
transport http {
tls_insecure_skip_verify
}
import proxy_public
}
}
exchange.hacktivism.ch {
tls /etc/caddy/certs/exchange.hacktivism.ch/fullchain.pem /etc/caddy/certs/exchange.hacktivism.ch/privkey.pem
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9014 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/exchange.hacktivism.ch
file_server
}
reverse_proxy 127.0.0.1:9011 {
import proxy_public
}
}
bank.hacktivism.ch {
header Alt-Svc "clear"
# Public landing first
redir / /intro/ 302
handle /intro* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
# taler-monitoring console HTML (host static — not in app containers)
handle /monitoring_err {
redir /monitoring_err/ 302
}
handle /monitoring_err* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
handle /monitoring {
redir /monitoring/ 302
}
handle /monitoring* {
root * /var/www/monitoring-sites/bank.hacktivism.ch
file_server
}
# Static terms/privacy on landing nginx :9013
handle /terms* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
handle /privacy* {
reverse_proxy 127.0.0.1:9013 {
import proxy_public
}
}
reverse_proxy 127.0.0.1:9012 {
import proxy_public
}
}
castopod.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9020 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
bonfire.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9021 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
prime.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9022 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
flush_interval -1
}
}
bt.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9023 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
}
}
# 9024 forgejo HTTP (SSH :9200 host-direct, not via Caddy)
git.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9024 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# Taler Operations design previews (static nginx)
tops.ng1.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9090 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng2.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9091 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
tops.ng3.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9092 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# 9025 paivana-httpd (GOA paywall)
paivana.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9025 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
}
}
# 9026 lemmy (+ ui/pictrs via internal nginx)
lemmy.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9026 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9027 decidim (rails)
decidim.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9027 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9029 galene — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site galene.hacktivism.ch --port 9029 --label galene
galene.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9029 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9030 cryptpad — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site cryptpad.hacktivism.ch --port 9030 --label cryptpad
# CryptPad also needs sandbox subdomain (cryptpad-ui / sandbox) — wire after first boot.
cryptpad.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9030 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9031 meet (Jitsi) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site meet.hacktivism.ch --port 9031 --label meet
# WebRTC media (UDP/JVB) is separate from this HTTPS vhost — VeciGate/firewall later.
meet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9031 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
# 9032 bbb (BigBlueButton) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site bbb.hacktivism.ch --port 9032 --label bbb
# Stack image base: Ubuntu (not CachyOS). Media/UDP ports TBD with install.
bbb.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9032 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}
http://taler.hacktivism.ch, http://exchange.hacktivism.ch, http://bank.hacktivism.ch, http://castopod.hacktivism.ch, http://bonfire.hacktivism.ch, http://prime.hacktivism.ch, http://bt.hacktivism.ch, http://git.hacktivism.ch, http://paivana.hacktivism.ch, http://tops.ng1.hacktivism.ch, http://tops.ng2.hacktivism.ch, http://tops.ng3.hacktivism.ch, http://lemmy.hacktivism.ch, http://decidim.hacktivism.ch, http://galene.hacktivism.ch, http://cryptpad.hacktivism.ch, http://meet.hacktivism.ch, http://bbb.hacktivism.ch {
handle /.well-known/acme-challenge/* {
root * /var/www/acme
file_server
}
handle {
redir https://{host}{uri} permanent
}
}

View file

@ -4,6 +4,7 @@
|------|------| |------|------|
| **`Caddyfile`** | Multi-vhost config mirror (`/etc/caddy/Caddyfile` on host) | | **`Caddyfile`** | Multi-vhost config mirror (`/etc/caddy/Caddyfile` on host) |
| `git.hacktivism.ch.caddy` | Site-block snippet for Forgejo | | `git.hacktivism.ch.caddy` | Site-block snippet for Forgejo |
| `silverbullet.hacktivism.ch.caddy` | Site-block snippet for SilverBullet |
| `Caddyfile.taler-host` | **Legacy** Taler-only sketch — do not deploy | | `Caddyfile.taler-host` | **Legacy** Taler-only sketch — do not deploy |
Also: `host/caddy/Caddyfile` (same as `Caddyfile` here). Also: `host/caddy/Caddyfile` (same as `Caddyfile` here).

View file

@ -0,0 +1,18 @@
# 9032 bbb (BigBlueButton) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site bbb.hacktivism.ch --port 9032 --label bbb
# Stack image base: Ubuntu (not CachyOS). Media/UDP ports TBD with install.
bbb.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9032 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,18 @@
# 9030 cryptpad — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site cryptpad.hacktivism.ch --port 9030 --label cryptpad
# Backend is koopa-cryptpad-edge (HTTP+WS). Sandbox subdomain (cryptpad-ui) — wire after first boot.
cryptpad.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9030 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,17 @@
# 9027 decidim (rails)
# Live: merged into /etc/caddy/Caddyfile
decidim.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9027 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,17 @@
# 9029 galene — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site galene.hacktivism.ch --port 9029 --label galene
galene.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9029 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,18 @@
# 9031 meet (Jitsi) — allocated 2026-09-08
# Merge: scripts/caddy/caddy-apply.sh --site meet.hacktivism.ch --port 9031 --label meet
# WebRTC media (UDP/JVB) is separate from this HTTPS vhost — VeciGate/firewall later.
meet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9031 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,18 @@
# 9028 silverbullet / SilverBullet — allocated 2026-09-08
# Merge into /etc/caddy/Caddyfile (sudo).
# Also add http://silverbullet.hacktivism.ch to the shared ACME/redirect list.
silverbullet.hacktivism.ch {
header Alt-Svc "clear"
reverse_proxy 127.0.0.1:9028 {
header_up Host {host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-Port 443
flush_interval -1
transport http {
read_timeout 3600s
write_timeout 3600s
}
}
}

View file

@ -0,0 +1,47 @@
# koopa-cryptpad — CryptPad on CachyOS base + Node from pacman
# Build on koopa (x86_64):
# bash ~/koopa-admin-log/scripts/cryptpad/build.sh
# → localhost/koopa-cryptpad:cachyos
#
# App tree from upstream release tarball (not the official Debian-ish image).
ARG CACHYOS_IMAGE=docker.io/cachyos/cachyos:latest
FROM ${CACHYOS_IMAGE}
ARG CRYPTPAD_VERSION=2025.9.0
ARG CRYPTPAD_URL=https://github.com/cryptpad/cryptpad/archive/refs/tags/${CRYPTPAD_VERSION}.tar.gz
ENV TZ=Europe/Zurich \
PATH=/usr/local/bin:$PATH \
CRYPTPAD_HOME=/cryptpad
RUN pacman -Syu --noconfirm --needed \
bash curl ca-certificates catatonit tar git \
nodejs npm \
&& pacman -Scc --noconfirm \
&& rm -rf /var/cache/pacman/pkg/* /tmp/*
# npm may block git deps (EALLOWGIT); rewrite git+ssh → https and allow git installs.
RUN curl -fsSL "$CRYPTPAD_URL" -o /tmp/cryptpad.tgz \
&& mkdir -p /cryptpad \
&& tar -xzf /tmp/cryptpad.tgz -C /cryptpad --strip-components=1 \
&& rm -f /tmp/cryptpad.tgz \
&& cd /cryptpad \
&& git config --global url."https://github.com/".insteadOf "ssh://git@github.com/" \
&& git config --global url."https://github.com/".insteadOf "git@github.com:" \
&& git config --global url."https://".insteadOf "git://" \
&& printf 'allow-git=all\nallow-remote=all\n' > /root/.npmrc \
&& (npm ci --omit=dev --allow-git=all --allow-remote=all \
|| npm install --omit=dev --allow-git=all --allow-remote=all) \
&& (npm run install:components || true) \
&& rm -rf /root/.npm /tmp/* /var/cache/pacman/pkg/*
COPY entrypoint.sh /docker-entrypoint.sh
RUN mkdir -p /cryptpad/config /cryptpad/data /cryptpad/datastore /cryptpad/block /cryptpad/blob \
/cryptpad/blobstage /cryptpad/data/logs
COPY config.example.js /cryptpad/config/config.js
RUN chmod 755 /docker-entrypoint.sh
EXPOSE 3000
WORKDIR /cryptpad
ENTRYPOINT ["/usr/bin/catatonit", "--", "/docker-entrypoint.sh"]

View file

@ -0,0 +1,32 @@
# CryptPad — on CachyOS (koopa)
| Item | Value |
|------|--------|
| Stack | [CryptPad](https://cryptpad.org/) |
| Image | `localhost/koopa-cryptpad:cachyos` |
| Live dir | `/home/hernani/koopa-cryptpad/` |
| Host port | **9030** = Paivana paywall; nginx edge backend **172.17.0.1:19130** → app (pasta host IP; Paivana DEST) |
| App ports (internal) | **3000** HTTP, **3003** websocket |
| Public site | `cryptpad.hacktivism.ch` |
`websocketPort` must differ from `httpPort` (upstream default 3003). Compose runs `koopa-cryptpad-edge` (nginx) so Caddy still only targets **9030**.
Upstream wants a separate **safe/sandbox** origin for some builds — add a second vhost after first boot if the admin UI requires it.
## Build + up
```bash
bash /path/to/koopa-admin-log/scripts/cryptpad/build.sh
mkdir -p ~/koopa-cryptpad
cp -a /path/to/koopa-admin-log/configs/cryptpad/{compose.yml,config.example.js} ~/koopa-cryptpad/
cp ~/koopa-cryptpad/config.example.js ~/koopa-cryptpad/config.js
# edit httpUnsafeOrigin / httpSafeOrigin in config.js
cd ~/koopa-cryptpad && podman-compose up -d
```
## Caddy
```bash
sudo bash /path/to/koopa-admin-log/scripts/caddy/caddy-apply.sh \
--snippet …/configs/caddy/cryptpad.hacktivism.ch.caddy \
--site cryptpad.hacktivism.ch --port 9030 --label cryptpad
```

View file

@ -0,0 +1,53 @@
# koopa-cryptpad — CryptPad on CachyOS + nginx edge (HTTP+WS on :9030)
# Live: /home/hernani/koopa-cryptpad/
# Build: bash ~/koopa-admin-log/scripts/cryptpad/build.sh → localhost/koopa-cryptpad:cachyos
#
# Public :9030 = koopa-paivana-cryptpad (shared paivana image).
# Edge on pasta host IP — Paivana DEST → 172.17.0.1:19130 (not LAN 0.0.0.0)
# App listens 3000 (http) + 3003 (websocket) inside the net.
services:
cryptpad:
image: localhost/koopa-cryptpad:cachyos
build:
context: .
dockerfile: Containerfile
args:
CRYPTPAD_VERSION: "${CRYPTPAD_VERSION:-2025.9.0}"
container_name: koopa-cryptpad
restart: unless-stopped
environment:
- TZ=Europe/Zurich
volumes:
- ./data:/cryptpad/data
- ./datastore:/cryptpad/datastore
- ./block:/cryptpad/block
- ./blob:/cryptpad/blob
- ./config.js:/cryptpad/config/config.js:ro
expose:
- "3000"
- "3003"
labels:
org.hacktivism.service: cryptpad
org.hacktivism.host_port: "9030"
org.hacktivism.backend_port: "${BACKEND_PORT:-19130}"
org.hacktivism.site: cryptpad.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.port_status: backend-19130-paywall-9030
org.hacktivism.image_base: cachyos
edge:
image: docker.io/library/nginx:alpine
container_name: koopa-cryptpad-edge
restart: unless-stopped
depends_on:
- cryptpad
volumes:
- ./edge.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "172.17.0.1:${BACKEND_PORT:-19130}:80"
labels:
org.hacktivism.service: cryptpad-edge
org.hacktivism.host_port: "9030"
org.hacktivism.backend_port: "${BACKEND_PORT:-19130}"
org.hacktivism.site: cryptpad.hacktivism.ch
org.hacktivism.managed_by: koopa-admin

View file

@ -0,0 +1,13 @@
/* CryptPad config — http on 3000, websockets on 3003 (must differ).
* Live: mount ./config.js over /cryptpad/config/config.js
* Edge nginx in compose merges both onto host :9030 (Caddy unchanged).
*/
module.exports = {
httpUnsafeOrigin: 'https://cryptpad.hacktivism.ch',
httpSafeOrigin: 'https://cryptpad.hacktivism.ch',
httpAddress: '0.0.0.0',
httpPort: 3000,
websocketPort: 3003,
logToStdout: true,
maxWorkers: 2,
};

View file

@ -0,0 +1,37 @@
# Front for koopa-cryptpad: HTTP :3000 + /cryptpad_websocket → :3003
upstream cryptpad_http {
server cryptpad:3000;
}
upstream cryptpad_ws {
server cryptpad:3003;
}
server {
listen 80 default_server;
server_name _;
client_max_body_size 150m;
location /cryptpad_websocket {
proxy_pass http://cryptpad_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
location / {
proxy_pass http://cryptpad_http;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}

5
configs/cryptpad/entrypoint.sh Executable file
View file

@ -0,0 +1,5 @@
#!/bin/bash
set -euo pipefail
cd /cryptpad
# Expect config.js already present (compose mounts or image default).
exec node server.js "$@"

View file

@ -11,7 +11,3 @@ SMTP_USERNAME=unused
SMTP_PASSWORD=unused SMTP_PASSWORD=unused
SMTP_PORT=25 SMTP_PORT=25
QUEUE_ADAPTER=sidekiq QUEUE_ADAPTER=sidekiq
DECIDIM_ISOC_EMAIL=isoc@hacktivism.ch
DECIDIM_ISOC_PASSWORD=@inline-secret@
DECIDIM_ISOC_NAME=isoc
DECIDIM_ISOC_NICKNAME=isoc

View file

@ -10,19 +10,14 @@
Secrets: host `~/koopa-decidim/{.env,users.env}` (mode 600). Not in this repo. Secrets: host `~/koopa-decidim/{.env,users.env}` (mode 600). Not in this repo.
Theme: `theme/hacktivism.css` + `theme/hacktivism.rb` (same exchange-dark palette as Lemmy/Bonfire). Analog stack: `configs/lemmy/`. Theme: `theme/hacktivism.css` + `theme/hacktivism.rb` (same exchange-dark palette as Bonfire/Castopod). Analog stack: `configs/castopod/`.
Privacy: no third-party trackers. Stock GDPR banner is hidden (`#dc-dialog-wrapper`); `theme/hacktivism-consent.js` sets essential-only `decidim-consent`.
```bash ```bash
cd ~/koopa-decidim && set -a && source .env && set +a && podman-compose up -d cd ~/koopa-decidim && set -a && source .env && set +a && podman-compose up -d
scripts/decidim/install-systemd.sh ~/koopa-decidim/bin/install-systemd.sh
scripts/decidim/apply-branding.sh ~/koopa-decidim/bin/apply-branding.sh
scripts/decidim/seed-example.sh # public process /processes/example + optional isoc user
``` ```
Public example (no account): `https://decidim.hacktivism.ch/processes/example` Caddy: `sudo /home/hernani/koopa-caddy/apply.sh` (vhost `decidim.hacktivism.ch` → `127.0.0.1:9027`).
Caddy: `sudo /home/hernani/koopa-caddy/apply.sh` This tree documents **this** instance only. Secrets stay in `koopa-admin-secrets` / host `~/koopa-decidim/{.env,users.env}`.
Daylog: `2026/2026-08-17--decidim.md`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Apply hacktivism colors + header CSS on the live organization.
set -euo pipefail
cd "${HOME}/koopa-decidim"
set -a
# shellcheck disable=SC1091
source .env
# shellcheck disable=SC1091
source users.env
set +a
podman exec \
-e DECIDIM_HOST="${DECIDIM_HOST:-decidim.hacktivism.ch}" \
-e DECIDIM_SYSTEM_EMAIL \
-e DECIDIM_SYSTEM_PASSWORD \
-e DECIDIM_ADMIN_EMAIL \
-e DECIDIM_ADMIN_PASSWORD \
-e DECIDIM_ADMIN_NAME \
-e DECIDIM_APPLICATION_NAME \
-e DECIDIM_DEFAULT_LOCALE \
-e DECIDIM_AVAILABLE_LOCALES \
koopa-decidim bundle exec rails runner /code/lib/koopa_bootstrap.rb
echo "branding applied. public: https://decidim.hacktivism.ch/"

View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Install Decidim user systemd units on koopa (boot via linger).
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
LIVE="${HOME}/koopa-decidim"
# admin-log tree (scripts/decidim → ../..) or live ~/koopa-decidim/bin
if [ -f "${HERE}/../../configs/decidim/container-koopa-decidim.service" ]; then
UNIT_SRC="${HERE}/../../configs/decidim"
elif [ -f "${LIVE}/container-koopa-decidim.service" ]; then
UNIT_SRC="${LIVE}"
else
echo "ERROR: decidim unit files not found" >&2
exit 1
fi
UNIT_DIR="${HOME}/.config/systemd/user"
mkdir -p "${UNIT_DIR}"
cp "${UNIT_SRC}/container-koopa-decidim-db.service" "${UNIT_DIR}/"
cp "${UNIT_SRC}/container-koopa-decidim.service" "${UNIT_DIR}/"
systemctl --user daemon-reload
systemctl --user enable \
container-koopa-decidim-db.service \
container-koopa-decidim.service
if ! podman ps --format '{{.Names}}' | grep -qx koopa-decidim; then
(cd "${HOME}/koopa-decidim" && set -a && source .env && set +a && podman-compose up -d)
fi
systemctl --user start \
container-koopa-decidim-db.service \
container-koopa-decidim.service
systemctl --user --no-pager --lines=0 status \
container-koopa-decidim-db.service \
container-koopa-decidim.service || true
echo "OK. Public: https://decidim.hacktivism.ch/"

View file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Publish public example process/meeting + optional isoc user from users.env.
set -euo pipefail
cd "${HOME}/koopa-decidim"
set -a
# shellcheck disable=SC1091
source .env
# shellcheck disable=SC1091
source users.env
set +a
src=""
if [ -f "${HOME}/src/koopa/koopa-admin-log/configs/decidim/seed_example.rb" ]; then
src="${HOME}/src/koopa/koopa-admin-log/configs/decidim/seed_example.rb"
elif [ -f ./seed_example.rb ]; then
src="./seed_example.rb"
else
echo "ERROR: seed_example.rb not found" >&2
exit 1
fi
podman cp "${src}" koopa-decidim:/code/lib/koopa_seed_example.rb
avatar_host="${DECIDIM_ISOC_AVATAR:-${HOME}/koopa-decidim/assets/img/isoc-gold.png}"
avatar_ctr=""
if [ -f "${avatar_host}" ]; then
avatar_ctr="/tmp/isoc-gold.png"
podman cp "${avatar_host}" "koopa-decidim:${avatar_ctr}"
fi
podman exec \
-e DECIDIM_HOST="${DECIDIM_HOST:-decidim.hacktivism.ch}" \
-e DECIDIM_ADMIN_EMAIL \
-e DECIDIM_ISOC_EMAIL \
-e DECIDIM_ISOC_PASSWORD \
-e DECIDIM_ISOC_NAME \
-e DECIDIM_ISOC_NICKNAME \
-e DECIDIM_ISOC_AVATAR="${avatar_ctr}" \
koopa-decidim bundle exec rails runner /code/lib/koopa_seed_example.rb
echo "seed done. public: https://decidim.hacktivism.ch/processes/example"

21
configs/decidim/bin/up.sh Executable file
View file

@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="${HOME}/koopa-decidim"
cd "${DIR}"
set -a
# shellcheck disable=SC1091
source .env
set +a
podman-compose up -d
echo "== wait for :9027 =="
ok=0
for i in $(seq 1 80); do
code=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 5 "http://127.0.0.1:9027/" || true)
echo "try $i: $code"
case "$code" in
2*|3*) ok=1; break ;;
esac
sleep 5
done
[[ "$ok" -eq 1 ]] || { echo "ERROR: no answer on 9027"; podman-compose ps; exit 1; }
echo "local ok. public: https://decidim.hacktivism.ch/"

View file

@ -42,9 +42,7 @@ services:
- ./entrypoint.sh:/usr/local/bin/koopa-decidim-entrypoint.sh:ro - ./entrypoint.sh:/usr/local/bin/koopa-decidim-entrypoint.sh:ro
- ./theme/hacktivism.rb:/code/config/initializers/hacktivism.rb:ro - ./theme/hacktivism.rb:/code/config/initializers/hacktivism.rb:ro
- ./theme/hacktivism.css:/code/public/hacktivism.css:ro - ./theme/hacktivism.css:/code/public/hacktivism.css:ro
- ./theme/hacktivism-consent.js:/code/public/hacktivism-consent.js:ro
- ./bootstrap.rb:/code/lib/koopa_bootstrap.rb:ro - ./bootstrap.rb:/code/lib/koopa_bootstrap.rb:ro
- ./seed_example.rb:/code/lib/koopa_seed_example.rb:ro
- ./assets/img/logo.svg:/code/public/hacktivism-logo.svg:ro - ./assets/img/logo.svg:/code/public/hacktivism-logo.svg:ro
- ./assets/img/favicon.svg:/code/public/hacktivism-favicon.svg:ro - ./assets/img/favicon.svg:/code/public/hacktivism-favicon.svg:ro
- decidim-storage:/code/storage - decidim-storage:/code/storage

View file

@ -289,18 +289,22 @@
</style> </style>
</head> </head>
<body> <body>
<p class="stack-bar" role="note" title="Taler software on this exchange service (links → git.taler.net tags)"> <!-- stack-bar -->
<p class="stack-bar" role="note" title="Taler software on this exchange service (goa-regio-ng vanilla)">
<strong>stack</strong><span class="sep">·</span> <strong>stack</strong><span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/6dbfa41e3fc6657eff28d11166d24301cdfa93ff.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.6">taler-exchange&nbsp;1.6.6</a> <a href="https://git.taler.net/taler-deployment.git/tree/?h=dev/hernani/goa-regio-ng-vanilla" target="_blank" rel="noopener noreferrer" title="taler-deployment branch dev/hernani/goa-regio-ng-vanilla">vanilla</a>
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/6dbfa41e3fc6657eff28d11166d24301cdfa93ff.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.6">libtalerexchange&nbsp;1.6.6</a> taler-exchange&nbsp;1.6.15
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/6dbfa41e3fc6657eff28d11166d24301cdfa93ff.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.6">taler-exchange-database&nbsp;1.6.6</a> libtalerexchange&nbsp;1.6.15
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/6dbfa41e3fc6657eff28d11166d24301cdfa93ff.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.6">taler-exchange-offline&nbsp;1.6.6</a> taler-exchange-database&nbsp;1.6.15
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/6dbfa41e3fc6657eff28d11166d24301cdfa93ff.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.6">taler-terms-generator&nbsp;1.6.6</a> taler-exchange-offline&nbsp;1.6.15
<span class="sep">·</span>
taler-terms-generator&nbsp;1.6.15
</p> </p>
<!-- /stack-bar -->
<main> <main>
<header class="hero"> <header class="hero">
<span class="badge">GOA · Exchange</span> <span class="badge">GOA · Exchange</span>
@ -500,10 +504,10 @@ sudo apt-get install -y taler-wallet-cli</pre>
<a href="https://exchange.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>. <a href="https://exchange.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>.
</p> </p>
<!-- landing-rev --> <!-- landing-rev -->
<p class="landing-rev" data-landing-site="exchange" data-landing-version="43" data-landing-commit="d0594cb"> <p class="landing-rev" data-landing-site="exchange" data-landing-version="44" data-landing-commit="0d881cd">
Exchange landing <strong>v43</strong> Exchange landing <strong>v44</strong>
· content <time datetime="2026-07-17T18:33:13+02:00">2026-07-17 18:33 CEST</time> · content <time datetime="2026-09-16T23:19:33+02:00">2026-09-16 23:19 CEST</time>
· <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/d0594cb44ffb1bec2e009f6812167cbbf216eda9" title="koopa-admin-log d0594cb44ffb1bec2e009f6812167cbbf216eda9">d0594cb</a> · <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/0d881cd726da8d298c98114678253e3cbb7aa5e6" title="koopa-admin-log 0d881cd726da8d298c98114678253e3cbb7aa5e6">0d881cd</a>
</p> </p>
<!-- /landing-rev --> <!-- /landing-rev -->
</footer> </footer>

View file

@ -18,6 +18,7 @@ sudo firewall-cmd --list-ports
| 8080/tcp | Tor OR | — | | 8080/tcp | Tor OR | — |
| 23235/tcp | (legacy list; host SSH is :22, WAN via VeciGate 23235→22) | — | | 23235/tcp | (legacy list; host SSH is :22, WAN via VeciGate 23235→22) | — |
| **9200/tcp** | **Forgejo git-SSH** (podman rootlessport) | **OK** after add+reload | | **9200/tcp** | **Forgejo git-SSH** (podman rootlessport) | **OK** after add+reload |
| **6881/tcp+udp** | qBittorrent BT listen (`koopa-prime-qbittorrent`) | apply: `scripts/prime/apply-qbittorrent-bt-net.sh` |
### Not opened on purpose ### Not opened on purpose
@ -61,6 +62,7 @@ Forgejo advertises `SSH_PORT=9200`. Traffic hits **host:9200** (not Caddy). With
|------|--------| |------|--------|
| 2026-07-09 | 443/tcp re-added for IPv6 | | 2026-07-09 | 443/tcp re-added for IPv6 |
| 2026-07-10 | **9200/tcp** for Forgejo git-SSH (verified LAN + hairpin + SSH auth) | | 2026-07-10 | **9200/tcp** for Forgejo git-SSH (verified LAN + hairpin + SSH auth) |
| 2026-09-25 | **6881/tcp+udp** for qBittorrent BT (`scripts/prime/apply-qbittorrent-bt-net.sh`); VeciGate wan+hairpin DNAT live; WAN/LAN `nc` OK |
## Nym (`koopa-nym`, nym.com) ## Nym (`koopa-nym`, nym.com)

View file

@ -58,3 +58,7 @@ Or: Profile → Appearance → theme **hacktivism**, then hard-reload.
### Registration ### Registration
Public signup is disabled (`DISABLE_REGISTRATION`, no registration button). Public signup is disabled (`DISABLE_REGISTRATION`, no registration button).
### pre-receive: gitleaks + *enc.git gate (TODO320, 2026-09-11)
Live hooks under `~/koopa-forgejo/data/custom/hooks/pre-receive.d/` (gitleaks skip `*enc.git`; `git-crypt-enforce` Klartext-Sperre). Binary `data/custom/bin/gitleaks` v8.21.2. Installer + smoke: laptop `llm-configs/bin/forgejo-hooks/`. Ops note: `2026/2026-09-11--forgejo-gitleaks-enc-gate.md`. New repos → re-run `install-hooks-ht.sh`.

View file

@ -0,0 +1,41 @@
# koopa-galene — Galene SFU on CachyOS base
# Build on koopa (x86_64):
# bash ~/koopa-admin-log/scripts/galene/build.sh
# → localhost/koopa-galene:cachyos
#
# Upstream no longer ships release tarballs; build from git tag/branch.
ARG CACHYOS_IMAGE=docker.io/cachyos/cachyos:latest
FROM ${CACHYOS_IMAGE}
ARG GALENE_REF=galene-0.96.3
ARG GALENE_REPO=https://github.com/jech/galene.git
ENV TZ=Europe/Zurich \
PATH=/usr/local/bin:$PATH \
GALENE_DATA=/data \
GOPATH=/tmp/go \
GOTOOLCHAIN=auto
RUN pacman -Syu --noconfirm --needed \
bash curl ca-certificates catatonit tar git go \
&& pacman -Scc --noconfirm \
&& rm -rf /var/cache/pacman/pkg/* /tmp/*
RUN set -eux \
&& git clone --depth 1 --branch "$GALENE_REF" "$GALENE_REPO" /src/galene \
&& cd /src/galene \
&& CGO_ENABLED=0 go build -ldflags='-s -w' -o /usr/local/bin/galene . \
&& test -x /usr/local/bin/galene \
&& mkdir -p /opt/galene \
&& cp -a /src/galene/static /opt/galene/static \
&& rm -rf /src/galene /tmp/go /root/go /var/cache/pacman/pkg/*
COPY entrypoint.sh /docker-entrypoint.sh
RUN chmod 755 /docker-entrypoint.sh \
&& mkdir -p /data/groups /data/recordings /data/data \
&& ln -sfn /opt/galene/static /data/static
EXPOSE 8443
WORKDIR /data
ENTRYPOINT ["/usr/bin/catatonit", "--", "/docker-entrypoint.sh"]

36
configs/galene/README.md Normal file
View file

@ -0,0 +1,36 @@
# Galene — SFU on CachyOS (koopa)
| Item | Value |
|------|--------|
| Stack | [Galene](https://galene.org/) |
| Image | `localhost/koopa-galene:cachyos` (`FROM docker.io/cachyos/cachyos`) |
| Build | Go from git tag `GALENE_REF` (default `galene-0.96.3`; no release tarballs) |
| Live dir | `/home/hernani/koopa-galene/` |
| Container | `koopa-galene` |
| Host port | **9029** = Paivana paywall; Galene HTTP backend **127.0.0.1:19129** (`-insecure`) |
| Public site | `galene.hacktivism.ch` |
## Build + up (koopa)
```bash
bash /path/to/koopa-admin-log/scripts/galene/build.sh
mkdir -p ~/koopa-galene && cp -a /path/to/koopa-admin-log/configs/galene/compose.yml ~/koopa-galene/
cd ~/koopa-galene && podman-compose up -d
```
## Caddy
```bash
sudo bash /path/to/koopa-admin-log/scripts/caddy/caddy-apply.sh \
--snippet /path/to/koopa-admin-log/configs/caddy/galene.hacktivism.ch.caddy \
--site galene.hacktivism.ch --port 9029 --label galene
```
DNS + VeciGate for the hostname; WebRTC UDP ports documented when first room is live.
## Notes
- Volume `./data` must not hide UI assets; entrypoint passes `-static /opt/galene/static`.
- Example group: copy `groups/hacktivism.json.example` → `~/koopa-galene/data/groups/hacktivism.json` (change op password).
- WebRTC UDP: compose publishes **10000–10099/udp**; set the same range in VeciGate DNAT → koopa. Entrypoint uses `-udp-range` (`GALENE_UDP_RANGE`).
- Built-in TURN (`-turn auto`) logs `no public addresses` until the host has a reachable public/mapped address; fix UDP/NAT first, then re-check logs.

View file

@ -0,0 +1,30 @@
# koopa-galene — Galene on CachyOS
# Live: /home/hernani/koopa-galene/
# Build: bash ~/koopa-admin-log/scripts/galene/build.sh → localhost/koopa-galene:cachyos
#
# Public :9029 = koopa-paivana-galene (shared paivana image).
# Backend on pasta host IP — Paivana DEST → 172.17.0.1:19129 (HTTP -insecure; not LAN 0.0.0.0).
# WebRTC UDP: still published (see README / ports.md)
services:
galene:
image: localhost/koopa-galene:cachyos
container_name: koopa-galene
restart: unless-stopped
environment:
- TZ=Europe/Zurich
- GALENE_UDP_RANGE=${GALENE_UDP_RANGE:-10000-10099}
volumes:
- ./data:/data
- ./entrypoint.sh:/docker-entrypoint.sh:ro
ports:
- "172.17.0.1:${BACKEND_PORT:-19129}:8443"
- "${GALENE_UDP_LO:-10000}-${GALENE_UDP_HI:-10099}:${GALENE_UDP_LO:-10000}-${GALENE_UDP_HI:-10099}/udp"
labels:
org.hacktivism.service: galene
org.hacktivism.host_port: "9029"
org.hacktivism.backend_port: "${BACKEND_PORT:-19129}"
org.hacktivism.site: galene.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.port_status: backend-19129-paywall-9029
org.hacktivism.image_base: cachyos

21
configs/galene/entrypoint.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/bash
set -euo pipefail
# Galene listens HTTPS by default; behind Caddy we serve plain HTTP on :8443
# with -insecure (TLS terminated at Caddy).
# Static assets stay in the image (/opt/galene/static); the ./data volume must
# not shadow them — pass -static explicitly.
DATA="${GALENE_DATA:-/data}"
STATIC="${GALENE_STATIC:-/opt/galene/static}"
# Host/UDP map: VeciGate WAN → koopa 10000-10099/udp (see configs/ports.md).
UDP_RANGE="${GALENE_UDP_RANGE:-10000-10099}"
mkdir -p "$DATA/groups" "$DATA/recordings" "$DATA/data"
cd "$DATA"
exec /usr/local/bin/galene \
-http "0.0.0.0:8443" \
-insecure \
-static "$STATIC" \
-udp-range "$UDP_RANGE" \
-data "$DATA/data" \
-groups "$DATA/groups" \
-recordings "$DATA/recordings" \
"$@"

View file

@ -0,0 +1,7 @@
{
"displayName": "hacktivism",
"public": true,
"op": [{"username": "op", "password": "changeme"}],
"presenter": [{}],
"other": []
}

View file

@ -0,0 +1,5 @@
# GOA backup pointers
Canonical dumps: **`~/backups/goa/`** on koopa and magikoopa (not in this git tree).
See `2026/2026-09-04--goa-backup-regio-ng.md`.

View file

@ -0,0 +1,51 @@
# Lab local on koopa (parallel to live)
Does **not** touch live GOA (`taler-hacktivism*`, **9010–9015**) or **9080** (`koopa-nym`).
| Lab | Container | Host binds (loopback only) |
|-----|-----------|----------------------------|
| **goa-regio-ng** | `goa-regio-ng` | `127.0.0.1:9180→80`, `127.0.0.1:9322→22` |
| **mytops-local** | `mytops-local` | `127.0.0.1:8288→80` |
## goa-regio-ng
- Tree on laptop/koopa: `~/src/regio-local/`
- Inventory (canonical copy here): [`goa-regio-ng-koopa.yml`](./goa-regio-ng-koopa.yml)
- Ansible from magikoopa: ProxyCommand → `hernani@koopa` → `127.0.0.1:9322`
- Master: `koopa-admin-secrets/backups/goa/current/exchange-offline/master.priv`
```bash
rsync -az ~/src/regio-local/ hernani@koopa:src/regio-local/
ssh hernani@koopa 'cd ~/src/regio-local && REGIO_HTTP_PORT=9180 REGIO_SSH_PORT=9322 REGIO_BIND=127.0.0.1 ./scripts/01-build-run.sh'
REGIO_PODMAN_SSH=hernani@koopa REGIO_INVENTORY=$HOME/git/admin-logs/koopa-admin-log/configs/lab-local/goa-regio-ng-koopa.yml \
~/src/regio-local/scripts/03-deploy.sh
REGIO_HTTP_PORT=9180 REGIO_PROBE_SSH=hernani@koopa ~/src/regio-local/scripts/04-probe.sh
```
Never `REGIO_PUBLISH_KOOPA_PORTS=1` on koopa next to live GOA.
## mytops-local
- **Verified 2026-09-04:** koopa `127.0.0.1:8288/config` → **200**; laptop same stack on **8088** → **200**. Daylog: `2026/2026-09-04--mytops-local-podman.md`. FIND: [`../koopa-setup`](../koopa-setup) · ports: [`../ports.md`](../ports.md).
- Tree: `mytops-admin-log` **`master`** (`mytops-local/wip:…`; rsync to `~/src/mytops-admin-log` on koopa; `.git` optional). Stage live-restore on betel still TODO.
- Config snippet: [`mytops-local.toml`](./mytops-local.toml) — port **8288** on koopa
- Orchestrator: `MYTOPS_LOCAL_HTTP_PORT=8288 ./scripts/taler-merchant/setup-local.sh`
- If `taler-merchant-dbconfig` fails (no postgres socket): `systemctl enable --now postgresql` inside the container, then dbconfig + `taler-merchant.target` again
```bash
# on koopa: image + container (repo bind)
podman build -t localhost/mytops-debian-systemd:trixie -f Containerfile.mytops-local .
podman rm -f mytops-local 2>/dev/null || true
podman run -d --name mytops-local --hostname mytops-local \
--systemd=always --cap-add SYS_ADMIN --security-opt label=disable \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw --tmpfs /run --tmpfs /run/lock \
-p 127.0.0.1:8288:80 \
-v "$HOME/src/mytops-admin-log:/root/mytops-admin-log:ro" \
localhost/mytops-debian-systemd:trixie /sbin/init
# apply koopa URL then setup (needs RW copy of config or run apply on host tree)
podman exec mytops-local bash -lc \
'cd /root/mytops-admin-log && MYTOPS_LOCAL_HTTP_PORT=8288 ./scripts/taler-merchant/setup-local.sh'
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8288/config # expect 200
```
Laptop default remains **8088**; koopa lab uses **8288** so both can coexist with regio **9180**.

View file

@ -0,0 +1,59 @@
# goa-regio-ng on koopa — parallel lab; does NOT use live 9010–9015 or 9080 (nym).
# Host binds on koopa: 127.0.0.1:9180→80, 127.0.0.1:9322→22.
# Ansible from magikoopa via ProxyCommand into koopa loopback.
#
# Live GOA (untouched): taler-hacktivism{,-bank,-exchange-ansible} on 9010–9015.
regional_currency:
hosts:
goa-regio-ng:
ansible_host: 127.0.0.1
ansible_port: 9322
ansible_user: root
ansible_ssh_private_key_file: "{{ lookup('ansible.builtin.env', 'HOME') }}/src/regio-local/ssh/regio_local_ed25519"
ansible_ssh_common_args: >-
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
-o ProxyCommand="ssh -W 127.0.0.1:%p -o StrictHostKeyChecking=no hernani@koopa"
ansible_python_interpreter: /usr/bin/python3
regional_currency_currency: GOA
regional_currency_currency_name: "GOA exploration currency"
regional_currency_domain: goa.local
regional_currency_bank_name: "GOA Exploration Bank"
regional_currency_bank_admin_password: "change-me"
regional_currency_bank_port: 8080
regional_currency_bank_bind: "127.0.0.1"
regional_currency_enable_tls: false
regional_currency_enable_conversion: false
regional_currency_testing_deployment: true
regional_currency_enable_exchange_terms: false
regional_currency_enable_exchange_privacy: false
regional_currency_podman_systemd_relax: true
# Dual merchant (CHF package + regional GOA); regio-style BASE_URLs (no :9180).
regional_currency_merchant_currency: CHF
regional_currency_merchant_regional_exchange_section: goa
regional_currency_merchant_disable_exchanges:
- kudos
regional_currency_merchant_disable_currencies:
- KUDOS
regional_currency_disable_currencies:
- kudos
- testkudos
- euro
- swiss-francs
- netzbon
regional_currency_round_unit: "GOA:0.00000001"
regional_currency_tiny_amount: "GOA:0.00000001"
regional_currency_fractional_input_digits: 8
regional_currency_fractional_normal_digits: 0
regional_currency_fractional_trailing_zero_digits: 0
regional_currency_alt_unit_names: '{"24":"Yotta-GOA","21":"Zetta-GOA","18":"Exa-GOA","15":"Peta-GOA","12":"Tera-GOA","9":"Giga-GOA","6":"Mega-GOA","3":"Kilo-GOA","0":"GOA","-1":"Deci-GOA","-2":"Centi-GOA","-3":"Milli-GOA","-6":"Micro-GOA","-7":"Deci-Micro-GOA","-8":"Atomic-GOA"}'
regional_currency_common_amounts: "GOA:10 GOA:20 GOA:50 GOA:100 GOA:200 GOA:1000"
regional_currency_static_coins_file: goa-exchange-coins.conf
regional_currency_coin_withdraw_duration: 7 days
regional_currency_default_debt_limit: "GOA:4503599627370496"
regional_currency_exchange_master_public_key_expected: "TW6K5FXF81VYCAH0YWYX0SX98KBBSJ42VX27WAX01FTFH400QG10"
regional_currency_exchange_master_priv_src: "{{ lookup('ansible.builtin.env', 'HOME') }}/git/admin-logs/koopa-admin-secrets/backups/goa/current/exchange-offline/master.priv"

View file

@ -0,0 +1,19 @@
---
# lab-only: pin *.goa.local → 127.0.0.1 inside goa-regio-ng
# ephemeral on container recreate — re-run after recreate / before site.yml wait-on-bank
# inventory: goa-regio-ng-koopa.yml (same SSH ProxyCommand)
#
# ansible-playbook -i goa-regio-ng-koopa.yml lab-hosts.yml
- name: lab hosts goa.local
hosts: regional_currency
gather_facts: false
tasks:
- name: /etc/hosts *.goa.local → 127.0.0.1
ansible.builtin.blockinfile:
path: /etc/hosts
marker: "# {mark} ANSIBLE LAB goa.local"
# podman systemd: /etc/hosts often EBUSY on atomic rename
unsafe_writes: true
block: |
127.0.0.1 bank.goa.local exchange.goa.local backend.goa.local goa.local

View file

@ -0,0 +1,6 @@
# Drop-in values for mytops-admin-log config.toml [mytops-local] when running on koopa.
# Laptop lab keeps 8088; koopa lab uses 8288 (avoid 901x live GOA, 9080 nym, 9180 goa-regio-ng).
[mytops-local]
base_url = "http://127.0.0.1:8288/"
forwarded_host = "127.0.0.1:8288"

View file

@ -0,0 +1,55 @@
# koopa-meet-web — Jitsi Meet web assets on CachyOS
# Build: bash ~/koopa-admin-log/scripts/meet/build.sh → localhost/koopa-meet-web:cachyos
#
# Full Meet needs prosody + jicofo + jvb (see compose.yml). This image serves
# the static web UI via nginx from Arch/CachyOS packages + upstream meet tarball.
# Signaling/media containers are separate services in the same compose.
ARG CACHYOS_IMAGE=docker.io/cachyos/cachyos:latest
FROM ${CACHYOS_IMAGE}
ARG JITSI_MEET_VERSION=stable
ARG JITSI_MEET_URL=https://download.jitsi.org/jitsi-meet/src/jitsi-meet-1.0.0.tar.bz2
ENV TZ=Europe/Zurich
RUN pacman -Syu --noconfirm --needed \
bash curl ca-certificates catatonit tar nginx \
&& pacman -Scc --noconfirm \
&& rm -rf /var/cache/pacman/pkg/* /tmp/*
# CachyOS/Arch nginx.conf embeds a default server and does NOT include http.d/.
# Replace it with a minimal conf that serves the branded landing.
RUN mkdir -p /usr/share/jitsi-meet /etc/nginx/http.d \
&& printf '%s\n' \
'worker_processes 1;' \
'events { worker_connections 1024; }' \
'http {' \
' include mime.types;' \
' default_type application/octet-stream;' \
' sendfile on;' \
' keepalive_timeout 65;' \
' server {' \
' listen 80 default_server;' \
' server_name _;' \
' root /usr/share/jitsi-meet;' \
' index index.html;' \
' location / { try_files $uri $uri/ /index.html; }' \
' }' \
'}' > /etc/nginx/nginx.conf \
&& printf '%s\n' \
'<!doctype html><html lang=en><meta charset=utf-8>' \
'<meta name=viewport content="width=device-width,initial-scale=1">' \
'<title>meet.hacktivism.ch</title>' \
'<style>body{font-family:system-ui,sans-serif;max-width:40rem;margin:3rem auto;padding:0 1rem;line-height:1.5}' \
'code{background:#f2f2f2;padding:.1rem .35rem;border-radius:4px}</style>' \
'<h1>meet.hacktivism.ch</h1>' \
'<p>Jitsi Meet <strong>web</strong> (CachyOS). Signaling/media (prosody / jicofo / jvb) is Phase&nbsp;2 — see compose + README.</p>' \
'<p>HTTP OK on host port <code>9031</code>. Full rooms need UDP/JVB after Phase&nbsp;2.</p>' \
> /usr/share/jitsi-meet/index.html
COPY entrypoint.sh /docker-entrypoint.sh
RUN chmod 755 /docker-entrypoint.sh
EXPOSE 80
ENTRYPOINT ["/usr/bin/catatonit", "--", "/docker-entrypoint.sh"]

23
configs/meet/README.md Normal file
View file

@ -0,0 +1,23 @@
# Meet (Jitsi) — CachyOS web stub (koopa)
| Item | Value |
|------|--------|
| Public site | `meet.hacktivism.ch` |
| Public port | **9031** (`koopa-paivana-meet`) |
| Backend | `127.0.0.1:19131` (`koopa-meet-web`) |
| Image (web) | `localhost/koopa-meet-web:cachyos` |
| Live dir | `/home/hernani/koopa-meet/` |
Phase 1 = Caddy vhost + branded nginx landing on CachyOS (`koopa-meet-web`) behind Paivana (GOA:42).
Phase 2 = prosody + jicofo + jvb — scaffold in `compose.phase2.yml` (`profiles: [phase2]`); images under `configs/meet/phase2/` still TODO. Not `docker-jitsi-meet` Debian by default.
UDP/JVB and TURN need VeciGate once rooms work (range TBD in `ports.md`).
## Caddy
Caddy stays on `127.0.0.1:9031` (paywall). App bind is loopback `19131` only.
```bash
sudo bash /path/to/koopa-admin-log/scripts/caddy/caddy-apply.sh \
--snippet …/configs/caddy/meet.hacktivism.ch.caddy \
--site meet.hacktivism.ch --port 9031 --label meet
```

View file

@ -0,0 +1,49 @@
# Phase-2 stubs — NOT started by default.
# Usage (after images exist):
# cd ~/koopa-meet && podman-compose -f compose.yml -f compose.phase2.yml up -d
#
# Do not pull official docker-jitsi-meet Debian images as the default base.
# Build CachyOS (or pinned binary) images under configs/meet/phase2/ when ready.
services:
prosody:
profiles: ["phase2"]
image: localhost/koopa-meet-prosody:cachyos
container_name: koopa-meet-prosody
restart: unless-stopped
environment:
- TZ=Europe/Zurich
# ports / volumes: fill when Containerfile exists
labels:
org.hacktivism.service: meet-prosody
org.hacktivism.site: meet.hacktivism.ch
org.hacktivism.phase: "2"
jicofo:
profiles: ["phase2"]
image: localhost/koopa-meet-jicofo:cachyos
container_name: koopa-meet-jicofo
restart: unless-stopped
environment:
- TZ=Europe/Zurich
depends_on:
- prosody
labels:
org.hacktivism.service: meet-jicofo
org.hacktivism.site: meet.hacktivism.ch
org.hacktivism.phase: "2"
jvb:
profiles: ["phase2"]
image: localhost/koopa-meet-jvb:cachyos
container_name: koopa-meet-jvb
restart: unless-stopped
environment:
- TZ=Europe/Zurich
# UDP host publish TBD in ports.md when allocated
depends_on:
- prosody
labels:
org.hacktivism.service: meet-jvb
org.hacktivism.site: meet.hacktivism.ch
org.hacktivism.phase: "2"

26
configs/meet/compose.yml Normal file
View file

@ -0,0 +1,26 @@
# koopa-meet — Jitsi Meet (CachyOS web stub + follow-up signaling/media)
# Live: /home/hernani/koopa-meet/
# Public :9031 = koopa-paivana-meet (shared paivana image).
# Backend on pasta host IP — Paivana DEST → 172.17.0.1:19131 (not LAN 0.0.0.0)
#
# Next: add prosody / jicofo / jvb services (CachyOS images or pinned binaries).
# Official docker-jitsi-meet is Debian-based — do not pull those as default here.
services:
meet-web:
image: localhost/koopa-meet-web:cachyos
build:
context: .
dockerfile: Containerfile
container_name: koopa-meet-web
restart: unless-stopped
environment:
- TZ=Europe/Zurich
ports:
- "172.17.0.1:${BACKEND_PORT:-19131}:80"
labels:
org.hacktivism.service: meet
org.hacktivism.backend_port: "${BACKEND_PORT:-19131}"
org.hacktivism.site: meet.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.port_status: backend-19131-paywall-9031
org.hacktivism.image_base: cachyos

3
configs/meet/entrypoint.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
set -euo pipefail
exec nginx -g 'daemon off;'

View file

@ -530,18 +530,22 @@
</style> </style>
</head> </head>
<body> <body>
<p class="stack-bar" role="note" title="Taler software on this merchant service (links → git.taler.net tags)"> <!-- stack-bar -->
<p class="stack-bar" role="note" title="Taler software on this merchant service (goa-regio-ng vanilla)">
<strong>stack</strong><span class="sep">·</span> <strong>stack</strong><span class="sep">·</span>
<a href="https://git.taler.net/taler/merchant/commit/b5af1c99052f4c5053070cd5c6cc39b68eca2a20.html" target="_blank" rel="noopener noreferrer" title="merchant tag v1.6.9">taler-merchant&nbsp;1.6.9</a> <a href="https://git.taler.net/taler-deployment.git/tree/?h=dev/hernani/goa-regio-ng-vanilla" target="_blank" rel="noopener noreferrer" title="taler-deployment branch dev/hernani/goa-regio-ng-vanilla">vanilla</a>
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/taler-typescript-core/commit/d7ab425239226b798a95dbf6742fe4b4a2e30e47.html" target="_blank" rel="noopener noreferrer" title="taler-typescript-core tag v1.6.8-dev.6">taler-merchant-webui&nbsp;1.6.8~dev6</a> taler-merchant&nbsp;1.6.23
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/merchant/commit/b5af1c99052f4c5053070cd5c6cc39b68eca2a20.html" target="_blank" rel="noopener noreferrer" title="merchant tag v1.6.9">libtalermerchant&nbsp;1.6.9</a> taler-merchant-webui&nbsp;1.6.38
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/fed7d0e782ea4d36b2d2e337d93bfd2723c6ed64.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.7-dev.2">libtalerexchange&nbsp;1.6.7~dev2</a> libtalermerchant&nbsp;1.6.23
<span class="sep">·</span> <span class="sep">·</span>
<a href="https://git.taler.net/taler/exchange/commit/fed7d0e782ea4d36b2d2e337d93bfd2723c6ed64.html" target="_blank" rel="noopener noreferrer" title="exchange tag v1.6.7-dev.2">taler-terms-generator&nbsp;1.6.7~dev2</a> libtalerexchange&nbsp;1.6.15
<span class="sep">·</span>
taler-terms-generator&nbsp;1.6.15
</p> </p>
<!-- /stack-bar -->
<main> <main>
<header class="hero"> <header class="hero">
<span class="badge">Merchant · dual currency</span> <span class="badge">Merchant · dual currency</span>
@ -833,10 +837,10 @@ sudo apt-get install -y taler-wallet-cli</pre>
<a href="https://taler.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>. <a href="https://taler.hacktivism.ch/privacy" style="color:#5eead4">/privacy</a>.
</p> </p>
<!-- landing-rev --> <!-- landing-rev -->
<p class="landing-rev" data-landing-site="merchant" data-landing-version="42" data-landing-commit="37ea4bb"> <p class="landing-rev" data-landing-site="merchant" data-landing-version="43" data-landing-commit="0d881cd">
Merchant landing <strong>v42</strong> Merchant landing <strong>v43</strong>
· content <time datetime="2026-07-17T18:27:48+02:00">2026-07-17 18:27 CEST</time> · content <time datetime="2026-09-16T23:19:33+02:00">2026-09-16 23:19 CEST</time>
· <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/37ea4bb8396691e3ea69ae61374e6623bf6c5ea7" title="koopa-admin-log 37ea4bb8396691e3ea69ae61374e6623bf6c5ea7">37ea4bb</a> · <a href="https://git.hacktivism.ch/hernani/koopa-admin-log/commit/0d881cd726da8d298c98114678253e3cbb7aa5e6" title="koopa-admin-log 0d881cd726da8d298c98114678253e3cbb7aa5e6">0d881cd</a>
</p> </p>
<!-- /landing-rev --> <!-- /landing-rev -->
</footer> </footer>

View file

@ -0,0 +1,5 @@
# Live on koopa: ~/koopa-silverbullet/.env (not git)
# Allocate HOST_PORT only after live `ss` + Freigabe + ports.md update.
HOST_PORT=9028
# Optional SilverBullet app auth (prefer Caddy basicauth):
# SB_USER=hernani:changeme

View file

@ -0,0 +1,44 @@
# koopa-silverbullet — SilverBullet on CachyOS base + server binary
# Build on koopa (x86_64):
# bash ~/koopa-admin-log/scripts/notes/build.sh
# → localhost/koopa-silverbullet:cachyos
#
# Base: docker.io/cachyos/cachyos (Arch-derived). App binary from upstream
# silverbullet-server-linux-x86_64 release (not the Alpine ghcr image).
ARG CACHYOS_IMAGE=docker.io/cachyos/cachyos:latest
FROM ${CACHYOS_IMAGE}
ARG SB_VERSION=2.10.0
ARG SB_ZIP_URL=https://github.com/silverbulletmd/silverbullet/releases/download/${SB_VERSION}/silverbullet-server-linux-x86_64.zip
ENV SB_HOSTNAME=0.0.0.0 \
SB_FOLDER=/space \
SB_PORT=3000 \
SB_NAME=SilverBullet \
TZ=Europe/Zurich \
PATH=/usr/local/bin:$PATH
# catatonit = Arch/CachyOS container init (tini not in repos)
RUN pacman -Syu --noconfirm --needed \
bash curl git openssh catatonit unzip \
&& pacman -Scc --noconfirm \
&& rm -rf /var/cache/pacman/pkg/* /tmp/*
# Fetch + install server binary (build-time; no Deno in image)
RUN curl -fsSL "$SB_ZIP_URL" -o /tmp/sb.zip \
&& unzip -o /tmp/sb.zip -d /tmp \
&& install -m 755 /tmp/silverbullet /silverbullet \
&& /silverbullet --version || true \
&& rm -rf /tmp/sb.zip /tmp/silverbullet
COPY entrypoint.sh /docker-entrypoint.sh
RUN chmod 755 /docker-entrypoint.sh \
&& mkdir -p /space
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD curl -fsS "http://127.0.0.1:${SB_PORT}/.instance" || exit 1
WORKDIR /space
ENTRYPOINT ["/usr/bin/catatonit", "--", "/docker-entrypoint.sh"]

65
configs/notes/README.md Normal file
View file

@ -0,0 +1,65 @@
# SilverBullet — SilverBullet on CachyOS (koopa)
Cross-host markdown notes (magikoopa + clementine). Stack name **SilverBullet** (parked web UI). Product **FreeNotes** = separate native enc notes (not this stack).
| Item | Value |
|------|--------|
| Stack | [SilverBullet](https://silverbullet.md/) server binary |
| Image | `localhost/koopa-silverbullet:cachyos` (`FROM docker.io/cachyos/cachyos`) |
| Live dir | `/home/hernani/koopa-silverbullet/` |
| Container | `koopa-silverbullet` |
| Host port | **9028** = Paivana paywall; app backend **127.0.0.1:19128** |
| Public site | `silverbullet.hacktivism.ch` |
| Auth | Paivana (GOA:42); no Caddy basic_auth |
| Forgejo space backup | private `hernani/freenotes` (historical name; SB space only) |
## Cutover freenotes → silverbullet (koopa)
Live still may be `~/koopa-freenotes` / CT `koopa-freenotes`. Scripts default dry-run; `--apply` needs Freigabe.
```bash
bash /path/to/koopa-admin-log/scripts/notes/status.sh
bash /path/to/koopa-admin-log/scripts/notes/cutover-to-silverbullet.sh
# Freigabe:
bash /path/to/koopa-admin-log/scripts/notes/cutover-to-silverbullet.sh --apply
```
See `scripts/notes/README.md` for seed + Caddy order. DNS: `silverbullet.hacktivism.ch`.
## Build + recreate (koopa)
```bash
# clone koopa-admin-log from Forgejo when needed (no permanent ~/ clone)
bash /path/to/koopa-admin-log/scripts/notes/build.sh
cd ~/koopa-silverbullet
podman-compose down
podman-compose up -d
bash /path/to/koopa-admin-log/scripts/notes/up.sh
```
## Caddy apply (sudo on koopa)
```bash
sudo bash /path/to/koopa-admin-log/scripts/caddy/merge-notes-site.sh
# seed from secrets-enc SoT so apply does not rotate PASS
sudo NOTES_AUTH_SEED=/tmp/silverbullet-basicauth-seed.txt \
bash /path/to/koopa-admin-log/scripts/caddy/apply-notes-basicauth.sh
```
Runtime: `/etc/caddy/secrets/silverbullet-basicauth.txt` (root-only). Never recreate `~/koopa-secrets`.
## Space SoT (Forgejo)
Private `hernani/freenotes` — live tree `~/koopa-silverbullet/space/` (git). On-koopa push uses oneshot HTTP token (no hernani SSH key in `~/.ssh`); laptop push via `git@git.hacktivism.ch:hernani/freenotes.git` (ProxyJump).
## Client apps (hosts)
Notes-like **system apps** (standalone Brave/Chrome `--app=` window + own profile): `configs/notes/client-apps/`.
- magikoopa: `~/Applications/SilverBullet.app` — `bash client-apps/install-magikoopa.sh`
- clementine (on-box): `silverbullet.desktop` — `bash client-apps/install-clementine.sh`
- optional: browser **Install app** (PWA) for Dock identity
## Plugs (SB)
`space/_plug/`: `treeview.plug.js`, `silversearch.plug.js` — see `PLUGS.md`.

View file

@ -0,0 +1,23 @@
# SilverBullet — system Notes apps (hosts)
Goal: **like Apple Notes** — a real system app window on each laptop, not a browser bookmark and not SilverBullet plugs.
| Host | App | Behavior |
|------|-----|----------|
| magikoopa | `SilverBullet.app` → `~/Applications/` | Brave/Chrome **`--app=`** + own profile (`SilverBullet-BraveProfile`) — no tab bar |
| clementine | `silverbullet.desktop` | same `--app=` via Brave/Chromium + `~/.local/share/SilverBullet-browser` |
| both (optional) | Browser **Install app** / PWA | even closer to native Dock/menu identity |
**Not this:** `space/_plug/` (TreeView/SilverSearch) — those are in-editor extensions.
Install:
```bash
# magikoopa
bash configs/notes/client-apps/install-magikoopa.sh
# clementine (on-box)
bash configs/notes/client-apps/install-clementine.sh
```
First launch: log in once (Caddy basicauth); credentials stay in the app profile.

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key><string>SilverBullet</string>
<key>CFBundleDisplayName</key><string>SilverBullet</string>
<key>CFBundleIdentifier</key><string>ch.hacktivism.silverbullet</string>
<key>CFBundleVersion</key><string>1</string>
<key>CFBundleShortVersionString</key><string>1.0</string>
<key>CFBundleExecutable</key><string>SilverBullet</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>LSMinimumSystemVersion</key><string>12.0</string>
<key>CFBundleIconFile</key><string>AppIcon</string>
</dict>
</plist>

View file

@ -0,0 +1,31 @@
#!/bin/bash
# SilverBullet — Notes-like system app (standalone window, not a browser tab)
URL="https://silverbullet.hacktivism.ch/"
USER_DATA="${HOME}/Library/Application Support/SilverBullet-BraveProfile"
mkdir -p "$USER_DATA"
BRAVE="/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
CHROME="/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
# Dedicated Chromium profile so this feels like its own app (Dock, cookies, no tab chrome)
if [[ -x "$BRAVE" ]]; then
exec "$BRAVE" \
--user-data-dir="$USER_DATA" \
--class=SilverBullet \
--app="$URL" \
--name=SilverBullet
elif [[ -x "$CHROME" ]]; then
exec "$CHROME" \
--user-data-dir="$USER_DATA" \
--class=SilverBullet \
--app="$URL" \
--name=SilverBullet
else
# last resort: Safari has no --app; open dedicated window via osascript
exec osascript <<'OSA'
tell application "Safari"
activate
make new document with properties {URL:"https://silverbullet.hacktivism.ch/"}
end tell
OSA
fi

View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Install SilverBullet XFCE launcher on clementine (on-box). No Freigabe (user home).
set -euo pipefail
SRC="$(cd "$(dirname "$0")" && pwd)/silverbullet.desktop"
APPDIR="${HOME}/.local/share/applications"
DESK="${HOME}/Desktop"
mkdir -p "$APPDIR" "$DESK"
install -m 0644 "$SRC" "$APPDIR/silverbullet.desktop"
install -m 0644 "$SRC" "$DESK/silverbullet.desktop"
# refresh menu cache if available
command -v update-desktop-database >/dev/null && update-desktop-database "$APPDIR" || true
echo "STATUS=ok DESKTOP=$APPDIR/silverbullet.desktop SHORTCUT=$DESK/silverbullet.desktop"
echo "TIP=open https://silverbullet.hacktivism.ch then browser Install app for PWA"

View file

@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Install SilverBullet.app into ~/Applications (magikoopa). No Freigabe (user home).
set -euo pipefail
SRC="$(cd "$(dirname "$0")" && pwd)/SilverBullet.app"
DEST="${HOME}/Applications/SilverBullet.app"
URL="${HOME}/Desktop/SilverBullet.url"
mkdir -p "${HOME}/Applications" "${HOME}/Desktop"
if [[ -d "$SRC" ]]; then
rm -rf "$DEST"
cp -R "$SRC" "$DEST"
else
# bootstrap minimal app if scaffold app tree missing
mkdir -p "$DEST/Contents/MacOS" "$DEST/Contents/Resources"
cat >"$DEST/Contents/Info.plist" <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key><string>SilverBullet</string>
<key>CFBundleDisplayName</key><string>SilverBullet</string>
<key>CFBundleIdentifier</key><string>ch.hacktivism.silverbullet</string>
<key>CFBundleVersion</key><string>1</string>
<key>CFBundleShortVersionString</key><string>1.0</string>
<key>CFBundleExecutable</key><string>SilverBullet</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>LSMinimumSystemVersion</key><string>12.0</string>
</dict>
</plist>
PLIST
printf '%s\n' '#!/bin/bash' 'open "https://silverbullet.hacktivism.ch/"' >"$DEST/Contents/MacOS/SilverBullet"
chmod +x "$DEST/Contents/MacOS/SilverBullet"
fi
printf '%s\n' '[InternetShortcut]' 'URL=https://silverbullet.hacktivism.ch/' >"$URL"
echo "STATUS=ok APP=$DEST URL=$URL"

View file

@ -0,0 +1,12 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=SilverBullet
Comment=Notes-like SilverBullet on koopa — standalone window
TryExec=brave-browser
Exec=sh -c 'B=""; for c in brave-browser brave chromium chromium-browser google-chrome; do command -v "$c" >/dev/null && B="$c" && break; done; if [ -n "$B" ]; then exec "$B" --user-data-dir="$HOME/.local/share/SilverBullet-browser" --class=SilverBullet --app=https://silverbullet.hacktivism.ch/; else exec xdg-open https://silverbullet.hacktivism.ch/; fi'
Terminal=false
Categories=Office;Network;
Keywords=notes;todo;silverbullet;
StartupWMClass=SilverBullet
StartupNotify=true

38
configs/notes/compose.yml Normal file
View file

@ -0,0 +1,38 @@
# koopa-silverbullet — SilverBullet on CachyOS base (parked; FreeNotes = native enc)
# Live: /home/hernani/koopa-silverbullet/
# Build: bash ~/koopa-admin-log/scripts/notes/build.sh → localhost/koopa-silverbullet:cachyos
#
# Public :9028 = koopa-paivana-silverbullet (shared paivana image).
# Backend on pasta host IP — Paivana DEST → 172.17.0.1:19128 (not LAN 0.0.0.0)
services:
notes:
image: localhost/koopa-silverbullet:cachyos
build:
context: .
dockerfile: Containerfile
args:
SB_VERSION: "${SB_VERSION:-2.10.0}"
container_name: koopa-silverbullet
restart: unless-stopped
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Zurich
- SB_INDEX_PAGE=index
- SB_NAME=SilverBullet
- SB_SHELL_BACKEND=off
# Optional app-layer auth (prefer Caddy basicauth; leave empty in .env to skip):
# - SB_USER=${SB_USER}
volumes:
- ./space:/space
ports:
- "172.17.0.1:${BACKEND_PORT:-19128}:3000"
labels:
org.hacktivism.service: silverbullet
org.hacktivism.host_port: "9028"
org.hacktivism.backend_port: "${BACKEND_PORT:-19128}"
org.hacktivism.site: silverbullet.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.port_status: backend-19128-paywall-9028
org.hacktivism.image_base: cachyos

View file

@ -0,0 +1,28 @@
# container-koopa-silverbullet.service
# Install on koopa as hernani (after compose create):
# mkdir -p ~/.config/systemd/user
# cp configs/notes/container-koopa-silverbullet.service ~/.config/systemd/user/
# systemctl --user daemon-reload
# systemctl --user enable --now container-koopa-silverbullet.service
# Requires: loginctl enable-linger hernani (root, once)
#
# Container must already exist (podman-compose up -d once).
[Unit]
Description=Podman container-koopa-silverbullet.service (SilverBullet)
Documentation=https://silverbullet.md/
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/run/user/1000/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=always
TimeoutStopSec=90
ExecStart=/usr/bin/podman start koopa-silverbullet
ExecStop=/usr/bin/podman stop -t 20 koopa-silverbullet
ExecStopPost=/usr/bin/podman stop -t 20 koopa-silverbullet
Type=forking
[Install]
WantedBy=default.target

36
configs/notes/entrypoint.sh Executable file
View file

@ -0,0 +1,36 @@
#!/bin/bash
# SilverBullet entrypoint (CachyOS/Arch user tools).
# Adapted from upstream docker-entrypoint.sh (busybox → shadow useradd).
set -euo pipefail
if [[ -f /space/CONTAINER_BOOT.md ]]; then
echo "Executing CONTAINER_BOOT.md script"
bash /space/CONTAINER_BOOT.md &
fi
SB_FOLDER="${SB_FOLDER:-/space}"
if [[ -z "${PUID:-}" && "$(id -u)" == "0" ]]; then
PUID=$(stat -c "%u" "$SB_FOLDER")
echo "Will run SilverBullet with UID $PUID (from owner of $SB_FOLDER)"
fi
if [[ -z "${PGID:-}" ]]; then
PGID=$(stat -c "%g" "$SB_FOLDER")
fi
if [[ "${PUID:-0}" == "0" || "$(id -u)" != "0" ]]; then
exec /silverbullet "$@"
fi
echo "Creating silverbullet user UID=$PUID GID=$PGID"
getent group silverbullet >/dev/null 2>&1 || groupadd -g "$PGID" silverbullet || groupadd -o -g "$PGID" silverbullet
getent passwd silverbullet >/dev/null 2>&1 || useradd -M -N -g silverbullet -u "$PUID" -d "$SB_FOLDER" -s /bin/bash silverbullet \
|| useradd -o -M -N -g silverbullet -u "$PUID" -d "$SB_FOLDER" -s /bin/bash silverbullet
echo "Running SilverBullet as PUID=$PUID PGID=$PGID"
# quote-safe: pass args via "$@" under su -c is awkward; use runuser when present
if command -v runuser >/dev/null 2>&1; then
exec runuser -u silverbullet -- /silverbullet "$@"
fi
args=$(printf '%q ' "$@")
exec su silverbullet -s /bin/bash -c "/silverbullet $args"

View file

@ -0,0 +1,12 @@
# Plugs (apps)
Third-party SilverBullet plugs in (loaded automatically).
| Plug | Role |
|------|------|
| treeview.plug.js | Folder sidebar (Apple Notes-like) |
| silversearch.plug.js | Full-text search |
Install/update: drop into , reload SilverBullet.
Builtin SB plugs stay in the image; only extras live here.

View file

@ -0,0 +1,31 @@
# TODO
Canonical ADHD todo (SilverBullet space SoT; FreeNotes = separate native enc).
## Now (max 3) — active quest board
- [x] magikoopa SilverBullet.app (`~/Applications`) + Desktop SilverBullet.url
- [ ] Install silverbullet.desktop on clementine (on-box: client-apps/install-clementine.sh)
- [ ] One-shot migrate: Apple Notes export + Dokumente/TODO.md → here (or FreeNotes later)
- [ ] Human sudo: confirm `sudo ls -la /etc/caddy/secrets/silverbullet-basicauth.txt`
- [ ] Live cutover Freigabe: dir/container → koopa-silverbullet; Caddy → silverbullet.hacktivism.ch; DNS
## Next
- [x] Private Forgejo backup remote for space/ (hernani/freenotes — historical name)
- [x] Seed notes space on koopa
- [x] Caddy merge + basicauth scripts (live cutover pending Freigabe)
- [ ] DNS / public hostname silverbullet.hacktivism.ch (human)
- [x] Update productivity-adhd-notes 02 / 02b → single SoT pointing here
- [x] Wire magikoopa SSH push to hernani/freenotes (ProxyJump) — clone ~/git/freenotes
## Someday / amnesty
- [ ] PWA install both laptops (browser Install app)
- [ ] Second-layer SB_USER if basicauth alone is not enough
- [ ] TreeView / SilverSearch UX polish after first week
## Stats (gamification — agent updates)
- Session streak: 1
- Quests finished today: 6
- XP today: 60
- Last win: rename stack freenotes → silverbullet
- Boss: silverbullet cutover
- Boss HP: 70%

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
# Inbox
Apple **Quick Note** analogue. Dump here first; triage into [[TODO]] (Now / Next / Waiting / Someday) or a dedicated page.
Rules:
- Empty capture OK — fill the next `- [ ]` line and save.
- Do not create a new folder just to capture.
- After triage, clear or check off lines so Inbox stays short.
## Capture
- [ ]

View file

@ -0,0 +1,46 @@
---
# SilverBullet index page (SB_INDEX_PAGE=index)
# Apple-Notes-like home: pins + capture path + search
---
# Notes
Cross-host notes (magikoopa + clementine) via koopa SilverBullet.
Mental model = Apple Notes: **folders/pages · list · editor**, pin primary TODO, Quick Note → triage.
| Page | Apple analogue | Role |
|------|----------------|------|
| [[TODO]] | Pinned primary note | ADHD SoT: Now≤3 / Next / Waiting / Someday / Stats |
| [[inbox]] | Quick Note | Capture before triage |
## Pins
- [[TODO]]
- [[inbox]]
## How to use (Apple habits → here)
1. **Capture** into [[inbox]] (or SB quick-note if enabled) — do not invent folders first.
2. **Triage** into [[TODO]] sections (Now max 3). Same rules as former Apple Notes guide.
3. **Find** with Page Picker / search (**Cmd/Ctrl-K**).
4. **New page** when a topic is not a todo (meetings, dumps) — link from TODO by title, do not dump transcripts into TODO.
5. Optional later: TreeView plug (folder sidebar), Space Lua query page = “smart folder” for `#tag` open tasks.
## Shortcuts (target)
| Action | Typical SB |
|--------|------------|
| Open page / filter | Cmd/Ctrl-K (Page Picker) |
| Quick note | Ctrl-q (if client supports) → prefer landing in [[inbox]] |
| Search body | built-in search / SilverSearch plug |
## Hygiene (from Apple Notes ADHD pack)
- One primary [[TODO]] — no competing systems.
- Capture first; tags (`#taler` …) optional and light.
- On “I’m back”: re-read **Now** only.
- No passwords/tokens in notes.
## Apps
- [[PLUGS]] — TreeView + SilverSearch

View file

@ -2,27 +2,32 @@
GNU Taler **paivana-httpd** reverse-proxy paywall (DD 95 / DD 76 style), GOA payments. GNU Taler **paivana-httpd** reverse-proxy paywall (DD 95 / DD 76 style), GOA payments.
One process = one `BASE_URL` + one `DESTINATION_BASE_URL` + one `MERCHANT_BACKEND_URL`.
Shared **image / secrets / entrypoint / conf template**; per-service env sets
`PAIVANA_BASE_URL` + `PAIVANA_DESTINATION_BASE_URL`. Portal on **9025**; app
paywalls on **9028–9031** (Caddy unchanged). App backends listen loopback only
(`19128` SilverBullet, `19129` Galene HTTP, `19130` CryptPad edge, `19131` Meet).
| Item | Value | | Item | Value |
|------|--------| |------|--------|
| Live | `/home/hernani/koopa-paivana/` | | Live | `/home/hernani/koopa-paivana/` |
| Containers | `koopa-paivana`, `koopa-paivana-upstream` | | Containers | `koopa-paivana`, `koopa-paivana-{silverbullet,galene,cryptpad,meet}`, `koopa-paivana-upstream` |
| Image | `localhost/koopa-paivana:latest` (built from `Containerfile`); process **uid 1000** `paivana-httpd` | | Image | `localhost/koopa-paivana:latest` (built from `Containerfile`); process **uid 1000** `paivana-httpd` |
| Upstream | `nginxinc/nginx-unprivileged` on **:8080** (not root nginx:80) | | Upstream | portal: `nginxinc/nginx-unprivileged` on **:8080**; apps via pasta host IP `172.17.0.1:19128–19131` (compose publish, not `127.0.0.1`) |
| Host port | **9025** → Caddy `paivana.hacktivism.ch` | | Host ports | **9025** portal; **9028/9029/9030/9031** app paywalls → Caddy |
| Currency | **GOA** | | Currency | **multi** via goa-shop template `paivana` choices (CHF / FLOODS / GOA / TESTPAYSAN); wallet still filters by held coins |
| Merchant | `https://taler.hacktivism.ch/instances/goa-shop/` | | Merchant | `https://taler.hacktivism.ch/instances/goa-shop/` |
| Template | `paivana` (`template_type: paivana`, amount **`GOA:4200`**, `website_regex: .*`) | | Template | `paivana` (`template_type: paivana`, amount **`GOA:42`**, `website_regex: .*`) |
| Access | **`-g`** site-wide: pay once → example upstream free to browse | | Access | **`-g`** site-wide: pay once → that hostname free to browse |
| Upstream | example site in `upstream/` (compose service) |
## Layout ## Layout
| Path | Role | | Path | Role |
|------|------| |------|------|
| `Containerfile` | Multi-stage: build paivana-httpd from `git.taler.net/paivana` + Taler libs | | `Containerfile` | Multi-stage: build paivana-httpd from `git.taler.net/paivana` + Taler libs |
| `compose.yml` | `koopa-paivana` + nginx upstream | | `compose.yml` | portal + 4 app paywalls + nginx upstream (YAML anchor `x-paivana-common`) |
| `conf/paivana.conf.template` | Config; secrets substituted at start | | `conf/paivana.conf.template` | Shared conf; `@BASE_URL@` / `@DESTINATION_BASE_URL@` / secrets at start |
| `entrypoint.sh` | Inject secrets → run `paivana-httpd -g -f` | | `entrypoint.sh` | Env + secrets → run `paivana-httpd -g -f` |
| `secrets/` | **not in git** — live only | | `secrets/` | **not in git** — live only |
| `upstream/` | Protected demo content | | `upstream/` | Protected demo content |
| `container-koopa-paivana.service` | systemd --user oneshot compose up | | `container-koopa-paivana.service` | systemd --user oneshot compose up |
@ -90,9 +95,10 @@ extra_hosts:
| Check | Expect | | Check | Expect |
|-------|--------| |-------|--------|
| `curl -si http://127.0.0.1:9025/` | **302** → `/.well-known/paivana/templates/paivana#…` | | `curl -si http://127.0.0.1:9025/` | **302** → `/.well-known/paivana/templates/paivana#…` |
| `https://paivana.hacktivism.ch/` | **402** paywall HTML + `paivana: taler://pay-template/…` | | `curl -si http://127.0.0.1:902{8,9,0}/` | **302** same template path (per-host BASE_URL) |
| `https://{paivana,silverbullet,galene,cryptpad,meet}.hacktivism.ch/` | unpaid → **302** `…/templates/paivana#…` (or paywall HTML) |
| monitoring `urls` | `www.paivana` OK | | monitoring `urls` | `www.paivana` OK |
| e2e (GOA, lokal) | `e2e.paivana` Template-Pay **GOA:4200** (wenn `E2E_PAIVANA=1`) | | e2e (GOA, lokal) | `e2e.paivana` Template-Pay **GOA:42** (wenn `E2E_PAIVANA=1`) |
--- ---
@ -137,22 +143,26 @@ Flags `-g` (site-wide payment) and `-f` (X-Forwarded-For).
## Merchant template ## Merchant template
Create (or replace via PATCH / DELETE+POST — see live merchant API):
```bash ```bash
curl -X POST 'https://taler.hacktivism.ch/instances/goa-shop/private/templates' \ curl -X POST 'https://taler.hacktivism.ch/instances/goa-shop/private/templates' \
-H "Authorization: Bearer secret-token:…" \ -H "Authorization: Bearer secret-token:…" \
-H 'Content-Type: application/json' \ -H 'Content-Type: application/json' \
-d '{ -d '{
"template_id": "paivana", "template_id": "paivana",
"template_description": "Paivana paywall (GOA)", "template_description": "Paivana paywall portal (GOA)",
"template_contract": { "template_contract": {
"template_type": "paivana", "template_type": "paivana",
"summary": "Access to paivana.hacktivism.ch", "summary": "Access to paivana.hacktivism.ch portal",
"website_regex": ".*", "website_regex": ".*",
"choices": [{ "amount": "GOA:4200", "description": "Unlock example site (then free to browse)" }] "choices": [{ "amount": "GOA:42", "description": "Unlock portal (cryptpad / galene / silverbullet links)" }]
} }
}' }'
``` ```
goa-shop template `paivana` exposes multi-currency **choices**. Wallet/UI still only offers currencies the wallet holds. Live conf must use `instances/goa-shop/` + matching merchant token (not `goa-demo-*`).
## Docs ## Docs
- https://docs.taler.net/taler-paivana-manual.html - https://docs.taler.net/taler-paivana-manual.html

View file

@ -1,21 +1,21 @@
# koopa-paivana — host :9025 → Caddy paivana.hacktivism.ch # koopa-paivana — shared image/secrets/entrypoint for portal + app paywalls
# Live: /home/hernani/koopa-paivana/ # Live: /home/hernani/koopa-paivana/
services: #
paivana: # Public Caddy targets (unchanged):
build: # 9025 → portal (paivana.hacktivism.ch)
context: . # 9028 → paywall silverbullet
dockerfile: Containerfile # 9029 → paywall galene
# 9030 → paywall cryptpad
# 9031 → paywall meet (Jitsi web)
# App backends on pasta host IP (see app compose; not LAN 0.0.0.0):
# 172.17.0.1:19128 / 19129 / 19130 / 19131
x-paivana-common: &paivana-common
image: localhost/koopa-paivana:latest image: localhost/koopa-paivana:latest
container_name: koopa-paivana
restart: unless-stopped restart: unless-stopped
# Image already USER paivana-httpd; pin numeric + keep-id for host secrets/volumes.
user: "1000:1000" user: "1000:1000"
userns_mode: keep-id userns_mode: keep-id
ports:
- "9025:9967"
extra_hosts: extra_hosts:
# pasta publishes merchant on host :9010. Prefer fixed IPv4 — host-gateway
# alone still loses to public AAAA and times out from the container.
- "taler.hacktivism.ch:172.17.0.1" - "taler.hacktivism.ch:172.17.0.1"
- "bank.hacktivism.ch:172.17.0.1" - "bank.hacktivism.ch:172.17.0.1"
- "exchange.hacktivism.ch:172.17.0.1" - "exchange.hacktivism.ch:172.17.0.1"
@ -24,6 +24,22 @@ services:
- ./entrypoint.sh:/usr/local/bin/paivana-entrypoint:ro - ./entrypoint.sh:/usr/local/bin/paivana-entrypoint:ro
- ./secrets/merchant-access-token:/run/secrets/merchant-access-token:ro - ./secrets/merchant-access-token:/run/secrets/merchant-access-token:ro
- ./secrets/paivana-secret:/run/secrets/paivana-secret:ro - ./secrets/paivana-secret:/run/secrets/paivana-secret:ro
labels:
org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: multi
services:
paivana:
<<: *paivana-common
build:
context: .
dockerfile: Containerfile
container_name: koopa-paivana
ports:
- "9025:9967"
environment:
PAIVANA_BASE_URL: https://paivana.hacktivism.ch/
PAIVANA_DESTINATION_BASE_URL: http://upstream:8080/
depends_on: depends_on:
- upstream - upstream
labels: labels:
@ -31,10 +47,70 @@ services:
org.hacktivism.host_port: "9025" org.hacktivism.host_port: "9025"
org.hacktivism.site: paivana.hacktivism.ch org.hacktivism.site: paivana.hacktivism.ch
org.hacktivism.managed_by: koopa-admin org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: GOA org.hacktivism.currency: multi
# App paywalls: same image/secrets; BASE/DEST via env. Caddy still hits 9028–9031.
paivana-silverbullet:
<<: *paivana-common
container_name: koopa-paivana-silverbullet
ports:
- "9028:9967"
environment:
PAIVANA_BASE_URL: https://silverbullet.hacktivism.ch/
PAIVANA_DESTINATION_BASE_URL: http://172.17.0.1:19128/
labels:
org.hacktivism.service: paivana-silverbullet
org.hacktivism.host_port: "9028"
org.hacktivism.site: silverbullet.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: multi
paivana-galene:
<<: *paivana-common
container_name: koopa-paivana-galene
ports:
- "9029:9967"
environment:
PAIVANA_BASE_URL: https://galene.hacktivism.ch/
PAIVANA_DESTINATION_BASE_URL: http://172.17.0.1:19129/
labels:
org.hacktivism.service: paivana-galene
org.hacktivism.host_port: "9029"
org.hacktivism.site: galene.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: multi
paivana-cryptpad:
<<: *paivana-common
container_name: koopa-paivana-cryptpad
ports:
- "9030:9967"
environment:
PAIVANA_BASE_URL: https://cryptpad.hacktivism.ch/
PAIVANA_DESTINATION_BASE_URL: http://172.17.0.1:19130/
labels:
org.hacktivism.service: paivana-cryptpad
org.hacktivism.host_port: "9030"
org.hacktivism.site: cryptpad.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: multi
paivana-meet:
<<: *paivana-common
container_name: koopa-paivana-meet
ports:
- "9031:9967"
environment:
PAIVANA_BASE_URL: https://meet.hacktivism.ch/
PAIVANA_DESTINATION_BASE_URL: http://172.17.0.1:19131/
labels:
org.hacktivism.service: paivana-meet
org.hacktivism.host_port: "9031"
org.hacktivism.site: meet.hacktivism.ch
org.hacktivism.managed_by: koopa-admin
org.hacktivism.currency: multi
upstream: upstream:
# Non-root nginx (listens on 8080). See DESTINATION_BASE_URL in conf template.
image: docker.io/nginxinc/nginx-unprivileged:1.27-alpine image: docker.io/nginxinc/nginx-unprivileged:1.27-alpine
container_name: koopa-paivana-upstream container_name: koopa-paivana-upstream
restart: unless-stopped restart: unless-stopped

View file

@ -1,14 +1,14 @@
# paivana.hacktivism.ch — paywall reverse proxy # Shared paivana-httpd conf — BASE/DEST injected by entrypoint (env).
# Secrets injected by entrypoint from /run/secrets/ # Secrets injected from /run/secrets/
[paivana] [paivana]
SERVE = tcp SERVE = tcp
PORT = 9967 PORT = 9967
BIND_TO = 0.0.0.0 BIND_TO = 0.0.0.0
BASE_URL = https://paivana.hacktivism.ch/ BASE_URL = @BASE_URL@
DESTINATION_BASE_URL = http://upstream:8080/ DESTINATION_BASE_URL = @DESTINATION_BASE_URL@
MERCHANT_BACKEND_URL = https://taler.hacktivism.ch/instances/goa-shop/ MERCHANT_BACKEND_URL = https://taler.hacktivism.ch/instances/goa-shop/
MERCHANT_ACCESS_TOKEN = @MERCHANT_ACCESS_TOKEN@ MERCHANT_ACCESS_TOKEN = @MERCHANT_ACCESS_TOKEN@

View file

@ -5,6 +5,10 @@ SECRET_FILE="${PAIVANA_SECRET_FILE:-/run/secrets/paivana-secret}"
TEMPLATE="${PAIVANA_CONF_TEMPLATE:-/etc/paivana/paivana.conf.template}" TEMPLATE="${PAIVANA_CONF_TEMPLATE:-/etc/paivana/paivana.conf.template}"
OUT="${PAIVANA_CONF:-/tmp/paivana.conf}" OUT="${PAIVANA_CONF:-/tmp/paivana.conf}"
# Per-instance (portal + app paywalls share this entrypoint/image).
BASE_URL="${PAIVANA_BASE_URL:-https://paivana.hacktivism.ch/}"
DEST_URL="${PAIVANA_DESTINATION_BASE_URL:-http://upstream:8080/}"
if [ ! -r "$TOKEN_FILE" ]; then if [ ! -r "$TOKEN_FILE" ]; then
echo "missing merchant token: $TOKEN_FILE" >&2 echo "missing merchant token: $TOKEN_FILE" >&2
exit 1 exit 1
@ -17,10 +21,12 @@ fi
TOKEN=$(tr -d '\n\r' < "$TOKEN_FILE") TOKEN=$(tr -d '\n\r' < "$TOKEN_FILE")
SECRET=$(tr -d '\n\r' < "$SECRET_FILE") SECRET=$(tr -d '\n\r' < "$SECRET_FILE")
awk -v t="$TOKEN" -v s="$SECRET" ' awk -v t="$TOKEN" -v s="$SECRET" -v b="$BASE_URL" -v d="$DEST_URL" '
{ {
gsub(/@MERCHANT_ACCESS_TOKEN@/, t) gsub(/@MERCHANT_ACCESS_TOKEN@/, t)
gsub(/@PAIVANA_SECRET@/, s) gsub(/@PAIVANA_SECRET@/, s)
gsub(/@BASE_URL@/, b)
gsub(/@DESTINATION_BASE_URL@/, d)
print print
} }
' "$TEMPLATE" > "$OUT" ' "$TEMPLATE" > "$OUT"

View file

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Example site — free after GOA:4200</title> <title>hacktivism tools — unlocked</title>
<style> <style>
:root { color-scheme: light dark; } :root { color-scheme: light dark; }
body { body {
@ -26,29 +26,41 @@
.price { font-variant-numeric: tabular-nums; } .price { font-variant-numeric: tabular-nums; }
code { background: color-mix(in srgb, CanvasText 12%, transparent); padding: 0.1em 0.35em; border-radius: 3px; } code { background: color-mix(in srgb, CanvasText 12%, transparent); padding: 0.1em 0.35em; border-radius: 3px; }
.card { .card {
margin-top: 1.5rem; margin-top: 1.25rem;
padding: 1rem 1.1rem; padding: 1rem 1.1rem;
border: 1px solid color-mix(in srgb, CanvasText 18%, transparent); border: 1px solid color-mix(in srgb, CanvasText 18%, transparent);
border-radius: 10px; border-radius: 10px;
} }
ul { padding-left: 1.2rem; } ul { padding-left: 1.2rem; }
a { color: inherit; }
.sites a {
display: block;
margin: 0.45rem 0;
font-weight: 600;
}
</style> </style>
</head> </head>
<body> <body>
<span class="badge">unlocked</span> <span class="badge">unlocked</span>
<h1>Example site</h1> <h1>hacktivism tools</h1>
<p> <p>
You paid <strong class="price">GOA:4200</strong> once via GNU Taler / Paivana. You paid once via GNU Taler / Paivana
This whole example site is now free for you to browse (site-wide access cookie). (template <code>paivana</code> on <code>goa-shop</code>: CHF / FLOODS / GOA / TESTPAYSAN choices).
Site-wide access cookie is set for <code>paivana.hacktivism.ch</code>.
</p> </p>
<div class="card sites">
<p><strong>Sites</strong></p>
<a href="https://cryptpad.hacktivism.ch/">cryptpad.hacktivism.ch</a>
<a href="https://galene.hacktivism.ch/">galene.hacktivism.ch</a>
<a href="https://silverbullet.hacktivism.ch/">silverbullet.hacktivism.ch</a>
</div>
<div class="card"> <div class="card">
<p><strong>What this demonstrates</strong></p> <p><strong>Notes</strong></p>
<ul> <ul>
<li>Paywall: <code>paivana-httpd</code> in front of a normal upstream HTTP site</li> <li>One Paivana process = one <code>DESTINATION_BASE_URL</code> → this portal is the gated upstream.</li>
<li>Currency: exploration money <code>GOA</code> on exchange.hacktivism.ch</li> <li>Merchant: <code>goa-shop</code> · template <code>paivana</code> (multi-currency choices).</li>
<li>After payment: no further charge for pages behind this proxy</li> <li>Host: <code>https://paivana.hacktivism.ch/</code></li>
</ul> </ul>
<p style="margin-bottom:0">Host: <code>https://paivana.hacktivism.ch/</code></p>
</div> </div>
</body> </body>
</html> </html>

View file

@ -1,4 +1,4 @@
# Port map (see also host/overview/services.md) # Port map (koopa)
| Port | Role | | Port | Role |
|------|------| |------|------|
@ -7,29 +7,44 @@
| 443 | systemd `https-proxy.socket` → Caddy **9001** | | 443 | systemd `https-proxy.socket` → Caddy **9001** |
| 9000 | Caddy HTTP + ACME webroot | | 9000 | Caddy HTTP + ACME webroot |
| 9001 | Caddy HTTPS (vhosts) | | 9001 | Caddy HTTPS (vhosts) |
| 9010 | podman `taler-hacktivism` (merchant) | | **9010** | `goa-regio-ng` merchant API (HTTPS in CTR) |
| 9011 | podman **`taler-hacktivism-exchange-ansible`** (exchange) | | **9011** | `goa-regio-ng` exchange |
| 9012 | podman `taler-hacktivism-bank` (libeufin-bank) | | **9012** | `goa-regio-ng` libeufin-bank |
| 9013–9015 | bank / exchange / merchant public landings | | **9013–9015** | bank / exchange / merchant public landings (host nginx) |
| 9020 | podman `koopa-castopod` → Caddy `castopod.hacktivism.ch` | | 9020 | `koopa-castopod` → `castopod.hacktivism.ch` |
| 9021 | podman `koopa-bonfire` → Caddy `bonfire.hacktivism.ch` | | 9021 | `koopa-bonfire` → `bonfire.hacktivism.ch` |
| 9022 | podman `koopa-prime` (Jellyfin) → Caddy `prime.hacktivism.ch` | | 9022 | `koopa-prime` (Jellyfin) → `prime.hacktivism.ch` |
| 9023 | podman qBittorrent → Caddy `bt.hacktivism.ch` | | 9023 | qBittorrent WebUI → `bt.hacktivism.ch` |
| **9024** | podman **`koopa-forgejo`** (HTTP) → Caddy **`git.hacktivism.ch`** | | **6881** | qBittorrent BT listen (tcp+udp; firewalld + VeciGate DNAT) |
| **9025** | podman **`koopa-paivana`** (paivana-httpd) → Caddy **`paivana.hacktivism.ch`** | | **9024** | `koopa-forgejo` (HTTP) → **`git.hacktivism.ch`** |
| **9026** | podman **`koopa-lemmy-proxy`** → Caddy **`lemmy.hacktivism.ch`** | | **9025** | `koopa-paivana` → `paivana.hacktivism.ch` |
| **9027** | podman **`koopa-decidim`** → Caddy **`decidim.hacktivism.ch`** | | **9026** | `koopa-lemmy-proxy` → `lemmy.hacktivism.ch` |
| **9200** | podman **Forgejo git-SSH** (host-direct; not Caddy) | | **9027** | `koopa-decidim` → `decidim.hacktivism.ch` |
| 9090–9092 | podman `koopa-tops-ng1` … `ng3` → Caddy `tops.ng{1,2,3}.hacktivism.ch` | | **9028** | `koopa-paivana-silverbullet` → `silverbullet.hacktivism.ch` |
| 8080 | Tor ORPort | | **9029** | `koopa-paivana-galene` → `galene.hacktivism.ch` |
| **9030** | `koopa-paivana-cryptpad` → `cryptpad.hacktivism.ch` |
| **9031** | `koopa-paivana-meet` → `meet.hacktivism.ch` |
| **9032** | `koopa-bbb-front` → `bbb.hacktivism.ch` |
| **9200** | Forgejo git-SSH (host-direct; not Caddy) |
| 9090–9092 | `koopa-tops-ng1`…`ng3` → `tops.ng{1,2,3}.hacktivism.ch` |
| **8080** | host `tor.service` ORPort |
| **9051** | host Tor ControlPort (loopback) |
VeciGate: WAN **80→9000**, WAN **443→9001**. VeciGate: WAN **80→9000**, WAN **443→9001**.
Public apps: Caddy vhosts on **9001** → 127.0.0.1:{9010–9015, 9020–9027, 9090–9092}. Public apps: Caddy on **9001** → 127.0.0.1:{9010–9015, 9020–9032, 9090–9092}.
Git SSH needs separate NAT/firewall **9200/tcp** if exposed to WAN. Git SSH needs **9200/tcp** if exposed to WAN.
| **1789** | podman **`koopa-nym`** mixnet (nym.com nym-node) | | UDP range | Role |
| **1790** | podman **`koopa-nym`** verloc | |-----------|------|
| **9080** | podman **`koopa-nym`** HTTP API (mapped from container 8080; Tor keeps **8080**) | | **10000–10099/udp** | Galene WebRTC |
| **19000** | optional nym entry WS (gateway mode) |
| **51822/udp** | optional nym WireGuard (dVPN path) |
| Extra | Role |
|-------|------|
| **1789** | `koopa-nym` mixnet |
| **1790** | `koopa-nym` verloc |
| **9080** | `koopa-nym` HTTP API |
| **9180** | lab `goa-regio-ng` HTTP (loopback; `configs/lab-local/`) |
| **9322** | lab `goa-regio-ng` SSH/ansible (loopback) |
| **8288** | lab `mytops-local` HTTP (loopback) |
login-health inventory: `scripts/login-health/koopa-login-health.sh`.

View file

@ -6,6 +6,7 @@
| Compose | `compose.yml` (this dir; **no secret values**) | | Compose | `compose.yml` (this dir; **no secret values**) |
| Jellyfin | **9022** → Caddy `prime.hacktivism.ch` | | Jellyfin | **9022** → Caddy `prime.hacktivism.ch` |
| qBittorrent | **9023** → Caddy `bt.hacktivism.ch` | | qBittorrent | **9023** → Caddy `bt.hacktivism.ch` |
| BT listen | **6881** tcp+udp (firewalld + VeciGate DNAT); apply `scripts/prime/apply-qbittorrent-bt-net.sh` |
| Topic | `2026/2026-07-09--koopa-prime-jellyfin.md` | | Topic | `2026/2026-07-09--koopa-prime-jellyfin.md` |
`WEBUI_PASSWORD` is `${WEBUI_PASSWORD}` in the mirror — live value only in `WEBUI_PASSWORD` is `${WEBUI_PASSWORD}` in the mirror — live value only in

Some files were not shown because too many files have changed in this diff Show more