Skip to content

Commit 10e66af

Browse files
authored
feat(docker): make reverse proxy optional with ENABLE_PROXY flag (#9)
## Summary - Makes the reverse proxy behavior optional in the web container - By default, the browser now connects directly to the API (no reverse proxy) - Set `ENABLE_PROXY=true` to use nginx as a reverse proxy (previous behavior) ## Changes - Add `ENABLE_PROXY` environment variable (default: `false`) - In direct mode: `config.json` contains the full `API_URL` - In proxy mode: `config.json` contains `/api/v1` (relative path) - Use dynamic DNS resolver extracted from `/etc/resolv.conf` for nginx - Fix `config.json` file permissions (644) so nginx can read it - Update `docker-compose.yaml` to set `ENABLE_PROXY=true` ## Usage **Direct mode (default):** ```bash docker run -e API_URL=https://api.example.com dispatchoor-web # config.json: {"apiUrl": "https://api.example.com/api/v1"} ``` **Reverse proxy mode:** ```bash docker run -e API_URL=http://api:9090 -e ENABLE_PROXY=true dispatchoor-web # config.json: {"apiUrl": "/api/v1"} ``` ## Test plan - [x] Build image: `make docker-build-web` - [x] Test direct mode: verify `config.json` contains full API URL - [x] Test proxy mode: verify `config.json` contains `/api/v1` - [x] Verify nginx starts without upstream resolution errors - [x] Verify `config.json` is accessible (not 403)
1 parent 1e63a2e commit 10e66af

File tree

2 files changed

+40
-12
lines changed

2 files changed

+40
-12
lines changed

Dockerfile.web

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,27 @@ RUN apk add --no-cache gettext
2323
COPY --from=builder /app/dist /usr/share/nginx/html
2424

2525
# Copy nginx config template
26+
# Uses dynamic resolver and variable-based proxy_pass for runtime DNS resolution
2627
COPY <<'EOF' /etc/nginx/templates/default.conf.template
2728
server {
2829
listen 80;
2930
server_name _;
3031
root /usr/share/nginx/html;
3132
index index.html;
3233

34+
# Dynamic DNS resolver (extracted from /etc/resolv.conf at startup)
35+
resolver ${RESOLVER} valid=10s ipv6=off;
36+
37+
# Set API URL as variable for dynamic resolution at request time
38+
set $api_upstream "${API_URL}";
39+
3340
# Gzip compression
3441
gzip on;
3542
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
3643

37-
# API proxy
44+
# API proxy - using variable triggers runtime DNS resolution
3845
location /api/ {
39-
proxy_pass ${API_URL};
46+
proxy_pass $api_upstream;
4047
proxy_http_version 1.1;
4148
proxy_set_header Upgrade $http_upgrade;
4249
proxy_set_header Connection "upgrade";
@@ -48,12 +55,12 @@ server {
4855
}
4956

5057
location /health {
51-
proxy_pass ${API_URL};
58+
proxy_pass $api_upstream;
5259
proxy_set_header Host $host;
5360
}
5461

5562
location /metrics {
56-
proxy_pass ${API_URL};
63+
proxy_pass $api_upstream;
5764
proxy_set_header Host $host;
5865
}
5966

@@ -74,25 +81,45 @@ EOF
7481
COPY <<'EOF' /docker-entrypoint.d/40-envsubst-on-templates.sh
7582
#!/bin/sh
7683
set -e
77-
envsubst '${API_URL}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf
84+
# Extract resolver from /etc/resolv.conf (first nameserver)
85+
# This works across Docker (127.0.0.11), Kubernetes (cluster DNS), and bare metal
86+
RESOLVER=$(grep -m1 '^nameserver' /etc/resolv.conf | awk '{print $2}')
87+
if [ -z "$RESOLVER" ]; then
88+
RESOLVER="127.0.0.11" # Fallback for Docker
89+
fi
90+
export RESOLVER
91+
echo "Using DNS resolver: $RESOLVER"
92+
envsubst '${API_URL} ${RESOLVER}' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf
7893
EOF
7994

8095
COPY <<'EOF' /docker-entrypoint.d/30-generate-ui-config.sh
8196
#!/bin/sh
8297
set -e
83-
# Generate UI config.json - uses /api/v1 since nginx proxies to the backend
84-
cat > /usr/share/nginx/html/config.json << 'CONFIG'
98+
99+
if [ "${ENABLE_PROXY:-false}" = "true" ]; then
100+
# Reverse proxy mode: use relative path (nginx proxies to backend)
101+
API_BASE="/api/v1"
102+
else
103+
# Direct mode: browser connects directly to API
104+
# Strip trailing slash if present, then append /api/v1
105+
API_BASE="${API_URL%/}/api/v1"
106+
fi
107+
108+
cat > /usr/share/nginx/html/config.json << CONFIGEOF
85109
{
86-
"apiUrl": "/api/v1"
110+
"apiUrl": "${API_BASE}"
87111
}
88-
CONFIG
89-
echo "Generated /usr/share/nginx/html/config.json"
112+
CONFIGEOF
113+
chmod 644 /usr/share/nginx/html/config.json
114+
echo "Generated config.json with apiUrl: ${API_BASE}"
90115
EOF
91116

92117
RUN chmod +x /docker-entrypoint.d/40-envsubst-on-templates.sh /docker-entrypoint.d/30-generate-ui-config.sh
93118

94-
# Default API URL
95-
ENV API_URL=http://api:9090
119+
# Default: direct API access (browser connects directly to API)
120+
# Set ENABLE_PROXY=true for reverse proxy mode (nginx proxies /api/* to backend)
121+
ENV API_URL=http://localhost:9090
122+
ENV ENABLE_PROXY=false
96123

97124
EXPOSE 80
98125

docker-compose.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ services:
3333
- "3000:80"
3434
environment:
3535
- API_URL=http://api:9090
36+
- ENABLE_PROXY=true
3637
depends_on:
3738
api:
3839
condition: service_healthy

0 commit comments

Comments
 (0)