# nginx-based images ## Security context nginx binds to port 80 (or 443) and needs to `chown` files before dropping to `www-data`. It must run as root but can drop most capabilities after startup. ```yaml spec: template: spec: securityContext: # pod level runAsNonRoot: false runAsUser: 0 seccompProfile: type: RuntimeDefault containers: - name: app securityContext: # container level allowPrivilegeEscalation: false capabilities: drop: [ALL] add: [CHOWN, SETUID, SETGID, NET_BIND_SERVICE] readOnlyRootFilesystem: false ``` Add `NET_BIND_SERVICE` only if the container binds to a port below 1024. Drop it if the app uses a high port (8080, 3000, etc.). ## Docker DNS resolver (`WC-DKRDNS`) nginx proxy configs shipped for Docker often contain: ```nginx resolver 127.0.0.11 valid=3s; set $backend app-backend:8000; proxy_pass http://$backend$request_uri; ``` `127.0.0.11` is Docker's embedded DNS resolver — it does not exist in Kubernetes. This fails with `send() failed (111: Connection refused) while resolving`. There's a second trap: **any nginx variable anywhere in the `proxy_pass` URL** (even `$request_uri` in the path) forces runtime DNS resolution and requires a `resolver` directive. Removing the resolver line but keeping `proxy_pass http://backend:8000$request_uri;` still fails with `no resolver defined to resolve backend`. **Fix**: override the nginx config template via a ConfigMap mounted with `subPath`, and remove the variable from `proxy_pass` entirely: ```nginx # Instead of: resolver 127.0.0.11 valid=3s; set $backend ${BACKEND}; proxy_pass http://$backend$request_uri; # Use: proxy_pass http://${BACKEND}; ``` With no nginx variable in `proxy_pass`, nginx resolves the hostname at startup using the pod's `/etc/resolv.conf` (which points to CoreDNS). The full request URI is still forwarded automatically in a regex `location ~` block. Mount the ConfigMap with `subPath` to override just the template file without replacing the whole directory.