Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
91 lines
4.2 KiB
Plaintext
91 lines
4.2 KiB
Plaintext
events {
|
||
worker_connections 1024;
|
||
}
|
||
|
||
http {
|
||
server {
|
||
listen 4848;
|
||
|
||
# envsubst from start.sh replaces FLY_MACHINE_ID only
|
||
set $machine_id "${FLY_MACHINE_ID}";
|
||
|
||
location / {
|
||
# Sticky routing for multi-machine Zero view-syncer. Clients store fly_machine_id (which
|
||
# Fly machine they last used). Same idea as Fly replay_cache in flyio-view-syncer. Goal:
|
||
# keep a session on one box for warm Zero state (see zero.rocicorp.dev self-host sticky sessions).
|
||
#
|
||
# $machine_id = this container (FLY_MACHINE_ID). The cookie may name another machine.
|
||
# Only the proxy_pass branch below sets Set-Cookie; a 307 fly-replay response does not, so
|
||
# fixing a bad cookie always ends with a successful proxy response.
|
||
#
|
||
# Paths (nginx picks the first that applies):
|
||
#
|
||
# A — No cookie, or cookie already matches $machine_id: do not fly-replay. Proxy to Zero on
|
||
# :4849 and set fly_machine_id to this machine (first visit, refresh, or already correct).
|
||
#
|
||
# B — Cookie names a different machine, first hop (no Fly-Replay-Src), Fly did not already
|
||
# signal Fly-Preferred-Instance-Unavailable: return 307 + fly-replay prefer_instance=<cookie>.
|
||
# Fly’s edge tries to route the request to that machine if it exists and can take load.
|
||
# If that machine is gone, busy (hard_limit), etc., Fly may deliver the request here instead
|
||
# and set Fly-Preferred-Instance-Unavailable (see Fly fly-replay docs).
|
||
#
|
||
# C — Cookie names a different machine but Fly-Replay-Src is present: Fly already replayed
|
||
# once (e.g. previous hop asked for the cookie machine and it was unreachable). Do not
|
||
# return another 307—proxy here and rewrite the cookie to $machine_id.
|
||
#
|
||
# D — Cookie names a different machine and Fly-Preferred-Instance-Unavailable is present:
|
||
# Fly already decided prefer_instance could not be satisfied for that ID. Do not return
|
||
# another 307 (would loop). Proxy here and rewrite the cookie. Header is forgeable in
|
||
# theory; low impact (stickiness only); typical browsers hit Fly first.
|
||
set $check_replay "";
|
||
if ($cookie_fly_machine_id != "") {
|
||
set $check_replay "has_cookie";
|
||
}
|
||
if ($cookie_fly_machine_id != $machine_id) {
|
||
set $check_replay "${check_replay}_different";
|
||
}
|
||
if ($http_fly_replay_src != "") {
|
||
set $check_replay "${check_replay}_replayed";
|
||
}
|
||
|
||
set $prefer_instance_unavailable "";
|
||
if ($http_fly_preferred_instance_unavailable != "") {
|
||
set $prefer_instance_unavailable "1";
|
||
}
|
||
|
||
set $issue_fly_replay "0";
|
||
if ($check_replay = "has_cookie_different") {
|
||
set $issue_fly_replay "1";
|
||
}
|
||
if ($prefer_instance_unavailable = "1") {
|
||
set $issue_fly_replay "0";
|
||
}
|
||
if ($issue_fly_replay = "1") {
|
||
add_header fly-replay "prefer_instance=$cookie_fly_machine_id" always;
|
||
return 307;
|
||
}
|
||
|
||
# Zero (upstream); sticky cookie refreshed below
|
||
proxy_pass http://127.0.0.1:4849;
|
||
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-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
# zero-cache can send large headers
|
||
proxy_buffer_size 64k;
|
||
proxy_buffers 8 64k;
|
||
|
||
# Long-lived sync / WebSocket upstream
|
||
proxy_read_timeout 86400;
|
||
proxy_send_timeout 86400;
|
||
|
||
# Pin this machine; SameSite=None for cross-origin (e.g. tldraw.com → fly.dev)
|
||
add_header Set-Cookie "fly_machine_id=$machine_id; Path=/; Max-Age=3600; SameSite=None; Secure" always;
|
||
}
|
||
}
|
||
}
|