A production-grade, SOC 2 compliant Docker image for Node.js applications. Built on Ubuntu 24.04 with Nginx, Node.js 20, ModSecurity WAF, and Wazuh SIEM integration.
Architecture
·
SOC 2 Compliance
| Category | Details |
|---|---|
| Runtime | Node.js 20 LTS with Nginx reverse proxy |
| WAF | ModSecurity 3 + OWASP Core Rule Set 4.4.0 |
| TLS | TLS 1.2+ only, AEAD cipher suites, HSTS |
| Security Headers | X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy |
| SIEM | Wazuh agent with file integrity monitoring and rootkit detection |
| Logging | Dual-format access logs (human-readable + JSON for SIEM ingestion) |
| Health Check | Built-in /elb-status endpoint for AWS ELB/ALB |
| Process Manager | Supervisord with auto-restart for all services |
# Build the image
just build
# Start the container
just run
# Run the full test suite
just testThe container exposes:
- HTTP on port
8082(health check + HTTPS redirect) - HTTPS on port
8443(application traffic)
services:
app:
image: ghcr.io/merchantprotocol/docker-nginx-node20:latest
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- "./:/var/www/html:rw"
environment:
- WAZUH_MANAGER=your-wazuh-manager
- WAZUH_REGISTRATION_PASSWORD=your-password
- WAZUH_AGENT_NAME=your-agent-nameMount your application code to /var/www/html. The container supports runtime configuration overrides by placing files in the nginx.d/ directory within your application root:
File in nginx.d/ |
Overrides |
|---|---|
nginx.conf |
Default Nginx server block |
nginx-ssl.conf |
SSL server block |
Additional extension points:
| Directory | Purpose |
|---|---|
supervisor.d/ |
Additional Supervisord program configs |
docker.d/ |
Shell scripts executed on container startup |
cron.d/ |
Cron job scripts (.sh files) |
The container remaps www-data to UID/GID 1000 by default so file ownership matches between host and container on mounted volumes. To use a different UID/GID:
just run-with-uid 1001 1001Or pass build args directly:
docker build --build-arg USER_ID=1001 --build-arg GROUP_ID=1001 -t docker-nginx-node20 .This image is designed for SOC 2 Type II compliance. Key controls include:
- Least privilege -- Nginx runs as
www-data(non-root). Nosudo,gosu, or dev tools installed. - WAF -- ModSecurity 3 with OWASP CRS blocks SQL injection, XSS, and other OWASP Top 10 attacks.
- Path restrictions --
.env,.git,/vendor,/config,/tmp, and sensitive file extensions (.sql,.yml,.ini,.zip,.sh,.log) return 403. - TLS hardening -- TLS 1.0/1.1 disabled. Only ECDHE/DHE with AES-GCM ciphers accepted.
- SIEM integration -- Wazuh agent ships logs to a central manager with file integrity monitoring, rootkit detection, and active response.
- Structured logging -- JSON access logs at
/var/log/nginx/access.json.logready for Wazuh, ELK, Splunk, or Datadog.
For the full SOC 2 control mapping, see docs/SOC2-COMPLIANCE.md.
The included test suite validates all security controls:
# Full lifecycle: build, start, test, clean up
just test-all
# Test a running container
just test| Test | What It Validates |
|---|---|
test-health |
/elb-status health check responds |
test-https-redirect |
HTTP 301 redirect to HTTPS |
test-security-headers |
All security headers present |
test-ssl |
TLS 1.2+ enforced |
test-waf |
WAF blocks SQL injection |
test-blocked-paths |
Sensitive files return 403 |
test-services |
Nginx, Supervisor, Cron, Wazuh all running |
test-permissions |
Correct UID/GID mapping |
| Component | Version | Notes |
|---|---|---|
| Ubuntu | 24.04 LTS | Supported through 2029 |
| Node.js | 20 LTS | Via NodeSource |
| Nginx | Latest | Ubuntu package |
| ModSecurity | 3.x | With OWASP CRS 4.4.0 |
| Wazuh Agent | 4.9.0 | SIEM + FIM |
| Yarn | Latest | Node.js package manager |
- Architecture Overview -- Container components, request flow, logging architecture, and volume mount strategy
- SOC 2 Compliance -- Control mapping, audit evidence commands, and security header reference
Open-source software licensed under the MIT License.
Copyright (c) 2024-2026 Merchant Protocol, LLC