Files
flatrender/deploy/README.md
T
soroush.asadi 468ae2ae97
CI/CD / CI · Web (tsc) (push) Successful in 1m10s
CI/CD / Deploy · full stack (push) Successful in 3m10s
docs(deploy): fix init-script path + add stale-volume reset note
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:48:51 +03:30

92 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Deploying FlatRender (Gitea CI/CD → 171.22.25.73, behind mirror-nginx)
Push to **Gitea** triggers `.gitea/workflows/ci-cd.yml`: a frontend `tsc` check, then a
self-hosted `deploy` job that builds the whole compose stack and brings it up. The
existing central **mirror-nginx** (owns 80/443, manual TLS certs) reverse-proxies the
three public domains to FlatRender's host ports — FlatRender does **not** run Caddy here.
GitHub (`origin`) stays a backup and never deploys.
Stack: gateway · identity · content · studio (.NET/Go) · file · render · notification
(Go) · Next.js frontend · Postgres · MinIO. All package installs route through
`mirror.soroushasadi.com` (Nexus).
```
mirror-nginx (:443, /etc/ssl/flatrender)
flatrender.ir → 171.22.25.73:1600 (fr2-frontend)
api.flatrender.ir → 171.22.25.73:1605 (fr2-gateway)
storage.flatrender.ir → 171.22.25.73:1610 (fr2-minio)
```
## One-time setup (do these BEFORE the first `git push gitea master`)
1. **DNS** — this box sits BEHIND NAT: its interface IP is `171.22.25.73` (private),
public NAT IPs are `31.171.101.127/.211`, and inbound 443 normally arrives via the
edge/CDN `185.239.1.100` (same entry your other sites use, e.g. `meezi.ir`). So a new
domain must enter the SAME way the others do — either:
- register `flatrender.ir` + `api` + `storage` + `www` in that edge/CDN (origin = this
server) and point DNS there, **or**
- bypass the CDN and point DNS straight at the server's public IP (like the hokm `api`
subdomain does — "must bypass").
Pointing DNS at a random/registrar IP shows that host's default page (e.g. a "not
licensed" page), NOT FlatRender.
2. **TLS cert** — ⚠️ mirror-nginx mounts cert dirs INDIVIDUALLY, so a fresh
`/etc/ssl/flatrender/` on the host is invisible inside the container. **Nest the cert
under an already-mounted dir** (the conf references this path):
```bash
mkdir -p /etc/ssl/soroushasadi/flatrender
cp <yourcert>/fullchain.pem /etc/ssl/soroushasadi/flatrender/
cp <yourcert>/privateKey.pem /etc/ssl/soroushasadi/flatrender/
```
Cert must cover `flatrender.ir` + `api.` + `storage.` (wildcard `*.flatrender.ir` + apex, or SAN).
3. **mirror-nginx** — add the server blocks from [`mirror-nginx-flatrender.conf`](./mirror-nginx-flatrender.conf)
to the proxy's `http{}` (the host file is `/root/mirror-server/nginx/nginx.conf`), then:
`docker exec mirror-nginx nginx -t && docker exec mirror-nginx nginx -s reload`.
⚠️ If you edited the conf with `sed -i` (which swaps the file inode), the running
container keeps the old inode → `docker restart mirror-nginx` instead (~3s blip).
Verify locally (bypasses DNS): `curl -sk --resolve flatrender.ir:443:127.0.0.1 https://flatrender.ir/ | head -c 60`
must show `<html lang="fa" dir="rtl">`. (Do this after the first deploy is up, or it 502s.)
4. **ENV_FILE secret** — at `…/soroushdes/flatrender/settings/secrets`, create `ENV_FILE`
from [`ENV_FILE.production.example`](./ENV_FILE.production.example) (already filled for
flatrender.ir; generate each secret with `openssl rand -hex 32`).
5. **Gitea Actions** enabled for this repo; act_runner has the `self-hosted:host` label
(the standard box already has this). daemon.json already mirrors Docker Hub via Nexus.
## Go live
```bash
git push gitea master # triggers CI + deploy
```
Watch `https://git.soroushasadi.com/soroushdes/flatrender/actions`. First run ~1525 min
(cold Nexus cache + all images build). When the deploy is green, add/reload the nginx
blocks (step 3) and visit `https://flatrender.ir`.
## Host ports (must be free on 171.22.25.73)
`1600` frontend · `1605` gateway · `1610` MinIO · `1611` MinIO console. Postgres (5432)
and render (5010) bind to `127.0.0.1` only. Avoid `:3000` (Gitea), `:8081-8083` (Nexus),
`:1500/1505/1520` (bargevasat), `:3010/3101-3103/5080/5081` (meezi), `:3020`, `:2569`.
Change them via `FRONTEND_PORT`/`GATEWAY_PORT`/`MINIO_PORT` in the secret if any collide.
## First-run notes
- **Migrations** auto-run once via `deploy/postgres-initdb/00-init.sh` (mounted as the
whole `/docker-entrypoint-initdb.d` directory — a single-file bind mount left a stale
empty dir → "Is a directory") when the Postgres volume is first created. Later schema
changes are applied manually with `psql` (the volume persists). ⚠️ If a deploy ever
ran with a wrong/empty secret, the volume bakes the wrong password + may skip init →
`docker rm -f fr2-postgres && docker volume rm flatrender_pgdata` (only while there's
no real data) then re-run, so it re-inits with the current password + migrations.
- **Rendering** — no After Effects node on the server, so `RENDER_DEV_WORKER=false`.
Disable rendering in **Admin → فارم رندر → موتور رندر** so users see an "unavailable"
notice instead of jobs that never finish. Point real render nodes at the server later.
- **MinIO public URLs** — verify an uploaded image + a render download resolve over
`https://storage.flatrender.ir`. If not, recheck `MINIO_HOST_ENDPOINT` /
`MINIO_HOST_USE_SSL` / `NEXT_PUBLIC_MINIO_URL` in the secret and redeploy.
## Redeploy / rotate secrets
Edit `ENV_FILE` in Gitea (or push any commit) → the deploy re-runs. It backs up the DB to
`/opt/flatrender-backups/` before each deploy and never runs `docker compose down -v`.
Changing a `NEXT_PUBLIC_*` value only takes effect after the redeploy (baked at build).