Skip to content

Commit 33acf6a

Browse files
hyperpolymathclaude
andcommitted
feat(container): add Fly.io multi-region seed node configs + deploy script
Four regional fly.toml configs (eu/de/us/ap) and deploy-seeds.sh for Umoja federation seed nodes. Extends the seed infrastructure started in the previous session. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 7ef4b1a commit 33acf6a

5 files changed

Lines changed: 310 additions & 0 deletions

File tree

container/fly/deploy-seeds.sh

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bash
2+
# SPDX-License-Identifier: PMPL-1.0-or-later
3+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
4+
#
5+
# Deploy (or re-deploy) all 4 Umoja seed nodes to fly.io.
6+
# Run from the boj-server repo root:
7+
# bash container/fly/deploy-seeds.sh
8+
#
9+
# Prerequisites: fly CLI authenticated (fly auth whoami)
10+
11+
set -euo pipefail
12+
13+
REPO_ROOT="$(git rev-parse --show-toplevel)"
14+
cd "$REPO_ROOT"
15+
16+
declare -A NODES=(
17+
[eu]="lhr"
18+
[de]="fra"
19+
[us]="iad"
20+
[ap]="syd"
21+
)
22+
23+
echo "=== BoJ Seed Node Deployment ==="
24+
echo "Authenticated as: $(fly auth whoami)"
25+
echo
26+
27+
for region_code in eu de us ap; do
28+
app="boj-seed-${region_code}"
29+
fly_region="${NODES[$region_code]}"
30+
config="container/fly/fly-${region_code}.toml"
31+
32+
echo "--- ${app} (${fly_region}) ---"
33+
34+
# Create app if it doesn't exist
35+
if ! fly apps list | grep -q "^[[:space:]]*${app}"; then
36+
echo " Creating app ${app}..."
37+
fly apps create "${app}" --org personal
38+
else
39+
echo " App ${app} already exists."
40+
fi
41+
42+
# Create volume if none exist for this app
43+
vol_count=$(fly volumes list --app "${app}" 2>/dev/null | grep -c "boj_data" || true)
44+
if [ "${vol_count}" -eq 0 ]; then
45+
echo " Creating 1 GB volume boj_data in ${fly_region}..."
46+
fly volumes create boj_data \
47+
--app "${app}" \
48+
--region "${fly_region}" \
49+
--size 1 \
50+
--yes
51+
else
52+
echo " Volume already exists (${vol_count} found)."
53+
fi
54+
55+
echo " Deploying ${app}..."
56+
fly deploy \
57+
--app "${app}" \
58+
--config "${config}" \
59+
--dockerfile container/Containerfile \
60+
--remote-only \
61+
--wait-timeout 900
62+
63+
echo " Done. Health: https://${app}.fly.dev/health"
64+
echo
65+
done
66+
67+
echo "=== All 4 seed nodes deployed ==="
68+
echo
69+
echo "REST endpoints:"
70+
for region_code in eu de us ap; do
71+
echo " https://boj-seed-${region_code}.fly.dev/health"
72+
done
73+
echo
74+
echo "Update container/seed-nodes.toml and compose.prod.yaml with .fly.dev hostnames."

container/fly/fly-ap.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# BoJ Seed Node — Asia-Pacific (Sydney, syd)
5+
# Deploy: fly deploy --config container/fly/fly-ap.toml (from repo root)
6+
7+
app = "boj-seed-ap"
8+
primary_region = "syd"
9+
10+
[env]
11+
APP_HOST = "0.0.0.0"
12+
APP_PORT = "7700"
13+
APP_DATA_DIR = "/data"
14+
APP_LOG_FORMAT = "json"
15+
BOJ_QUIC = "1"
16+
BOJ_FEDERATION_PORT = "9999"
17+
BOJ_NODE_ID = "seed-ap-south"
18+
BOJ_SEED_NODES = "boj-seed-eu.fly.dev:9999,boj-seed-de.fly.dev:9999,boj-seed-us.fly.dev:9999,boj-seed-ap.fly.dev:9999"
19+
MIX_ENV = "prod"
20+
PORT = "7700"
21+
22+
[[mounts]]
23+
source = "boj_data"
24+
destination = "/data"
25+
26+
[[services]]
27+
internal_port = 7700
28+
protocol = "tcp"
29+
30+
[[services.ports]]
31+
handlers = ["http"]
32+
port = 80
33+
force_https = true
34+
35+
[[services.ports]]
36+
handlers = ["tls", "http"]
37+
port = 443
38+
39+
[[services.tcp_checks]]
40+
grace_period = "30s"
41+
interval = "30s"
42+
restart_limit = 0
43+
timeout = "10s"
44+
45+
[[services]]
46+
internal_port = 9999
47+
protocol = "udp"
48+
49+
[[services.ports]]
50+
port = 9999
51+
52+
[checks]
53+
[checks.health]
54+
type = "http"
55+
port = 7700
56+
method = "GET"
57+
path = "/health"
58+
interval = "30s"
59+
timeout = "10s"

container/fly/fly-de.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# BoJ Seed Node — EU Central (Frankfurt, fra)
5+
# Deploy: fly deploy --config container/fly/fly-de.toml (from repo root)
6+
7+
app = "boj-seed-de"
8+
primary_region = "fra"
9+
10+
[env]
11+
APP_HOST = "0.0.0.0"
12+
APP_PORT = "7700"
13+
APP_DATA_DIR = "/data"
14+
APP_LOG_FORMAT = "json"
15+
BOJ_QUIC = "1"
16+
BOJ_FEDERATION_PORT = "9999"
17+
BOJ_NODE_ID = "seed-eu-central"
18+
BOJ_SEED_NODES = "boj-seed-eu.fly.dev:9999,boj-seed-de.fly.dev:9999,boj-seed-us.fly.dev:9999,boj-seed-ap.fly.dev:9999"
19+
MIX_ENV = "prod"
20+
PORT = "7700"
21+
22+
[[mounts]]
23+
source = "boj_data"
24+
destination = "/data"
25+
26+
[[services]]
27+
internal_port = 7700
28+
protocol = "tcp"
29+
30+
[[services.ports]]
31+
handlers = ["http"]
32+
port = 80
33+
force_https = true
34+
35+
[[services.ports]]
36+
handlers = ["tls", "http"]
37+
port = 443
38+
39+
[[services.tcp_checks]]
40+
grace_period = "30s"
41+
interval = "30s"
42+
restart_limit = 0
43+
timeout = "10s"
44+
45+
[[services]]
46+
internal_port = 9999
47+
protocol = "udp"
48+
49+
[[services.ports]]
50+
port = 9999
51+
52+
[checks]
53+
[checks.health]
54+
type = "http"
55+
port = 7700
56+
method = "GET"
57+
path = "/health"
58+
interval = "30s"
59+
timeout = "10s"

container/fly/fly-eu.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# BoJ Seed Node — EU West (London, lhr)
5+
# Deploy: fly deploy --config container/fly/fly-eu.toml (from repo root)
6+
7+
app = "boj-seed-eu"
8+
primary_region = "lhr"
9+
10+
[env]
11+
APP_HOST = "0.0.0.0"
12+
APP_PORT = "7700"
13+
APP_DATA_DIR = "/data"
14+
APP_LOG_FORMAT = "json"
15+
BOJ_QUIC = "1"
16+
BOJ_FEDERATION_PORT = "9999"
17+
BOJ_NODE_ID = "seed-eu-west"
18+
BOJ_SEED_NODES = "boj-seed-eu.fly.dev:9999,boj-seed-de.fly.dev:9999,boj-seed-us.fly.dev:9999,boj-seed-ap.fly.dev:9999"
19+
MIX_ENV = "prod"
20+
PORT = "7700"
21+
22+
[[mounts]]
23+
source = "boj_data"
24+
destination = "/data"
25+
26+
[[services]]
27+
internal_port = 7700
28+
protocol = "tcp"
29+
30+
[[services.ports]]
31+
handlers = ["http"]
32+
port = 80
33+
force_https = true
34+
35+
[[services.ports]]
36+
handlers = ["tls", "http"]
37+
port = 443
38+
39+
[[services.tcp_checks]]
40+
grace_period = "30s"
41+
interval = "30s"
42+
restart_limit = 0
43+
timeout = "10s"
44+
45+
[[services]]
46+
internal_port = 9999
47+
protocol = "udp"
48+
49+
[[services.ports]]
50+
port = 9999
51+
52+
[checks]
53+
[checks.health]
54+
type = "http"
55+
port = 7700
56+
method = "GET"
57+
path = "/health"
58+
interval = "30s"
59+
timeout = "10s"

container/fly/fly-us.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# BoJ Seed Node — US East (Ashburn VA, iad)
5+
# Deploy: fly deploy --config container/fly/fly-us.toml (from repo root)
6+
7+
app = "boj-seed-us"
8+
primary_region = "iad"
9+
10+
[env]
11+
APP_HOST = "0.0.0.0"
12+
APP_PORT = "7700"
13+
APP_DATA_DIR = "/data"
14+
APP_LOG_FORMAT = "json"
15+
BOJ_QUIC = "1"
16+
BOJ_FEDERATION_PORT = "9999"
17+
BOJ_NODE_ID = "seed-us-east"
18+
BOJ_SEED_NODES = "boj-seed-eu.fly.dev:9999,boj-seed-de.fly.dev:9999,boj-seed-us.fly.dev:9999,boj-seed-ap.fly.dev:9999"
19+
MIX_ENV = "prod"
20+
PORT = "7700"
21+
22+
[[mounts]]
23+
source = "boj_data"
24+
destination = "/data"
25+
26+
[[services]]
27+
internal_port = 7700
28+
protocol = "tcp"
29+
30+
[[services.ports]]
31+
handlers = ["http"]
32+
port = 80
33+
force_https = true
34+
35+
[[services.ports]]
36+
handlers = ["tls", "http"]
37+
port = 443
38+
39+
[[services.tcp_checks]]
40+
grace_period = "30s"
41+
interval = "30s"
42+
restart_limit = 0
43+
timeout = "10s"
44+
45+
[[services]]
46+
internal_port = 9999
47+
protocol = "udp"
48+
49+
[[services.ports]]
50+
port = 9999
51+
52+
[checks]
53+
[checks.health]
54+
type = "http"
55+
port = 7700
56+
method = "GET"
57+
path = "/health"
58+
interval = "30s"
59+
timeout = "10s"

0 commit comments

Comments
 (0)