Messages went out locally but not from the server. The relay gateway
identifies the sending server by `host`, and the owner's ruling (D26)
is that this is the server's IP. With SMS_RELAY_HOST unset, the driver
sent the machine's first external IPv4. On the bare PHP server that was
the real IP; inside the API container it is the container's (172.x).
Reproduced: a container on this machine reports 172.17.0.3.
- relay.driver: when SMS_RELAY_HOST is unset and the machine address is
private (RFC 1918, CGNAT, link-local), the public IPv4 is looked up
once (ipify, ifconfig.me, icanhazip in turn) and cached. If every
lookup fails, it falls back to the old value. SMS_RELAY_HOST still wins.
- SmsService logs the host it will send at boot, and warns when it is
still private, so a wrong value is visible instead of silent.
- Removed a debug console.log that wrote every recipient's mobile to the
server log.
- .env.example and SERVER-SETUP-CHECKLIST: SMS_RELAY_HOST = this
server's public IP.
Tests: relay-host.spec (5). All 254 API tests pass.
اپ: پیامک کد ورود دوباره بهدرستی ارسال میشود.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>