mirror of
https://gitverse.ru/kpa39l/xmpp-server-prosody.git
synced 2026-09-29 09:45:02 +00:00
Initial commit: Hermes skill xmpp-server-prosody
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Docker IP shift: nginx stale upstream → WS 502 → Converse spinner
|
||||
|
||||
Symptom (2026-08-30, chat.nixg.ru): page loads fine, the login form flashes briefly,
|
||||
then Converse shows only the pulsing white "connecting" circle forever. No config
|
||||
change was made — the break appeared after container recreation.
|
||||
|
||||
## Root cause
|
||||
|
||||
`icq-webchat`'s nginx resolves `proxy_pass http://prosody:5280` ONCE at config load and
|
||||
caches the IP for the life of the process. Docker bridge IPs are assigned at container
|
||||
creation; after `docker compose up` recreates containers (or adds a service) any
|
||||
container can move to a different IP. In this incident:
|
||||
|
||||
- webchat started 42h ago → cached the OLD mapping (prosody = 172.27.0.2)
|
||||
- prosody recreated 26h ago, slidgram created 22h ago → IPs shifted
|
||||
- new mapping: slidgram = 172.27.0.2, webchat = 172.27.0.3, prosody = 172.27.0.4
|
||||
|
||||
Every `/xmpp-websocket` request was proxied to Slidge's port 5280 (closed) →
|
||||
Connection refused → 502 → client never connects → spinner forever.
|
||||
|
||||
## Diagnostic trail (fast)
|
||||
|
||||
```bash
|
||||
docker logs icq-webchat --tail 40 | grep -E 'xmpp-websocket|refused'
|
||||
# → connect() failed (111: Connection refused) while connecting to upstream
|
||||
# upstream: "http://172.27.0.2:5280/xmpp-websocket" ← STALE IP in the error line
|
||||
docker compose ps --format '{{.Name}}\t{{.Status}}' # "Up X hours" reveals who was recreated
|
||||
# get ACTUAL container IPs on the compose network:
|
||||
docker network inspect icq_default --format '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}'
|
||||
```
|
||||
|
||||
Compare the upstream IP in the nginx error with the current IP of `prosody`: mismatch =
|
||||
stale DNS cache. Note: `docker logs icq-prosody` can show 0 lines because Prosody logs
|
||||
to the mounted volume — read `/opt/icq/logs/prosody.log` instead (it is the live log,
|
||||
debug-level, presence/roster traffic from the Telegram bridge is visible there).
|
||||
|
||||
## Fix
|
||||
|
||||
```bash
|
||||
cd /opt/icq && docker compose restart webchat # nginx re-resolves "prosody" → new IP
|
||||
```
|
||||
|
||||
Verify: `docker logs icq-webchat --since 2m | grep -cE '502|refused'` → 0. The user must
|
||||
F5 the tab — an already-open tab stuck on the spinner does NOT auto-reconnect.
|
||||
|
||||
## Permanent hardening (avoid recurrence)
|
||||
|
||||
In `webchat/nginx.conf`, force per-request DNS via Docker's embedded resolver + a
|
||||
variable in `proxy_pass` (the documented nginx pattern: a static hostname in proxy_pass
|
||||
is resolved only at config load; a variable makes nginx consult the resolver per request):
|
||||
|
||||
```nginx
|
||||
location /xmpp-websocket {
|
||||
resolver 127.0.0.11 valid=30s; # Docker embedded DNS, re-resolve every 30s
|
||||
set $prosody prosody:5280;
|
||||
proxy_pass http://$prosody/xmpp-websocket;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_read_timeout 3600s;
|
||||
proxy_send_timeout 3600s;
|
||||
}
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- Blank page (NOTHING renders, ESM `import.meta` SyntaxError) → `conversejs-blank-page-and-auth-testing.md`
|
||||
- Caddy bind-mount inode trap (edit silently ignored) → `webchat-conversejs-and-caddy-trap.md`
|
||||
- This is the same class as any nginx-in-Docker stale-upstream issue; the tell is the IP
|
||||
in the 502 line belonging to a different container than the one named in proxy_pass.
|
||||
Reference in New Issue
Block a user