DVWA provides official Docker images that simplify deployment and ensure consistent environments across different systems.
Prerequisites
Before starting, ensure you have Docker and Docker Compose installed.
Required Software
- Docker - Container runtime
- Docker Compose - Multi-container orchestration
Installation Check
Verify your installation:
docker version
docker compose version
```text
Expected output:
```text
>>> docker version
Client:
[..]
Version: 23.0.5
[..]
Server: Docker Desktop 4.19.0 (106363)
Engine:
[..]
Version: 23.0.5
[..]
>>> docker compose version
Docker Compose version v2.17.3
Install Docker
Docker Desktop
Docker Engine (Linux)
Download from docker.com for:Docker Desktop includes both Docker and Docker Compose. Follow the official installation guide for your distribution:
DVWA supports the latest Docker release. Older versions from package managers may work but are supported on a best-effort basis.
Quick Start
Get DVWA running in four simple steps.
Clone the repository
git clone https://github.com/digininja/DVWA.git
cd DVWA
```bash
</Step>
<Step title="Start the containers">
```bash
docker compose up -d
The -d flag runs containers in detached mode (background).Access DVWA
Open your browser and navigate to: Complete setup
- Click “Create / Reset Database”
- Log in with default credentials:
- Username:
admin
- Password:
password
DVWA is now running in Docker!
Docker Compose Configuration
DVWA uses a compose.yml file to define services, networks, and volumes.
Complete Configuration
From compose.yml:
volumes:
dvwa:
networks:
dvwa:
services:
dvwa:
build: .
image: ghcr.io/digininja/dvwa:latest
# Change `always` to `build` to build from local source
pull_policy: always
environment:
- DB_SERVER=db
depends_on:
- db
# Uncomment the next 2 lines to serve local source
# volumes:
# - ./:/var/www/html
networks:
- dvwa
ports:
- 127.0.0.1:4280:80
restart: unless-stopped
db:
image: docker.io/library/mariadb:10
environment:
- MYSQL_ROOT_PASSWORD=dvwa
- MYSQL_DATABASE=dvwa
- MYSQL_USER=dvwa
- MYSQL_PASSWORD=p@ssw0rd
volumes:
- dvwa:/var/lib/mysql
networks:
- dvwa
restart: unless-stopped
```bash
### Architecture Overview
DVWA runs as two connected services:
<CardGroup cols={2}>
<Card title="dvwa" icon="globe">
Apache web server running PHP application
</Card>
<Card title="db" icon="database">
MariaDB 10 database server
</Card>
</CardGroup>
Both services:
- Share a private `dvwa` network
- Persist data in the `dvwa` volume
- Restart automatically unless manually stopped
## Port Configuration
By default, DVWA is accessible on port **4280**.
### Default Port Binding
```yaml
ports:
- 127.0.0.1:4280:80
This maps:
- Host:
127.0.0.1:4280 (your machine)
- Container: port
80 (inside container)
DVWA uses port 4280 instead of 80 to avoid conflicts with existing web servers and to support rootless container engines.
Why Not Port 80?
- Conflict avoidance - Port 80 may already be in use
- Rootless containers - Ports below 1024 require privileges
- Security - Reduces risk of accidental exposure
Change the Port
To use a different port, edit compose.yml:
ports:
- 127.0.0.1:8806:80 # Now accessible at localhost:8806
```bash
Restart the containers:
```bash
docker compose down
docker compose up -d
Access DVWA at: http://localhost:8806
Expose to Local Network
By default, DVWA only listens on 127.0.0.1 (localhost).
To make it accessible on your local network:
ports:
- 4280:80 # Listens on all interfaces
```text
Or bind to a specific IP:
```yaml
ports:
- 192.168.1.100:4280:80 # Only accessible from this IP
Only expose DVWA on a local network in controlled environments like workshops or isolated lab networks. Never expose it to the internet.
Environment Variables
Configure DVWA behavior using environment variables.
DVWA Service Variables
dvwa:
environment:
- DB_SERVER=db
- DEFAULT_SECURITY_LEVEL=low
- DEFAULT_LOCALE=en
- RECAPTCHA_PUBLIC_KEY=your_key_here
- RECAPTCHA_PRIVATE_KEY=your_key_here
```bash
#### Available Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `DB_SERVER` | `db` | Database hostname |
| `DB_DATABASE` | `dvwa` | Database name |
| `DB_USER` | `dvwa` | Database username |
| `DB_PASSWORD` | `p@ssw0rd` | Database password |
| `DB_PORT` | `3306` | Database port |
| `DEFAULT_SECURITY_LEVEL` | `impossible` | Initial security level |
| `DEFAULT_LOCALE` | `en` | Interface language |
| `DISABLE_AUTHENTICATION` | `false` | Disable login requirement |
| `RECAPTCHA_PUBLIC_KEY` | _(empty)_ | reCAPTCHA public key |
| `RECAPTCHA_PRIVATE_KEY` | _(empty)_ | reCAPTCHA private key |
| `SQLI_DB` | `mysql` | SQLi lab database backend |
### Database Service Variables
```yaml
db:
environment:
- MYSQL_ROOT_PASSWORD=dvwa
- MYSQL_DATABASE=dvwa
- MYSQL_USER=dvwa
- MYSQL_PASSWORD=p@ssw0rd
MariaDB Variables
| Variable | Value | Description |
|---|
MYSQL_ROOT_PASSWORD | dvwa | Root user password |
MYSQL_DATABASE | dvwa | Auto-created database |
MYSQL_USER | dvwa | Auto-created user |
MYSQL_PASSWORD | p@ssw0rd | User password |
Example: Start at Low Security
dvwa:
environment:
- DB_SERVER=db
- DEFAULT_SECURITY_LEVEL=low
```bash
## Volume Mapping for Development
Developers can mount local files into the container for live editing.
### Enable Local Development
Uncomment the volume mount in `compose.yml`:
```yaml
dvwa:
volumes:
- ./:/var/www/html # Mount current directory
Setup Steps
Copy configuration file
cp config/config.inc.php.dist config/config.inc.php
```bash
</Step>
<Step title="Enable volume mount">
Edit `compose.yml` and uncomment the volumes section.
</Step>
<Step title="Restart containers">
```bash
docker compose down
docker compose up -d
Benefits
- Live editing - Changes reflect immediately
- No rebuilds - Skip image rebuilding
- Faster development - Instant feedback
- Local debugging - Use your favorite tools
This mode is perfect for contributing to DVWA or testing custom modifications.
Local Build vs Pulling Images
DVWA can either pull prebuilt images or build from local source.
Pull Prebuilt Images (Default)
pull_policy: always
```bash
- **Faster** - No build time
- **Consistent** - Official tested images
- **Automatic updates** - Latest commits from master branch
- **Recommended for** - Most users
Images are automatically built from the `master` branch and published to:
[GitHub Container Registry](https://github.com/digininja/DVWA/pkgs/container/dvwa)
### Build from Local Source
Change the pull policy:
```yaml
pull_policy: build
Then rebuild:
docker compose up -d --build
```bash
- **Customizable** - Modify source code
- **Development** - Test local changes
- **Offline** - No internet required after first build
- **Recommended for** - Developers and contributors
### Image Information
View available images:
```bash
docker images | grep dvwa
Pull latest image manually:
docker pull ghcr.io/digininja/dvwa:latest
```bash
## Docker Management Commands
Common commands for managing DVWA containers.
### Start Services
```bash
# Start in background
docker compose up -d
# Start with logs visible
docker compose up
# Rebuild and start
docker compose up -d --build
Stop Services
# Stop containers (keeps data)
docker compose stop
# Stop and remove containers (keeps data)
docker compose down
# Stop and remove everything including volumes (deletes data)
docker compose down -v
```bash
### View Logs
```bash
# All services
docker compose logs
# Follow logs in real-time
docker compose logs -f
# Specific service
docker compose logs dvwa
docker compose logs db
# Export logs to file
docker compose logs > dvwa.log
Container Status
# List running containers
docker compose ps
# Detailed container info
docker compose ps -a
```bash
### Execute Commands in Container
```bash
# Open shell in DVWA container
docker compose exec dvwa bash
# Open MySQL shell in database
docker compose exec db mysql -u dvwa -pp@ssw0rd dvwa
# Run a single command
docker compose exec dvwa ls -la /var/www/html
Reset Everything
# Complete reset (deletes all data)
docker compose down -v
docker compose up -d
# Then navigate to setup page and recreate database
```bash
## Auto-Start Behavior
By default, DVWA automatically starts when Docker runs.
### Restart Policy
```yaml
restart: unless-stopped
This means:
- ✅ Starts on system boot
- ✅ Restarts after crashes
- ✅ Restarts after Docker daemon restart
- ❌ Does NOT restart after manual stop
Disable Auto-Start
To prevent automatic startup, remove or comment out the restart policy:
# restart: unless-stopped
```bash
Or stop containers manually:
```bash
docker compose stop
Manual Start
Start DVWA only when needed:
docker compose start
```bash
## Docker Troubleshooting
Common issues and solutions for Docker deployments.
### Viewing Logs
**Docker Desktop:**
1. Open Docker Desktop application
2. Navigate to "Containers" tab
3. Find `dvwa` project
4. Click on container name to view logs
**Command Line:**
```bash
docker compose logs -f
Port Already in Use
Error:
Error starting userland proxy: listen tcp4 0.0.0.0:4280: bind: address already in use
Solutions:
- Check what’s using the port:
2. Change DVWA port in `compose.yml`:
```yaml
ports:
- 127.0.0.1:8080:80
Database Connection Failed
Error in DVWA setup page:
Database Error: Connection refused
Solutions:
- Verify database container is running:
2. Check database logs:
```bash
docker compose logs db
-
Ensure
DB_SERVER=db in environment variables
-
Restart containers:
### MariaDB Won't Start
Error in logs:
[Warn] [Entrypoint]: /sys/fs/cgroup/memory.pressure not writable
**Solution:**
Add volume mount to `compose.yml`:
```yaml
db:
volumes:
- dvwa:/var/lib/mysql
- /sys/fs/cgroup/memory.pressure:/sys/fs/cgroup/memory.pressure
This is typically a memory constraint issue on the host. Consider:
- Upgrading to a larger instance (cloud hosting)
- Increasing Docker memory limits (Docker Desktop)
Check logs for errors:
docker compose logs
```bash
Common causes:
- Database initialization failure
- Permission issues
- Port conflicts
### File Permission Issues
With volume mounts, you may encounter permission errors.
**Solution:**
Fix ownership:
```bash
sudo chown -R www-data:www-data hackable/uploads/
sudo chmod -R 755 hackable/uploads/
Or run from within container:
docker compose exec dvwa chown -R www-data:www-data /var/www/html/hackable/uploads/
```bash
### Complete Reset
If nothing else works:
```bash
# Stop and remove everything
docker compose down -v
# Remove images
docker rmi ghcr.io/digininja/dvwa:latest
docker rmi mariadb:10
# Clean Docker system
docker system prune -a
# Start fresh
docker compose up -d
Security Considerations
DVWA is intentionally vulnerable. Never expose it to the internet or untrusted networks.
Best Practices
- Localhost only - Keep the
127.0.0.1 binding
ports:
- 127.0.0.1:4280:80 # Safe
2. **Isolated networks** - Only use on:
- Local machine
- Isolated lab networks
- NAT-mode virtual machines
3. **No production** - Never run alongside production services
4. **Regular cleanup** - Remove when not in use:
```bash
docker compose down -v
- Firewall rules - Ensure Docker ports are not exposed externally
Network Isolation
DVWA creates an isolated Docker network:
networks:
dvwa:
```bash
This ensures:
- DVWA and database can communicate
- Other containers cannot access DVWA network
- Network traffic is isolated
## Next Steps
<CardGroup cols={2}>
<Card title="Configure DVWA" icon="gear" href="/configuration/setup">
Set up configuration file and options
</Card>
<Card title="Database Setup" icon="database" href="/configuration/database">
Initialize the DVWA database
</Card>
<Card title="Start Testing" icon="flask" href="/vulnerabilities">
Begin exploring vulnerabilities
</Card>
<Card title="Security Levels" icon="shield" href="/configuration/security-levels">
Understand difficulty levels
</Card>
</CardGroup>