This project provides an Nginx Docker image that integrates ModSecurity.
3.4K
English | 简体中文
Production-oriented Docker images for running Nginx with the ModSecurity v3 WAF engine. The image builds ModSecurity and the modsecurity-nginx connector from source, compiles the Nginx connector as a dynamic module, and publishes multi-architecture images for linux/amd64 and linux/arm64.
This repository is intentionally small: each supported version pair lives in its own nginx-<version>/mod-<version>/Dockerfile, while build-matrix.json controls which images are currently published by CI.
nginx:<version>-alpine imagemodsecurity-nginx compiled as an Nginx dynamic module/etc/nginx/modules-available/50-modsecurity.conf/etc/nginx/modules-enabled/unicode.mapping copied to /etc/nginx/modsec/The image provides the WAF engine and Nginx module. It does not bundle a default OWASP Core Rule Set configuration, so production deployments should mount their own ModSecurity configuration and rules.
The current CI build matrix is defined in build-matrix.json:
| Channel | Nginx | ModSecurity | modsecurity-nginx | Dockerfile |
|---|---|---|---|---|
mainline / latest | 1.31.0 | v3.0.15 | v1.0.4 | nginx-1.31.0/mod-3.0.15/Dockerfile |
stable | 1.30.1 | v3.0.15 | v1.0.4 | nginx-1.30.1/mod-3.0.15/Dockerfile |
Older version directories remain in the repository as historical build definitions, but only entries listed in build-matrix.json are built and published by the current GitHub Actions workflow.
Images are published to both Docker Hub and GitHub Container Registry:
docker pull e1saps/nginx-modsecurity:latest
docker pull ghcr.io/apts-1547/nginx-modsecurity:latest
Use Docker Hub if you do not have a registry preference. Use GHCR when your deployment workflow already authenticates against GitHub Packages.
Each matrix entry is published with a version tag and a plain Nginx version tag:
| Tag | Example | Meaning |
|---|---|---|
<nginx-version>-<modsecurity-version> | 1.31.0-3.0.15 | Exact Nginx and ModSecurity pair |
<nginx-version> | 1.31.0 | Alias for the Nginx version's current ModSecurity pair |
latest | latest | Current mainline build |
mainline | mainline | Current Nginx mainline build |
stable | stable | Current Nginx stable build |
For production, prefer the full version tag, for example:
docker pull e1saps/nginx-modsecurity:1.30.1-3.0.15
That avoids accidental upgrades when latest, mainline, or stable move.
Run the latest mainline image:
docker run --rm -p 8080:80 e1saps/nginx-modsecurity:latest
Then check the default Nginx page:
curl http://localhost:8080/
This confirms that Nginx starts. To actually inspect traffic with ModSecurity, add a ModSecurity configuration and enable it in your Nginx server or location block.
The image places the module loader at:
/etc/nginx/modules-enabled/50-modsecurity.conf
If you replace /etc/nginx/nginx.conf, make sure your custom file includes enabled modules before the events block:
include /etc/nginx/modules-enabled/*.conf;
events {}
http {
server {
listen 80;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
location / {
proxy_pass http://app:3000;
}
}
}
If you only mount files under /etc/nginx/conf.d/, the default Nginx image entrypoint keeps the base nginx.conf, so the loader behavior depends on that base configuration. When in doubt, provide a complete nginx.conf with the include /etc/nginx/modules-enabled/*.conf; line.
Create a minimal ModSecurity configuration:
# ./modsec/modsecurity.conf
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecAuditEngine RelevantOnly
SecAuditLog /var/log/nginx/modsec_audit.log
SecRule ARGS:test "@contains attack" "id:1000,phase:2,deny,status:403,msg:'Test ModSecurity rule'"
Create an Nginx config that loads the module and uses that rules file:
# ./nginx.conf
include /etc/nginx/modules-enabled/*.conf;
events {}
http {
server {
listen 80;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
location / {
return 200 "nginx-modsecurity is running\n";
}
}
}
Run the container:
docker run --rm \
-p 8080:80 \
-v "$PWD/nginx.conf:/etc/nginx/nginx.conf:ro" \
-v "$PWD/modsec:/etc/nginx/modsec:ro" \
e1saps/nginx-modsecurity:stable
Test the rule:
curl "http://localhost:8080/?test=ok"
curl -i "http://localhost:8080/?test=attack"
The second request should return 403 when the rule is active.
services:
waf:
image: e1saps/nginx-modsecurity:1.30.1-3.0.15
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./modsec:/etc/nginx/modsec:ro
- ./logs:/var/log/nginx
restart: unless-stopped
Build a specific version from its Dockerfile:
docker build \
-t nginx-modsecurity:1.31.0-3.0.15 \
-f nginx-1.31.0/mod-3.0.15/Dockerfile \
.
Run it:
docker run --rm -p 8080:80 nginx-modsecurity:1.31.0-3.0.15
For multi-architecture publishing, use Buildx:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t your-registry/nginx-modsecurity:1.31.0-3.0.15 \
-f nginx-1.31.0/mod-3.0.15/Dockerfile \
--push \
.
Use update.sh to create a new version directory from the nearest existing template with the same ModSecurity version:
./update.sh <NGINX_VERSION> <MODSECURITY_VERSION> <MODSECURITY_NGINX_VERSION> [ROLE]
Example:
./update.sh 1.31.1 v3.0.15 v1.0.4 mainline
The script:
nginx-<nginx-version>/mod-<modsecurity-version>/Dockerfilebuild_date labelrole entry in build-matrix.jsonValid roles are currently interpreted by CI as:
| Role | Published channel tags |
|---|---|
mainline | latest, mainline |
stable | stable |
After running the script, review the generated Dockerfile before committing. Different Nginx or ModSecurity versions sometimes require small build fixes.
The GitHub Actions workflow at .github/workflows/docker-image.yml runs on pushes to master that modify build-matrix.json or versioned Dockerfiles. It can also be started manually with workflow_dispatch.
For each matrix entry, CI:
linux/amd64 and linux/arm64 images on native runnersforce_rebuild input is enabled.
├── build-matrix.json
├── update.sh
├── nginx-1.31.0/
│ └── mod-3.0.15/
│ └── Dockerfile
├── nginx-1.30.1/
│ └── mod-3.0.15/
│ └── Dockerfile
└── .github/
└── workflows/
└── docker-image.yml
Older nginx-* directories follow the same layout.
This project is licensed under the MIT License.
Content type
Image
Digest
sha256:8cff30fd7…
Size
89.2 MB
Last updated
about 2 hours ago
docker pull e1saps/nginx-modsecurity:mainline