fix: map Docker nginx to port 8080 to avoid conflict with host reverse proxy
The base docker-compose.yml maps nginx to 80:80, which conflicts with the host-level nginx that handles SSL termination on production servers. The production overlay now explicitly maps to 8080:80 so the host proxy can forward to localhost:8080. Updated DEPLOYMENT.md with host reverse proxy setup instructions and corrected architecture diagrams. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,10 +10,13 @@
|
||||
# - Restart policies for reliability
|
||||
#
|
||||
# SSL/TLS is handled at the host level (e.g., host nginx + certbot).
|
||||
# The Docker nginx container listens on port 80 only.
|
||||
# The Docker nginx container listens internally on port 80, mapped to
|
||||
# host port 8080 so it doesn't conflict with the host reverse proxy.
|
||||
|
||||
services:
|
||||
nginx:
|
||||
ports:
|
||||
- "8080:80" # override: avoid conflict with host nginx
|
||||
volumes:
|
||||
- ./nginx/production.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -171,14 +171,54 @@ nano .env
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build
|
||||
```
|
||||
|
||||
To add SSL on top of the production stack:
|
||||
> **Port mapping:** The production overlay maps the Docker nginx to **host
|
||||
> port 8080** (not 80) so it doesn't conflict with a host-level reverse
|
||||
> proxy. If you're NOT using a host reverse proxy, you can override this:
|
||||
> ```bash
|
||||
> # Direct access on port 80 (no host reverse proxy)
|
||||
> docker compose -f docker-compose.yml -f docker-compose.prod.yml \
|
||||
> up -d --build --scale nginx=0
|
||||
> # Then manually: docker compose ... run -d -p 80:80 nginx
|
||||
> ```
|
||||
|
||||
### Host reverse proxy setup (recommended)
|
||||
|
||||
In production, SSL termination is typically handled by a **host-level nginx**
|
||||
(or Caddy, Traefik, etc.) that proxies to the Docker stack on port 8080:
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/sites-available/app.yourdomain.com
|
||||
server {
|
||||
listen 80;
|
||||
server_name app.yourdomain.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name app.yourdomain.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/app.yourdomain.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/app.yourdomain.com/privkey.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
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;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then enable and reload:
|
||||
```bash
|
||||
docker compose \
|
||||
-f docker-compose.yml \
|
||||
-f docker-compose.prod.yml \
|
||||
-f docker-compose.ssl.yml \
|
||||
up -d --build
|
||||
sudo ln -s /etc/nginx/sites-available/app.yourdomain.com /etc/nginx/sites-enabled/
|
||||
sudo certbot --nginx -d app.yourdomain.com # if using certbot on host
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
> **Tip:** Create a shell alias to avoid typing the compose files every time:
|
||||
@@ -690,8 +730,9 @@ docker compose logs -f nginx # nginx access/error log
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
Development:
|
||||
┌──────────────────┐
|
||||
Browser ─────────► │ nginx :80/:443 │
|
||||
Browser ─────────► │ nginx :80 │
|
||||
└────────┬─────────┘
|
||||
┌──────────┴──────────┐
|
||||
▼ ▼
|
||||
@@ -701,10 +742,31 @@ docker compose logs -f nginx # nginx access/error log
|
||||
└──────┬───────┘ └──────────────┘
|
||||
┌────┴────┐
|
||||
▼ ▼
|
||||
┌────────────┐ ┌───────────┐ ┌───────────┐
|
||||
│postgres:5432│ │redis :6379│ │ certbot │
|
||||
│ (PG 15) │ │ (Redis 7) │ │ (renewal) │
|
||||
└────────────┘ └───────────┘ └───────────┘
|
||||
┌────────────┐ ┌───────────┐
|
||||
│postgres:5432│ │redis :6379│
|
||||
│ (PG 15) │ │ (Redis 7) │
|
||||
└────────────┘ └───────────┘
|
||||
|
||||
Production (with host reverse proxy):
|
||||
┌──────────────────────┐
|
||||
Browser ─────────► │ Host nginx :80/:443 │ ← SSL termination
|
||||
└────────┬─────────────┘
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ Docker nginx:8080│ ← proxy to services
|
||||
└────────┬─────────┘
|
||||
┌──────────┴──────────┐
|
||||
▼ ▼
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ backend :3000│ │frontend :3001│
|
||||
│ (compiled) │ │ (static nginx)│
|
||||
└──────┬───────┘ └──────────────┘
|
||||
┌────┴────┐
|
||||
▼ ▼
|
||||
┌────────────┐ ┌───────────┐
|
||||
│postgres:5432│ │redis :6379│
|
||||
│ (PG 15) │ │ (Redis 7) │
|
||||
└────────────┘ └───────────┘
|
||||
```
|
||||
|
||||
**Multi-tenant isolation:** Each HOA organization gets its own PostgreSQL
|
||||
|
||||
Reference in New Issue
Block a user