Cloudflare → nginx-lb (V1) → 5 internal servers — production reference drawing. Main conclusions and points to be addressed: section 03. Details of each floor:Deep Dive infrastructure.
HTTP :80 origin-pull — see "Realip / Cloudflare trust" card below
Operating notes:V2 and V3 share the same default hostnameubuntu-8gb-ash-1(Hetzner is named after the spec, not the unique identifier).Do not use the hostname to identify the server when SSH — only the IP can be sure: V2 = 10.0.0.4 / 178.156.166.189, V3 = 10.0.0.2 / 178.156.211.239.
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
… (15 Cloudflare CIDR bands) …
set_real_ip_from 131.0.72.0/22;
real_ip_header CF-Connecting-IP;
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 $http_x_forwarded_proto;
proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
proxy_set_header CF-Ray $http_cf_ray;
upstream backend {
least_conn;
server 10.0.0.5:3001 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.5:3002 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.5:3003 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.5:3004 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.4:3001 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.4:3002 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.4:3003 weight=1 max_fails=3 fail_timeout=30s;
server 10.0.0.4:3004 weight=1 max_fails=3 fail_timeout=30s;
}
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
worker_processes auto;
worker_connections 1024;
keepalive_timeout 65;
gzip on;
gzip_comp_level 6;
include conf.d/*.conf;
image: nginx:alpine
container_name: nginx-lb
restart: always
network_mode: host
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
network_mode: hostThis is the reason why nginx can directly call 10.0.0.x without having to declare a separate Docker network - and also the reason why if running 2 versions on 2 servers, they will NOT conflict with each other's ports (each is independent on its own host).firewall-ssh22/tcp ← Any IPv4, Any IPv6
icmp ← Any IPv4, Any IPv6
80/tcp ← 5/15 Cloudflare strips
(missing 10 strips nginx is trusting)
443/tcp ← 15/15 Cloudflare strips
(nginx not listening 443)
set_real_ip_from(filtering at the application layer). The two levels are different at port 80: the firewall is tighter than nginx (5 bands compared to 15), so it can mistakenly block real Cloudflare traffic.firewall-sshis the only firewall in the project and there are no rules for 6379/5432/9200/… — default-deny data ports from the Internet.Point to be handled (Hetzner Firewallfirewall-ssh, applies to all 5 servers):rule :80 indicates whitelist5/15 Cloudflare bandswhile nginx believes 15 bands passedset_real_ip_from— real requests via PoP belonging to 10 missing bands are DROP before reaching nginx (edit on Console, step 0A of conversion plan); rule :22 opens to the entire Internet (step 0B); rule :443 has enough 15/15 ranges even if nginx doesn'tlisten 443. See card ⑦ above andrisks #13–14 in infrastructure-deep-dive.html.
Main conclusion: nginx-lb only on V1— SPOF of the entire system ·frontend is not in 5 servers: 6 site (client, shop, agent, super-agent, admin, cashier) hosting onCloudflare Pages· data ports (6379/5432/9200/…) default-deny from the Internet · Dozzle (4/4) and RedisInsight reportunhealthyjust the healthcheck image is wrong — not a problem. Processing plan:comparison-and-migration-plan.html· target architecture:target-system.html.