DOCKER.md•5.65 kB
# ZAP MCP Server - Docker Setup
This document describes how to run the ZAP MCP Server in a Docker container and how to scan localhost applications.
## ⚠️ IMPORTANT: Automatic Localhost URL Transformation
The server detects Docker environments and transparently maps `localhost`/`127.0.0.1` URLs to `host.docker.internal`.
Examples:
```bash
URL: http://localhost:3000 → http://host.docker.internal:3000
URL: http://127.0.0.1:8080 → http://host.docker.internal:8080
URL: https://localhost:8443 → https://host.docker.internal:8443
# Localhost URLs can be used directly ✅
```
## Prerequisites
- Docker and Docker Compose installed
- At least 4GB RAM for the container
- Ports 8080 and 8082 available
- Firefox ESR installed in container (for AJAX scans)
## Quick Start
### Option 1: Host Gateway (Recommended)
```bash
# Build container
./build.sh
# Start container
./start.sh
# Check status
docker-compose ps
```
**⚠️ CRITICAL: For localhost scans, you can use:**
- `http://localhost:3000` (automatically mapped to `http://host.docker.internal:3000`)
- `http://127.0.0.1:8080` (automatically mapped to `http://host.docker.internal:8080`)
- No manual URL replacement needed
## Localhost Scanning
### ⚠️ CRITICAL NOTE
Inside Docker, `localhost` normally refers to the container. This project detects Docker and automatically remaps `localhost`/`127.0.0.1` to `host.docker.internal` for scan targets, so you can pass `localhost` URLs directly.
## Configuration
**📖 For complete configuration details, see [README.md](README.md#-configuration)**
### Docker-Specific Settings
- `ZAP_SESSION_NAME`: Session Name (Default: `zap_docker_session`)
- `ZAP_MCP_HOST`: MCP Server Host (Default: `0.0.0.0`)
### Volumes
- `zap-data`: Persistent ZAP sessions
- `./logs`: Log files
## Access
**📖 For complete access information, see [README.md](README.md#-quick-start)**
After startup, the following services are available:
- **ZAP API**: http://localhost:8080
- **MCP Server**: http://localhost:8082/mcp
## AJAX Scans
The container includes Firefox ESR for AJAX spider scans:
- **Browser**: Firefox ESR (headless mode)
- **No X11 Required**: Runs completely headless without display server
- **Environment**: `MOZ_HEADLESS=1` with all sandbox features disabled
- **JVM Options**: Headless mode with OpenGL disabled
- **Default Configuration**: Uses `firefox-headless` browser ID
AJAX scans will automatically use the Firefox browser in headless mode without requiring any display server.
## Example Scans
### Automatic URL Transformation
```bash
# Test ZAP API directly
curl http://localhost:8080/JSON/core/view/version/
# Test MCP Server
curl http://localhost:8082/mcp
# Scan a service running on your host (localhost auto-mapped)
curl http://localhost:3000
```
### Example with OWASP Juice Shop
```bash
# Scan OWASP Juice Shop (publicly available test target)
curl -X POST http://localhost:8082/mcp \
-H "Content-Type: application/json" \
-d '{
"tool": "start_complete_scan",
"arguments": {
"url": "https://juice-shop.herokuapp.com/#/",
"include_findings": true
}
}'
```
## Troubleshooting
### Container Won't Start
```bash
# Check logs
docker-compose logs zap-mcp
# Check container status
docker-compose ps
```
### ZAP Won't Start
```bash
# Log into container
docker-compose exec zap-mcp bash
# Check ZAP status
curl http://localhost:8080/JSON/core/view/version/
```
### Localhost Access Doesn't Work
```bash
# Check if host.docker.internal is reachable from container
docker-compose exec zap-mcp curl http://host.docker.internal:3000
# You can also use localhost (auto-mapped)
docker-compose exec zap-mcp curl http://localhost:3000
# If host.docker.internal doesn't work, try host IP address
docker-compose exec zap-mcp curl http://172.17.0.1:3000
```
### Port Conflicts
If ports are already in use, configure custom ports:
**Using .env file (Recommended):**
```bash
# Copy the example file
cp env.example .env
# Edit .env file
ZAP_PORT=8081
ZAP_MCP_PORT=8083
ZAP_BASE=http://127.0.0.1:8081
```
**Using environment variables:**
```bash
# Set custom ports
export ZAP_PORT=8081
export ZAP_MCP_PORT=8083
export ZAP_BASE="http://127.0.0.1:8081"
# Then start containers
./start.sh
```
**Connect to**: `http://localhost:8083/mcp`
## Performance Tuning
### Memory
For large scans, increase available memory:
```yaml
services:
zap-mcp:
deploy:
resources:
limits:
memory: 8G
reservations:
memory: 4G
```
### CPU
```yaml
services:
zap-mcp:
deploy:
resources:
limits:
cpus: '4.0'
reservations:
cpus: '2.0'
```
## Security
- Container runs as non-root user (`zap`)
- ZAP API keys are disabled by default
- Only necessary ports are exposed
## Updates
```bash
# Rebuild image
./build.sh
# Restart container
docker-compose down
docker-compose up -d
```
## Solution Comparison
| Solution | Advantages | Disadvantages | Recommendation |
|----------|------------|---------------|----------------|
| Host Gateway | Secure, isolated, flexible | None (automatic URL transformation) | ✅ **Recommended** |
## Usage with MCP Clients
**📖 For complete MCP client usage instructions, see [README.md](README.md#-connect-your-mcp-client)**
The Docker container provides the MCP server via HTTP at: `http://localhost:8082/mcp`
## Advanced Configuration
**📖 For advanced configuration options, see [README.md](README.md#-configuration)**
### Docker-Specific Advanced Options
- Custom ZAP versions
- Additional ZAP addons
- Persistent session management