VPS Coolify Realtime Modes
This page explains exactly how realtime works for:
CLOSE_COOLIFY_REALTIME_PORTS=falseCLOSE_COOLIFY_REALTIME_PORTS=true
It also includes operational update procedures and a dedicated script: scripts/update-realtime-mode.sh.
Realtime variables in scope
CLOSE_COOLIFY_REALTIME_PORTSfalse: keep public publish path for6001/6002true: block direct public6001/6002and enforce domain-based realtime path
COOLIFY_REALTIME_DOMAIN- used as
PUSHER_HOSTwhen set - optional in closed mode; if empty, bootstrap uses
COOLIFY_PUBLIC_DOMAINas realtime host
- used as
Mode A: CLOSE_COOLIFY_REALTIME_PORTS=false
Behavior
Bootstrap enforces:
- removes
DOCKER-USERdrop guards for realtime ports6001/6002 - if
COOLIFY_REALTIME_DOMAINis set:- writes
PUSHER_HOST=<domain> - writes
PUSHER_PORT=443 - writes
PUSHER_SCHEME=https
- writes
- if
COOLIFY_REALTIME_DOMAINis empty:- removes
PUSHER_HOST,PUSHER_PORT,PUSHER_SCHEME
- removes
Result:
- direct public access to
6001/6002may exist via Docker publish rules - app-level routing can still point to domain
443when domain is set
Graph (descriptive)
flowchart TD
A["Browser"] --> B["Coolify UI/API"]
B --> C["PUSHER_* config"]
C --> D{"Realtime domain set?"}
D -->|No| E["Direct websocket path to 6001/6002"]
D -->|Yes| F["Domain path on 443"]
E --> G["Soketi realtime container"]
F --> G
H["DOCKER-USER guards"] --> I["Removed in this mode"]
Advantages
- simplest setup for initial bring-up
- less dependency on reverse proxy/domain readiness
- faster troubleshooting for raw websocket connectivity
Risks
6001/6002can be internet-reachable if Docker publishes them- larger attack surface compared to closed mode
- easy to assume UFW blocks these ports while Docker bypasses UFW paths
Example
CLOSE_COOLIFY_REALTIME_PORTS=false
COOLIFY_REALTIME_DOMAIN=
or
CLOSE_COOLIFY_REALTIME_PORTS=false
COOLIFY_REALTIME_DOMAIN=realtime.example.com
Mode B: CLOSE_COOLIFY_REALTIME_PORTS=true
Behavior
Bootstrap enforces:
- resolves effective realtime domain:
COOLIFY_REALTIME_DOMAINwhen set (non-placeholder)- otherwise
COOLIFY_PUBLIC_DOMAIN
- writes
PUSHER_HOST=<effective-domain>,PUSHER_PORT=443,PUSHER_SCHEME=https - adds
DOCKER-USERguards to drop public forwarded traffic to6001/6002with localhost/private network allow exceptions
Result:
- direct public
6001/6002ingress is blocked byDOCKER-USER - realtime must flow through domain/reverse-proxy path on
443
Graph (descriptive)
flowchart TD
A["Browser"] --> B["Realtime domain on 443"]
B --> C["Reverse proxy / TLS termination"]
C --> D["Coolify realtime service"]
E["Direct public 6001/6002 traffic"] --> F["DOCKER-USER DROP"]
Advantages
- reduced external attack surface
- deterministic ingress path through
80/443 - easier policy enforcement and security review
Risks
- depends on correct DNS and reverse-proxy readiness
- broken TLS/domain config can cause realtime failures
- stricter mode; misconfigured domain causes immediate service issues
Example
CLOSE_COOLIFY_REALTIME_PORTS=true
COOLIFY_REALTIME_DOMAIN=realtime.example.com
or reuse the same domain:
CLOSE_COOLIFY_REALTIME_PORTS=true
COOLIFY_REALTIME_DOMAIN=
COOLIFY_PUBLIC_DOMAIN=hub.example.com
Update procedure for each mode
Use the dedicated script on the VPS:
scripts/update-realtime-mode.sh
It:
- updates server
bootstrap.env - validates mode/domain combination
- runs bootstrap replay to apply policy (unless
--no-replay)
Switch to public mode (domain cleared)
sudo bash /opt/vps-coolify-bootstrap/scripts/update-realtime-mode.sh \
--mode public \
--clear-domain
Switch to public mode (keep domain routing)
sudo bash /opt/vps-coolify-bootstrap/scripts/update-realtime-mode.sh \
--mode public \
--domain realtime.example.com
Switch to closed mode
sudo bash /opt/vps-coolify-bootstrap/scripts/update-realtime-mode.sh \
--mode closed \
--domain realtime.example.com
Switch to closed mode (reuse COOLIFY_PUBLIC_DOMAIN)
sudo bash /opt/vps-coolify-bootstrap/scripts/update-realtime-mode.sh \
--mode closed
Update only env (apply later)
sudo bash /opt/vps-coolify-bootstrap/scripts/update-realtime-mode.sh \
--mode closed \
--domain realtime.example.com \
--no-replay
Then apply later:
sudo bash /opt/vps-coolify-bootstrap/scripts/bootstrap-host.sh /etc/vps-coolify-bootstrap/bootstrap.env
Post-update verification
sudo grep -nE '^CLOSE_COOLIFY_REALTIME_PORTS=|^COOLIFY_REALTIME_DOMAIN=' /etc/vps-coolify-bootstrap/bootstrap.env
sudo grep -nE '^PUSHER_(HOST|PORT|SCHEME)=' /data/coolify/source/.env
sudo iptables -S DOCKER-USER | grep -E '6001|6002' || true
sudo ip6tables -S DOCKER-USER 2>/dev/null | grep -E '6001|6002' || true
sudo ss -lntp | grep -E ':(80|443|8000|6001|6002)\b' || true
sudo bash /opt/vps-coolify-bootstrap/scripts/verify-bootstrap-state.sh /etc/vps-coolify-bootstrap/bootstrap.env
Interpretation:
- closed mode expected:
6001/6002guards present - public mode expected:
6001/6002guards removed; published ports may exist
Back to Docs Home