Files
cloudflare/cloudflare-setup.md
2026-03-29 14:49:10 +00:00

166 lines
4.5 KiB
Markdown

# Cloudflare Load Balancer + Origin Certificate Setup
## Architecture
```
Internet
│ HTTPS (Cloudflare proxied)
Cloudflare Load Balancer ──health check: /v1/health──► Server 1 (Primary)
└──► Server 2 (Secondary)
Both servers: Traefik → Appwrite
```
---
## 1. Cloudflare SSL/TLS Mode
Dashboard → your domain → **SSL/TLS → Overview**
Set mode to: **Full**
Traefik on each server uses Let's Encrypt automatically (same as your current
setup). Cloudflare "Full" mode accepts these valid LE certificates.
No manual certificate management needed.
---
## 3. Create the Load Balancer
Requires Cloudflare **Pro** plan or higher (Load Balancing is a paid add-on).
### Create Origin Pool — Pool 1 (Server 1)
Dashboard → **Traffic → Load Balancing → Manage Pools → Create Pool**
| Field | Value |
|---|---|
| Pool name | `appwrite-node1` |
| Origin Address | `<Server 1 IP>` |
| Weight | 1 |
| Health Check | (create new, see below) |
### Create Origin Pool — Pool 2 (Server 2)
| Field | Value |
|---|---|
| Pool name | `appwrite-node2` |
| Origin Address | `<Server 2 IP>` |
| Weight | 1 |
| Health Check | same health check |
### Health Check Configuration
| Field | Value |
|---|---|
| Name | `appwrite-health` |
| Monitor Type | HTTPS |
| Path | `/v1/health` |
| Port | 443 |
| Interval | 60 seconds |
| Retries | 2 |
| Expected status codes | 200 |
### Create Load Balancer
Dashboard → **Traffic → Load Balancing → Create Load Balancer**
| Field | Value |
|---|---|
| Hostname | `hostsuite.teamhup.com` |
| Fallback Pool | `appwrite-node1` |
| Traffic Steering | **Random** (both servers active simultaneously) |
Add both pools. With Random steering:
- Both servers receive traffic normally
- If one fails health checks, all traffic goes to the healthy one automatically
---
## 4. WebSocket / Realtime Considerations
Appwrite realtime uses WebSockets (`/v1/realtime`).
Cloudflare supports WebSockets by default on proxied records — no extra config needed.
However, if a user's WebSocket connection is on Server 1 and the next HTTP
request goes to Server 2, that's fine — WebSocket sessions are stateless
(backed by Redis). No sticky sessions needed.
---
## 5. Firewall Rules on Both Servers
Allow inbound traffic **only from Cloudflare IP ranges** on ports 80 and 443.
This prevents direct access bypassing Cloudflare.
```bash
# Get current Cloudflare IPs
# IPv4: https://www.cloudflare.com/ips-v4
# IPv6: https://www.cloudflare.com/ips-v6
# Example with ufw:
ufw default deny incoming
ufw allow ssh
# Allow Cloudflare IPv4 ranges (update these periodically)
for ip in \
173.245.48.0/20 \
103.21.244.0/22 \
103.22.200.0/22 \
103.31.4.0/22 \
141.101.64.0/18 \
108.162.192.0/18 \
190.93.240.0/20 \
188.114.96.0/20 \
197.234.240.0/22 \
198.41.128.0/17 \
162.158.0.0/15 \
104.16.0.0/13 \
104.24.0.0/14 \
172.64.0.0/13 \
131.0.72.0/22; do
ufw allow from $ip to any port 80,443 proto tcp
done
ufw enable
```
---
## 6. Deployment Checklist
### On current server (before cutover)
- [ ] Fill in `MANAGED_DB_HOST`, `MANAGED_DB_USER`, `MANAGED_DB_PASS` in `migrate.sh`
- [ ] Stop Appwrite: `docker compose down`
- [ ] Run migration: `./migrate.sh`
- [ ] Verify managed DB has all tables and S3 has all files
### On Server 1 (Primary)
- [ ] Copy project files: `compose-node1.yml`, `.env.ha` (rename to `.env`), `certs/`
- [ ] Fill in `CHANGE_ME` values in `.env`
- [ ] Create `traefik-tls.yml` in config volume (see section 1)
- [ ] Install Cloudflare Origin Certificate in `certs/`
- [ ] `docker compose -f compose-node1.yml up -d`
- [ ] Verify: `curl -k https://localhost/v1/health`
### On Server 2 (Secondary)
- [ ] Copy same files: `compose-node2.yml`, `.env` (identical to Server 1), `certs/`
- [ ] `docker compose -f compose-node2.yml up -d`
- [ ] Verify: `curl -k https://localhost/v1/health`
### Cloudflare
- [ ] Create origin pools pointing to both server IPs
- [ ] Create health check on `/v1/health`
- [ ] Create load balancer for `hostsuite.teamhup.com`
- [ ] Set SSL mode to Full (strict)
- [ ] Test failover by stopping one server and confirming traffic continues
---
## 7. DNS Update
Once the load balancer is created, Cloudflare manages the DNS automatically
(the LB hostname replaces the A record). You don't need to manually update DNS.
If you previously had `hostsuite.teamhup.com` as an A record pointing to
`51.38.129.81`, the load balancer creation will replace it.