pyrtan / deploy / openmediavault / docker-compose.yml
5,252 bytes · last changed 2026-10-27 in No seeds: pyrtan.com is GitHub Pages and a hub list, nothing more
| 1 | # Pyrtan demo swarm for OpenMediaVault (or any Docker host). |
| 2 | # |
| 3 | # One hub, reachable from the LAN, and two services behind it that each |
| 4 | # hold part of the examples, so the demo shows routing between services |
| 5 | # rather than one process. A third service holds a trees/ folder you can |
| 6 | # edit on the NAS: drop a .toml in and it is live on the next request. |
| 7 | # |
| 8 | # Edit the two CHANGE-ME paths (the checkout, and a trees folder) to match |
| 9 | # your shared folder, then in OMV: Services > Compose > Files > Add (paste |
| 10 | # this) > Up. Steps in ../README.md. |
| 11 | # |
| 12 | # Open http://<nas-ip>:8700/ for the demo page. |
| 13 | |
| 14 | name: pyrtan |
| 15 | |
| 16 | x-pyrtan: &pyrtan |
| 17 | # Built on the NAS from a checkout of the repository (no image is |
| 18 | # published yet). The context is the repository root. |
| 19 | build: |
| 20 | context: /srv/dev-disk-by-uuid-CHANGE-ME/pyrtan |
| 21 | image: pyrtan:local |
| 22 | restart: unless-stopped |
| 23 | read_only: true |
| 24 | security_opt: [no-new-privileges:true] |
| 25 | cap_drop: [ALL] |
| 26 | tmpfs: [/tmp] |
| 27 | logging: |
| 28 | driver: json-file |
| 29 | options: { max-size: "5m", max-file: "3" } |
| 30 | environment: &env |
| 31 | # Uncomment to require a bearer token on every request but /health and |
| 32 | # the console. Every container reads it, so the swarm shares it. Do |
| 33 | # this before the hub is reachable from outside your LAN. |
| 34 | # PYRTAN_TOKEN: "change-me-to-something-long" |
| 35 | PYRTAN_EGRESS: any |
| 36 | # Federation: once the hub is reachable from outside (a tunnel or a |
| 37 | # port-forward with TLS), give it its public URL and it joins the |
| 38 | # default network pyrtan.com publishes, follows a hub in it, and lists |
| 39 | # itself in the directory. Needs the token, and PYRTAN_EGRESS: public |
| 40 | # above: hubs that follow this one may ask it to run trees. |
| 41 | # PYRTAN_JOIN may also hold invites to networks of your own |
| 42 | # (NAME:SECRET@HUB, from `pyrtan network new`), space-separated. |
| 43 | # PYRTAN_ADVERTISE: "https://hub.example.net" |
| 44 | # PYRTAN_JOIN: "default" |
| 45 | # PYRTAN_LISTED: "true" |
| 46 | # PYRTAN_REPORT_GAPS: "true" # opt in: the gaps your catalog trees meet (tree, node, value; never inputs) reach their authors via pyrtan.com |
| 47 | # PYRTAN_WATCH: "true" # run the trees' [[watches]]: a clock, a file, a topic or a serial line starts a run |
| 48 | # PYRTAN_CHAT: "true" # a lobby at /chat: people meet a random stranger here or on a hub this one follows, or a bot made of its trees |
| 49 | # PYRTAN_CHAT_PUBLIC: "true" # open the lobby to people without the token (they meet people, never a bot); everything else keeps the token |
| 50 | # PYRTAN_CHAT_TYPING: "0" # turn the lobby's "Stranger is typing…" off for everyone (each person can also turn it off for themselves) |
| 51 | PYRTAN_UNANSWERED: /state/unanswered.jsonl # sentences nobody answered, kept across restarts (the hub's; services with a hub leave the record to it) |
| 52 | PYRTAN_STATE: /state/federation.json |
| 53 | PYRTAN_STORE: /state/store # blobs: the hub's own and the ones it keeps for others |
| 54 | PYRTAN_REPLICAS: "2" # how many members or hubs should keep each of its blobs |
| 55 | # PYRTAN_HANDOUT: /handout # trees for the phones that joined with the token, not for this box (mount a directory at /handout) |
| 56 | |
| 57 | services: |
| 58 | hub: |
| 59 | <<: *pyrtan |
| 60 | # --cors lets the console at pyrtan.com talk to this hub from a browser. |
| 61 | command: ["hub", "--host", "0.0.0.0", "--port", "8700", "--poll", "10", "--cors", "https://pyrtan.com"] |
| 62 | environment: |
| 63 | <<: *env |
| 64 | PYRTAN_PORT: "8700" |
| 65 | ports: |
| 66 | - "8700:8700" |
| 67 | volumes: |
| 68 | - hub-state:/state |
| 69 | # - /srv/dev-disk-by-uuid-CHANGE-ME/pyrtan/handout:/handout # with PYRTAN_HANDOUT above: trees the phones run |
| 70 | # Trees that read files, run programs or open serial lines reach this |
| 71 | # container, not the NAS: mount what they may see (read-only where you |
| 72 | # can) and pass the devices through; the tree's own paths/commands/ |
| 73 | # devices lists are the allow-lists. PYRTAN_EGRESS: public closes all |
| 74 | # three. Browser trees need an image with Playwright (pyrtan[browser]). |
| 75 | # volumes: |
| 76 | # - /var/log:/var/log:ro |
| 77 | # devices: |
| 78 | # - /dev/ttyUSB0:/dev/ttyUSB0 |
| 79 | |
| 80 | news: |
| 81 | <<: *pyrtan |
| 82 | command: ["serve", "/examples/hacker-news", "/examples/github", "--host", "0.0.0.0", "--port", "8701", "--name", "news", "--hub", "http://hub:8700", "--advertise", "http://news:8701"] |
| 83 | depends_on: [hub] |
| 84 | |
| 85 | weather: |
| 86 | <<: *pyrtan |
| 87 | command: ["serve", "/examples/weather", "/examples/site-status", "--host", "0.0.0.0", "--port", "8701", "--name", "weather", "--hub", "http://hub:8700", "--advertise", "http://weather:8701"] |
| 88 | depends_on: [hub] |
| 89 | |
| 90 | # Your own trees. Edit files in this folder from a share; the service |
| 91 | # reloads them without a restart. `pyrtan check` them first: |
| 92 | # docker compose -p pyrtan exec mine pyrtan check /trees |
| 93 | # Gaps are kept in /trees/.gaps.jsonl (the one file the service writes), |
| 94 | # so the list of branches to write survives a restart. |
| 95 | mine: |
| 96 | <<: *pyrtan |
| 97 | command: ["serve", "/trees", "--host", "0.0.0.0", "--port", "8701", "--name", "mine", "--hub", "http://hub:8700", "--advertise", "http://mine:8701", "--gaps", "/trees/.gaps.jsonl"] |
| 98 | volumes: |
| 99 | - /srv/dev-disk-by-uuid-CHANGE-ME/pyrtan/trees:/trees |
| 100 | depends_on: [hub] |
| 101 | |
| 102 | volumes: |
| 103 | hub-state: |