diff --git a/DEPLOY.md b/DEPLOY.md index a43b223..a2a6673 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -7,22 +7,25 @@ TLS for `hamkadr.ir` and reverse-proxies to the app. ## Architecture & open ports ``` -Internet ──443/80──► nginx (host, existing) ──► 127.0.0.1:2569 ──► hamkadr_api (container :8080) - │ internal docker net - ▼ - hamkadr_db (postgres, no host port) +Internet ─443/80─► central nginx (container) ─► http://171.22.25.73:2569 ─► hamkadr_api (container :8080) + (nexus/mirror/gitea/meezi…) host-published port │ internal docker net + ▼ + hamkadr_db (postgres, no host port) ``` +Matches the existing soroush pattern: the **containerized** central nginx reaches each app via the +**host IP + published port** (`171.22.25.73:`), not localhost. So hamkadr publishes `2569` on +the host (like meezi 5080, draletaha 5010…). + | Port | Open? | Purpose | |------|-------|---------| | 22 | ✅ (ideally IP-restricted) | SSH | -| 80 | ✅ | HTTP → 443 redirect + Let's Encrypt ACME | -| 443 | ✅ | HTTPS `hamkadr.ir` | -| 2569 | ❌ host-localhost only | app, reached only by nginx | +| 80 / 443 | ✅ (already open) | central nginx — serves `hamkadr.ir` too | +| 2569 | host-published | app; only nginx proxies to it. Optionally firewall to the nginx host. | | 5432 | ❌ internal docker net only | Postgres — never published | -`ufw` should be exactly: `allow 22, 80, 443`. Nothing else. (80/443 are already open since nginx -serves git./mirror. — no firewall change needed.) +No firewall change needed for 80/443 (nginx already serves git./mirror./meezi). 2569 is published +on the host like the other apps. ## Files in this repo @@ -30,7 +33,7 @@ serves git./mirror. — no firewall change needed.) |------|------| | `Dockerfile` | multi-stage build, images + NuGet via `mirror.soroushasadi.com` | | `nuget.docker.config` | NuGet → Nexus `nuget-group` | -| `docker-compose.yml` | production stack: `api` (127.0.0.1:${HOST_PORT}) + `db` (internal) + named volume | +| `docker-compose.yml` | production stack: `api` (host :${HOST_PORT}) + `db` (internal) + named volume | | `docker-compose.dev.yml` | local-dev Postgres only (host 5433) for `dotnet run` | | `.gitea/workflows/ci-cd.yml` | build job + self-hosted deploy (backup → rollback tag → recreate → health-wait) | | `deploy/nginx-hamkadr.ir.conf` | nginx vhost for hamkadr.ir | @@ -38,10 +41,10 @@ serves git./mirror. — no firewall change needed.) ## One-time setup ### 1. DNS -A records → server IP: +A records → 171.22.25.73: ``` -hamkadr.ir A -www.hamkadr.ir A +hamkadr.ir A 171.22.25.73 +www.hamkadr.ir A 171.22.25.73 ``` ### 2. Gitea runner @@ -74,13 +77,22 @@ ADMIN_PHONE=09XXXXXXXXX > `ASPNETCORE_ENVIRONMENT=Production` is set by the compose file ⇒ only **reference data** > (roles/cities/districts) is seeded — no demo facilities/shifts. -### 4. nginx vhost + TLS -```bash -sudo cp deploy/nginx-hamkadr.ir.conf /etc/nginx/sites-available/hamkadr.ir -sudo ln -s /etc/nginx/sites-available/hamkadr.ir /etc/nginx/sites-enabled/ -sudo nginx -t && sudo systemctl reload nginx -sudo certbot --nginx -d hamkadr.ir -d www.hamkadr.ir -``` +### 4. TLS cert + nginx vhost +Your central nginx is a **single monolithic `nginx.conf`** with **manually-placed certs** (no +certbot). Match that: + +1. Put the hamkadr.ir cert where nginx expects (same convention as your other domains): + ``` + /etc/ssl/hamkadr/fullchain.pem + /etc/ssl/hamkadr/privateKey.pem + ``` +2. Paste the two `server { }` blocks from `deploy/nginx-hamkadr.ir.conf` **into the `http { }` + block** of your central nginx.conf (next to meezi/draletaha). They proxy to + `http://171.22.25.73:2569` and reuse the global `$connection_upgrade` map. +3. Reload: + ```bash + nginx -t && nginx -s reload # or: docker exec nginx -s reload + ``` ### 5. First deploy ```bash diff --git a/deploy/nginx-hamkadr.ir.conf b/deploy/nginx-hamkadr.ir.conf index 4eb544b..33d2f69 100644 --- a/deploy/nginx-hamkadr.ir.conf +++ b/deploy/nginx-hamkadr.ir.conf @@ -1,25 +1,38 @@ -# hamkadr.ir reverse-proxy vhost for the EXISTING nginx on the server. -# Install: -# sudo cp deploy/nginx-hamkadr.ir.conf /etc/nginx/sites-available/hamkadr.ir -# sudo ln -s /etc/nginx/sites-available/hamkadr.ir /etc/nginx/sites-enabled/ -# sudo nginx -t && sudo systemctl reload nginx -# sudo certbot --nginx -d hamkadr.ir -d www.hamkadr.ir # adds the :443 server + HTTP→HTTPS redirect +# ============================================================================ +# hamkadr.ir — paste these two server{} blocks INTO the http { } block of your +# central nginx.conf (the one with nexus/mirror/gitea/meezi), then: +# nginx -t && nginx -s reload (or: docker exec nginx -s reload) # -# The port below MUST match HOST_PORT in the Gitea ENV_FILE secret (default 2569). +# Prereqs (match your existing pattern): +# • TLS cert placed at /etc/ssl/hamkadr/fullchain.pem + privateKey.pem (manual, like your others) +# • hamkadr.ir + www.hamkadr.ir A records → 171.22.25.73 +# • the app published on the host at :2569 (docker-compose.yml) — nginx reaches it via the host IP, +# exactly like meezi (5080), draletaha (5010), etc. $connection_upgrade map is already defined globally. +# ============================================================================ server { listen 80; - listen [::]:80; server_name hamkadr.ir www.hamkadr.ir; + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl; + http2 on; + server_name hamkadr.ir www.hamkadr.ir; + client_max_body_size 25m; + + ssl_certificate /etc/ssl/hamkadr/fullchain.pem; + ssl_certificate_key /etc/ssl/hamkadr/privateKey.pem; - # The app binds 127.0.0.1:2569 (docker-compose.yml, service "api") — never exposed publicly. location / { - proxy_pass http://127.0.0.1:2569; + proxy_pass http://171.22.25.73:2569; proxy_http_version 1.1; 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 $scheme; # app's ForwardedHeaders reads this → knows it's HTTPS - proxy_read_timeout 60s; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; } } diff --git a/docker-compose.yml b/docker-compose.yml index 8e1d452..e219eed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,9 @@ services: db: condition: service_healthy ports: - - "127.0.0.1:${HOST_PORT:-2569}:8080" # localhost-only; nginx proxies hamkadr.ir → here + # Published on the host so the (containerized) central nginx can reach it at + # http://171.22.25.73:${HOST_PORT} — same pattern as the other soroush apps. + - "${HOST_PORT:-2569}:8080" environment: ASPNETCORE_ENVIRONMENT: "Production" ASPNETCORE_URLS: "http://+:8080"