Skip to content

Docker CSP Integration

Add CSP headers to containerized applications using Nginx, Traefik, or Envoy.

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY dist/ /usr/share/nginx/html/
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# CSP Header
add_header Content-Security-Policy-Report-Only "
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
report-uri https://ingest.headerhawk.com/csp/YOUR_SITE_ID
" always;
# Other security headers
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
location / {
try_files $uri $uri/ /index.html;
}
}
}
services:
traefik:
image: traefik:v3.0
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app:
image: your-app:latest
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`example.com`)"
- "traefik.http.middlewares.csp.headers.customresponseheaders.Content-Security-Policy-Report-Only=default-src 'self'; script-src 'self'; report-uri https://ingest.headerhawk.com/csp/YOUR_SITE_ID"
- "traefik.http.routers.app.middlewares=csp"
http:
middlewares:
csp:
headers:
customResponseHeaders:
Content-Security-Policy-Report-Only: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; report-uri https://ingest.headerhawk.com/csp/YOUR_SITE_ID"
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
response_headers_to_add:
- header:
key: "Content-Security-Policy-Report-Only"
value: "default-src 'self'; script-src 'self'; report-uri https://ingest.headerhawk.com/csp/YOUR_SITE_ID"
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_cluster
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; report-uri https://ingest.headerhawk.com/csp/YOUR_SITE_ID" always;
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80

Use environment variables for different environments:

FROM nginx:alpine
ARG SITE_ID
ENV SITE_ID=${SITE_ID}
COPY nginx.conf.template /etc/nginx/templates/default.conf.template
nginx.conf.template
server {
listen 80;
add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri https://ingest.headerhawk.com/csp/${SITE_ID}" always;
location / {
root /usr/share/nginx/html;
index index.html;
}
}

Build with:

Terminal window
docker build --build-arg SITE_ID=your-site-id -t your-app .
  1. Check container logs: docker logs <container-id>
  2. Verify nginx config syntax: docker exec <container> nginx -t
  3. Ensure the config file is properly mounted/copied
  1. Check file permissions
  2. Verify COPY paths in Dockerfile
  3. Use docker exec to inspect files inside container
Terminal window
# From inside the container
docker exec <container-id> curl -I http://localhost
# From host
curl -I http://localhost:<mapped-port>