# Deploying torly This is the deployment used for `torly.smesh.lol`: one TinyGo binary behind Caddy, serving the relay and Blossom endpoints. The old orly service and its database have been removed from the host. ## Host layout ``` /usr/local/bin/torly torly binary /usr/local/bin/torly-monitor health check /etc/torly/torly.env torly environment /etc/systemd/system/torly.service /etc/systemd/system/torly-monitor.{service,timer} /home/mleku/.local/share/torly/ relay.key stable relay signing key db/ torly WAL and indexes blossom/blobs/ content-addressed Blob files blossom/index.log Blob ownership index monitor-status.json last health check ``` torly listens on `127.0.0.1:3336`. Caddy terminates TLS and proxies `https://torly.smesh.lol/`, `https://relay.orly.dev/` and `https://relay.mleku.dev/` and their WebSocket endpoints to that port. All three names serve the same relay identity `350abd25b77d4d6a11e66e022efa181c759e07a2828b8cc9a80034bcf4161d88`. ## Service control ```sh systemctl status torly systemctl restart torly journalctl -u torly -n 100 curl -sS http://127.0.0.1:3336/health ``` `torly.service` uses `TORLY_CONN_WORKERS=256` and `TORLY_BLOSSOM_MAX_BLOB_MB=128` from `/etc/torly/torly.env`. The worker pool is fixed; the acceptor is a raw nonblocking IPv4 socket with a 1024-connection backlog. Database startup waits up to two minutes because replaying a large WAL after an unclean shutdown can take that long. ## Monitor `torly-monitor.timer` runs every five minutes. It checks `/health`, the NIP-11 document and that `torly.service` is active, then writes `monitor-status.json`. After three consecutive health failures it restarts torly. It does not depend on orly or a mirror process. ```sh cat /home/mleku/.local/share/torly/monitor-status.json journalctl -u torly-monitor -n 50 systemctl list-timers torly-monitor.timer ``` ## Blossom backup and restore The backup is a tar with `manifest.json` first, followed by `blobs/`. Blob metadata (owner pubkey, MIME type, upload time) is in the manifest. The offline backup command requires the relay to be stopped because it opens the Blob store directly. ```sh systemctl stop torly runuser -u mleku -- /usr/local/bin/torly blossom-backup \ --data-dir /home/mleku/.local/share/torly \ --out /home/mleku/torly-blossom-$(date +%Y%m%d-%H%M%S).tar systemctl start torly ``` The default restore is live. The CLI copies the tar atomically to `DATA/blossom/restore.tar`; the running Blossom domain notices it within one second, imports every blob, writes `restore.status.json`, and removes the spool: ```sh runuser -u mleku -- /usr/local/bin/torly blossom-restore \ --data-dir /home/mleku/.local/share/torly \ --file /home/mleku/torly-blossom-YYYYmmdd-HHMMSS.tar ``` Use `--offline` to open the store directly while torly is stopped. Restore verifies every SHA-256, skips blobs already present, and preserves metadata. The live path is safe to repeat: the import is idempotent. For a database backup, stop torly and copy the whole data directory; the WAL and index files are only consistent while the process is stopped. ## Migrating Blossom out of orly The old Blossom data lived in Badger. `tools/orly-blossom-extract` is a standalone Go module that scans `blob:meta:` records and files and writes a torly backup tar. It must run as the orly user with orly stopped so Badger can take the lock: ```sh cd tools/orly-blossom-extract go build -o /usr/local/bin/orly-blossom-extract . runuser -u mleku -- /usr/local/bin/orly-blossom-extract \ --db /home/mleku/.local/share/ORLY \ --out /home/mleku/torly-blossom.tar ``` The migration used here produced 659 blobs (564 MB); the live restore reported `{"ok":true,"restored":68,"skipped":591}` because most blobs were already present from an earlier partial run. The old orly database has since been deleted. ## Caddy The site block is kept in `deploy/Caddyfile.torly` and appended to `/etc/caddy/Caddyfile`: ```caddyfile torly.smesh.lol { import compress import block_bots import no_adtech header Access-Control-Allow-Origin * header Access-Control-Allow-Headers "Accept, Authorization, Content-Type" reverse_proxy 127.0.0.1:3336 log { output file /var/log/caddy/torly.smesh.lol.log format json level INFO } } ``` The `relay.orly.dev` and `relay.mleku.dev` blocks also reverse-proxy to `127.0.0.1:3336`. `caddy validate --config /etc/caddy/Caddyfile` must be run as root only after the log file exists with owner `caddy`; `caddy validate` run as root can create the log file as root and make the subsequent reload fail with permission denied. If that happens, remove the root-owned file and reload Caddy again. ## Migration notes - The old orly export contained about 3,180 records with invalid UTF-8 or malformed JSON (out of 2,114,719 lines). torly's strict decoder rejected them and the importer counted them under `invalid`; they are not present in torly. This loss was accepted. - Blossom blobs were not part of the event export; they were migrated with the Badger extractor above. - The relay key was preserved. Deleting `relay.key` changes the relay's NIP-11 identity and graph-result signatures. - Events with more than 256 tags in total are stored and returned by ordinary queries but are skipped entirely by the graph index.