koopa-admin-log/2026/2026-07-09--exchange-snapshot-and-restore.md

6.8 KiB
Raw Blame History

Exchange snapshot + restore (GOA) — 2026-07-09

Scope: local on host koopa only. No registry, no upload, no public internet publish.

Container was stopped then committed/saved. Live name: taler-exchange-hacktivism.


1. What was stored (local files)

Directory (hernani on koopa):

/home/hernani/images/taler-stack-20260709-snapshot/
File Role Size (approx.)
taler-exchange-hacktivism-live-20260709-snapshot.tar full exchange image archive ~1.6G
taler-hacktivism-live-20260709-snapshot.tar merchant archive (partial earlier run) ~2.4G
SHA256SUMS checksums for completed saves

Podman images (local store only):

Image Tag Notes
localhost/taler-exchange-hacktivism-live 20260709-snapshot committed from stopped container
localhost/taler-exchange-hacktivism-live 9011 previous live tag (still present)
localhost/taler-hacktivism-live 20260709-snapshot merchant (if commit kept)
localhost/taler-bank-hacktivism-live 20260709-snapshot bank (if commit kept)

Verify:

# as hernani@koopa
ls -lh /home/hernani/images/taler-stack-20260709-snapshot/
sha256sum -c /home/hernani/images/taler-stack-20260709-snapshot/SHA256SUMS
podman images | grep exchange
podman ps -a --filter name=taler-exchange-hacktivism

Expected container state after stop:

taler-exchange-hacktivism  Exited (…)  localhost/taler-exchange-hacktivism-live:9011  0.0.0.0:9011->9011/tcp

2. How the snapshot was made

# as hernani@koopa — local only
podman stop taler-exchange-hacktivism

TAG=20260709-snapshot
OUT=/home/hernani/images/taler-stack-$TAG
mkdir -p "$OUT"

podman commit taler-exchange-hacktivism \
  localhost/taler-exchange-hacktivism-live:$TAG

podman save -o "$OUT/taler-exchange-hacktivism-live-$TAG.tar" \
  localhost/taler-exchange-hacktivism-live:$TAG

sha256sum "$OUT/taler-exchange-hacktivism-live-$TAG.tar" | tee -a "$OUT/SHA256SUMS"

-p on commit pauses the container if still running; after stop it is optional.


3. Restore from image (same host)

A. From local image tag (fast)

podman rm -f taler-exchange-hacktivism   # only if replacing dead/exited

podman run -d --name taler-exchange-hacktivism \
  --network pasta \
  -p 9011:9011 \
  --label org.hacktivism.service=taler-exchange \
  --label org.hacktivism.host_port=9011 \
  --label org.hacktivism.site=exchange.hacktivism.ch \
  --label org.hacktivism.currency=GOA \
  --label org.hacktivism.managed_by=koopa-admin \
  localhost/taler-exchange-hacktivism-live:20260709-snapshot \
  sleep infinity

B. From tar (if image store was wiped)

podman load -i /home/hernani/images/taler-stack-20260709-snapshot/taler-exchange-hacktivism-live-20260709-snapshot.tar
# then same podman run as above

C. Start services (manual model, no systemd)

Inside container as root, then app user:

podman exec -u root -it taler-exchange-hacktivism bash
# 1) base: postgres, runtime dirs, secmods, wire helpers
/root/start_base_services_for_taler_exchange.sh --no-shell
# 2) httpd
runuser -u taler-exchange-httpd -- /usr/local/bin/start_exchange.sh --restart
# 3) health
/usr/local/bin/check_exchange-health.sh

Host / public checks:

curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:9011/config
curl -sS -o /dev/null -w "%{http_code}\n" https://exchange.hacktivism.ch/config
curl -sS -o /dev/null -w "%{http_code}\n" https://exchange.hacktivism.ch/keys

Caddy already proxies exchange.hacktivism.ch → host :9011 (see configs/caddy/, configs/ports.md).


4. GOA configuration (authoritative tree)

Do not edit package taler-exchange.conf defaults by hand. Site config lives in overrides + coins (merchant pattern).

In container In admin-log repo
/etc/taler-exchange/exchange-overrides.conf configs/taler-exchange/exchange-overrides.conf
/etc/taler-exchange/conf.d/exchange-coins.conf configs/taler-exchange/conf.d-exchange-coins.conf
secrets (wire gateway) not in admin-log → koopa-admin-secrets
start scripts scripts/taler-exchange/

GOA essentials in overrides:

  • CURRENCY = GOA, BASE_URL = https://exchange.hacktivism.ch/
  • SERVE = tcp, PORT = 9011
  • [currency-goa] ENABLED + unit names (Yotta…Atomic)
  • [exchange-account-1] payto x-taler-bank/bank.hacktivism.ch/exchange
  • Terms stubs: TERMS_ETAG / PRIVACY_ETAG = no-terms-v0 / no-privacy-v0

Deploy overrides from the local machine (example):

# from laptop, secrets never committed to admin-log
scp configs/taler-exchange/exchange-overrides.conf \
    hernani@koopa:/tmp/exchange-overrides.conf
scp configs/taler-exchange/conf.d-exchange-coins.conf \
    hernani@koopa:/tmp/exchange-coins.conf
ssh hernani@koopa 'podman cp /tmp/exchange-overrides.conf taler-exchange-hacktivism:/etc/taler-exchange/exchange-overrides.conf
  podman cp /tmp/exchange-coins.conf taler-exchange-hacktivism:/etc/taler-exchange/conf.d/exchange-coins.conf'

Greenfield (empty Debian + packages) only:
scripts/taler-exchange/archive/exchange-bootstrap.sh as root inside container — generates a new master key; not the same as restoring this snapshot.

After config change:

runuser -u taler-exchange-httpd -- /usr/local/bin/start_exchange.sh --restart
# optional offline keys / wire:
# scripts/taler-exchange/wire-enable-and-upload.sh
# scripts/taler-exchange/offline-sign-upload-keys.sh
# /usr/local/bin/install_no_terms.sh

5. Ansible

There is no Ansible playbook in koopa-admin-log / this monorepo path for the exchange.
Operational model is: podman + manual start scripts + GOA overrides as above.

If an external Ansible tree is added later, it should only:

  1. podman load / ensure image tag
  2. podman run with pasta + 9011:9011 + labels above
  3. copy GOA configs from configs/taler-exchange/
  4. run start_basestart_exchange
  5. never push images to a public registry without explicit request

Doc Content
configs/taler-exchange/README.md GOA site notes, terms, ports
scripts/taler-exchange/archive/README.md bootstrap vs daily start
configs/ports.md 9011 pasta
ops/ROOT_HYGIENE.md secrets layout

7. Session note (2026-07-09)

  • Exchange stopped on request (Exited 137).
  • Snapshot local only under /home/hernani/images/….
  • Known pre-stop issue: wirewatch had died after Postgres ownership/outage → bank confirms OK but wallet “Geld von Bank abheben…” could hang until wirewatch imports credits. After restore, always verify wirewatch is live (check_exchange-health.sh).