OPC # 0001: Extract gateway into standalone repo

This commit is contained in:
amadzarak
2026-04-25 17:27:47 -04:00
commit 6accc7ca25
10 changed files with 224 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
# gateway
Nginx reverse proxy + Dnsmasq DNS resolver for the ClarityStack local dev environment.
## Structure
```
gateway/
├── nginx/
│ ├── nginx.conf
│ ├── conf.d/ # per-service virtual host configs
│ ├── clarity.test.crt
│ └── clarity.test.key
├── dnsmasq/
│ └── dnsmasq.conf # resolves *.clarity.test → 127.0.0.1
└── docker-compose.yml
```
## Usage
```bash
docker compose up -d
```
Requires the external Docker network `clarity-net` to exist:
```bash
docker network create clarity-net
```
## OPC #0039
Extracted from the original monorepo `infra/` as a standalone composable unit.
+17
View File
@@ -0,0 +1,17 @@
# Resolve all *.clarity.local subdomains to the loopback address.
# nginx (bound to port 80 on the host) then routes by subdomain to the correct tenant container.
address=/.clarity.test/127.0.0.1
# Don't read /etc/resolv.conf or /etc/hosts from the container — we are the resolver
no-resolv
no-hosts
# Forward everything that isn't clarity.local to Cloudflare DNS
server=1.1.1.1
server=8.8.8.8
# Listen on all interfaces inside the container
listen-address=0.0.0.0
# Log queries — useful during initial setup, can be removed later
log-queries
+34
View File
@@ -0,0 +1,34 @@
services:
nginx:
image: nginx:alpine
container_name: clarity-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/clarity.test.crt:/etc/nginx/certs/clarity.test.crt:ro
- ./nginx/clarity.test.key:/etc/nginx/certs/clarity.test.key:ro
networks:
- clarity-net
dnsmasq:
image: dockurr/dnsmasq
container_name: clarity-dnsmasq
restart: unless-stopped
ports:
- "53:53/udp"
- "53:53/tcp"
volumes:
- ./dnsmasq/dnsmasq.conf:/etc/dnsmasq.conf:ro
cap_add:
- NET_ADMIN
networks:
- clarity-net
networks:
clarity-net:
external: true
name: clarity-net
@@ -0,0 +1,19 @@
# Auto-generated by ControlPlane.Worker — do not edit manually.
# Tenant: fdev-app-clarity-01000000
server {
listen 443 ssl;
server_name fdev-app-clarity-01000000.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
location / {
# Docker DNS resolves the container name on the managed network
set $upstream http://fdev-app-clarity-01000000:8080;
proxy_pass $upstream;
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;
}
}
@@ -0,0 +1,19 @@
# Auto-generated by ControlPlane.Worker — do not edit manually.
# Tenant: fdev-app-clarity-02000000
server {
listen 443 ssl;
server_name fdev-app-clarity-02000000.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
location / {
# Docker DNS resolves the container name on the managed network
set $upstream http://fdev-app-clarity-02000000:8080;
proxy_pass $upstream;
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;
}
}
@@ -0,0 +1,19 @@
# Auto-generated by ControlPlane.Worker — do not edit manually.
# Tenant: fdev-app-clarity-03000000
server {
listen 443 ssl;
server_name fdev-app-clarity-03000000.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
location / {
# Docker DNS resolves the container name on the managed network
set $upstream http://fdev-app-clarity-03000000:8080;
proxy_pass $upstream;
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;
}
}
@@ -0,0 +1,19 @@
# Auto-generated by ControlPlane.Worker — do not edit manually.
# Tenant: fdev-app-clarity-04000000
server {
listen 443 ssl;
server_name fdev-app-clarity-04000000.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
location / {
# Docker DNS resolves the container name on the managed network
set $upstream http://fdev-app-clarity-04000000:8080;
proxy_pass $upstream;
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;
}
}
+21
View File
@@ -0,0 +1,21 @@
server {
listen 443 ssl;
server_name opc.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
# Git over HTTP needs larger body and longer timeouts
client_max_body_size 100m;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
location / {
set $upstream http://host.docker.internal:3000;
proxy_pass $upstream;
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;
}
}
+16
View File
@@ -0,0 +1,16 @@
server {
listen 443 ssl;
server_name keycloak.clarity.test;
ssl_certificate /etc/nginx/certs/clarity.test.crt;
ssl_certificate_key /etc/nginx/certs/clarity.test.key;
location / {
set $upstream http://keycloak:8080;
proxy_pass $upstream;
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;
}
}
+27
View File
@@ -0,0 +1,27 @@
events {
worker_connections 1024;
}
http {
# Use Docker's embedded DNS resolver so container names resolve dynamically.
# This is critical — without it nginx resolves upstream names at startup only
# and won't pick up newly provisioned tenant containers.
resolver 127.0.0.11 valid=5s ipv6=off;
# Shared log format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
# Redirect all HTTP → HTTPS
server {
listen 80 default_server;
return 301 https://$host$request_uri;
}
# Pick up per-tenant server blocks dropped by the provisioning worker
include /etc/nginx/conf.d/*.conf;
}