194 lines
5.0 KiB
Markdown
194 lines
5.0 KiB
Markdown
# 04 — SWAG Nginx Proxy Configs (Test)
|
|
|
|
## Context
|
|
SWAG reads nginx configs from bind-mounted directories:
|
|
- `/config/nginx/proxy-confs/` → `swag/proxy-confs/` in repo, deployed to `/opt/iklimco/swag/proxy-confs/`
|
|
- `/config/nginx/site-confs/` → `swag/site-confs/` in repo, deployed to `/opt/iklimco/swag/site-confs/`
|
|
|
|
Templates use `${VAR}` placeholders processed with `envsubst` at deploy time.
|
|
|
|
## Required env vars (in `.env` on storagebox `test/secrets/iklim.co/.env`)
|
|
|
|
```bash
|
|
API_SUBDOMAIN=api-test.iklim.co
|
|
APIGW_SUBDOMAIN=apigw-test.iklim.co
|
|
RABBITMQ_SUBDOMAIN=rabbitmq-test.iklim.co
|
|
GRAFANA_SUBDOMAIN=grafana-test.iklim.co
|
|
RESTRICTED_IP_1=78.187.87.109
|
|
RESTRICTED_IP_2=95.70.151.248
|
|
```
|
|
|
|
## Files to create
|
|
|
|
### `swag/site-confs/default.conf`
|
|
Default catch-all: HTTP→HTTPS redirect + 444 for unknown HTTPS hosts.
|
|
|
|
```nginx
|
|
server {
|
|
listen 80 default_server;
|
|
listen [::]:80 default_server;
|
|
server_name _;
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
|
|
server {
|
|
listen 443 ssl http2 default_server;
|
|
listen [::]:443 ssl http2 default_server;
|
|
server_name _;
|
|
include /config/nginx/ssl.conf;
|
|
return 444;
|
|
}
|
|
```
|
|
|
|
### `swag/proxy-confs/api.conf.tpl`
|
|
Public API gateway — no IP restriction.
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${API_SUBDOMAIN};
|
|
|
|
include /config/nginx/ssl.conf;
|
|
include /config/nginx/resolver.conf;
|
|
|
|
client_max_body_size 50m;
|
|
|
|
location / {
|
|
include /config/nginx/proxy.conf;
|
|
include /config/nginx/resolver.conf;
|
|
set $upstream_app apisix;
|
|
set $upstream_port 9080;
|
|
set $upstream_proto http;
|
|
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
|
|
}
|
|
}
|
|
```
|
|
|
|
### `swag/proxy-confs/apigw.conf.tpl`
|
|
APISIX Dashboard — IP restricted.
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${APIGW_SUBDOMAIN};
|
|
|
|
include /config/nginx/ssl.conf;
|
|
include /config/nginx/resolver.conf;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
allow ${RESTRICTED_IP_1};
|
|
allow ${RESTRICTED_IP_2};
|
|
deny all;
|
|
|
|
include /config/nginx/proxy.conf;
|
|
include /config/nginx/resolver.conf;
|
|
set $upstream_app apisix-dashboard;
|
|
set $upstream_port 9000;
|
|
set $upstream_proto http;
|
|
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
|
|
}
|
|
}
|
|
```
|
|
|
|
### `swag/proxy-confs/rabbitmq.conf.tpl`
|
|
RabbitMQ Management UI — IP restricted.
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${RABBITMQ_SUBDOMAIN};
|
|
|
|
include /config/nginx/ssl.conf;
|
|
include /config/nginx/resolver.conf;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
allow ${RESTRICTED_IP_1};
|
|
allow ${RESTRICTED_IP_2};
|
|
deny all;
|
|
|
|
include /config/nginx/proxy.conf;
|
|
include /config/nginx/resolver.conf;
|
|
set $upstream_app rabbitmq;
|
|
set $upstream_port 15672;
|
|
set $upstream_proto http;
|
|
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
|
|
}
|
|
}
|
|
```
|
|
|
|
### `swag/proxy-confs/grafana.conf.tpl`
|
|
Grafana — IP restricted.
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl http2;
|
|
listen [::]:443 ssl http2;
|
|
server_name ${GRAFANA_SUBDOMAIN};
|
|
|
|
include /config/nginx/ssl.conf;
|
|
include /config/nginx/resolver.conf;
|
|
|
|
client_max_body_size 0;
|
|
|
|
location / {
|
|
allow ${RESTRICTED_IP_1};
|
|
allow ${RESTRICTED_IP_2};
|
|
deny all;
|
|
|
|
include /config/nginx/proxy.conf;
|
|
include /config/nginx/resolver.conf;
|
|
set $upstream_app grafana;
|
|
set $upstream_port 3000;
|
|
set $upstream_proto http;
|
|
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Deploy step (handled by pipeline — see `07-deploy-pipeline-update.md`)
|
|
|
|
```bash
|
|
# Process templates and write to host
|
|
mkdir -p /opt/iklimco/swag/proxy-confs /opt/iklimco/swag/site-confs
|
|
|
|
set -a; . ./.env; set +a
|
|
export RESTRICTED_IP_1="78.187.87.109"
|
|
export RESTRICTED_IP_2="95.70.151.248"
|
|
|
|
for tpl in swag/proxy-confs/*.conf.tpl; do
|
|
out="/opt/iklimco/swag/proxy-confs/$(basename "${tpl%.tpl}")"
|
|
envsubst < "$tpl" > "$out"
|
|
echo "✅ $out"
|
|
done
|
|
|
|
cp swag/site-confs/default.conf /opt/iklimco/swag/site-confs/default.conf
|
|
```
|
|
|
|
## Verification
|
|
|
|
After deploy, check SWAG nginx config is valid:
|
|
```bash
|
|
docker exec $(docker ps -q -f name=iklimco_swag) nginx -t
|
|
```
|
|
|
|
Check subdomains resolve (from outside the server):
|
|
```bash
|
|
curl -sk https://api-test.iklim.co/health # expects APISIX response
|
|
curl -sk https://grafana-test.iklim.co # expects 403 Forbidden (wrong IP)
|
|
```
|
|
|
|
## Notes
|
|
- `include /config/nginx/resolver.conf` enables dynamic upstream resolution via Docker DNS —
|
|
required for overlay service names like `apisix`, `grafana`, etc.
|
|
- SWAG's `proxy.conf` already sets `X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto` and
|
|
WebSocket upgrade headers. No manual addition needed.
|
|
- `*.iklim.co` cert covers both `api.iklim.co` and `api-test.iklim.co` subdomains —
|
|
both test and prod servers can independently obtain and use it.
|