Building a Security Testbed with Docker on Windows

In the evolving cybersecurity landscape, building a reproducible and controlled penetration testing lab is essential. Docker simplifies this by enabling modular, isolated environments. This guide walks you through creating a Docker-based security testbed on Windows using WSL 2, complete with vulnerable apps (DVWA, Metasploitable), Kali Linux, and Snort 3 for IDS testing.

Why Use Docker for Security Labs?

  • Lightweight & Isolated: Easily spin up/down labs without bloating your host OS.
  • Repeatable: Same configurations on multiple machines.
  • Safe: No permanent changes to the host network or system.
  • Scriptable: Easily defined using docker-compose.

Prerequisites

  • Windows 10/11 (64-bit, 22H2+)
  • Hardware Virtualization enabled (BIOS/UEFI)
  • WSL 2 installed
  • Docker Desktop

Step-by-Step Setup

  1. Install WSL 2
    Open PowerShell (as Admin) and run:
    wsl --install
    wsl --set-default-version 2
    

    Then restart your machine.

  2. Install Docker Desktop
    • Download from Docker’s official site
    • Run the installer, accept the license, and select WSL 2 as the backend during setup.
  3. Configure WSL Integration
    • Open Docker Desktop > Settings > General
    • Enable WSL 2 integration
    • Select your preferred Linux distributions (e.g., Ubuntu)
  4. Verify Docker Installation
    Open PowerShell and run:
    docker --version
    docker run hello-world
    

Setting Up the Pentest Lab

Here’s a breakdown of the services we’ll be using:

ContainerPurposePortNotes
DVWAVulnerable Web App (MySQL-backed)8080Web-based pentesting
KaliPenetration Testing Distro (GUI)7002Accessible via browser (KasmVNC)
MetasploitableDeliberately vulnerable OS7003Useful for scanning and exploit tests
Snort 3Intrusion Detection SystemCLI only; test alerting and signatures

docker-compose.yml

version: ‘3.8’

services:
dvwa:
image: vulnerables/web-dvwa
container_name: dvwa
ports:
– “8080:80”
networks:
– pentest-network
tty: true
stdin_open: true
restart: unless-stopped
depends_on:
– dvwa_db

dvwa_db:
image: mariadb:10.1
container_name: dvwa_db
hostname: dvwa_db
volumes:
– dvwa_db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: dvwa
MYSQL_USER: dvwa
MYSQL_PASSWORD: p@ssw0rd
restart: unless-stopped
networks:
– pentest-network

kali:
build:
context: .
dockerfile: Dockerfile.kali
container_name: kali
shm_size: ‘512m’
ports:
– “7002:6901”
environment:
– VNC_PW=password
user: “root”
networks:
– pentest-network
tty: true
stdin_open: true
restart: unless-stopped
volumes:
– kali_data:/root
command: >
bash -c “apt-get update && apt-get install -y iputils-ping traceroute whois net-tools nmap tshark wireshark hping3 nano && tail -f /dev/null”

metasploitable:
build:
context: .
dockerfile: Dockerfile.metasploitable
container_name: metasploitable
networks:
– pentest-network
tty: true
stdin_open: true
restart: unless-stopped
ports:
– “7003:80”
volumes:
– metasploitable_data:/var/lib/metasploitable

snort3:
build:
context: .
dockerfile: Dockerfile.snort3
container_name: snort3
hostname: snort3
user: “snorty”
working_dir: /home/snorty
networks:
– pentest-network
tty: true
stdin_open: true
restart: unless-stopped
volumes:
– snort_data:/etc/snort
command: >
bash -c “apt-get update && apt-get install -y iputils-ping traceroute whois net-tools nmap tshark wireshark hping3 nano && tail -f /dev/null”

networks:
pentest-network:
driver: bridge

volumes:
dvwa_db_data:
kali_data:
metasploitable_data:
snort_data:

You’ve already got the full config (shared above). Here’s what it does:

  • Spins up all 4 services in a bridge network called pentest-network
  • Maps appropriate ports for GUI (Kali via VNC), DVWA, and Metasploitable
  • Uses persistent volumes for database and tool storage
  • Configures Snort and Kali with common network tools preinstalled
  1. Launch the Environment
    Place all files, including the Dockerfile.kali, Dockerfile.metasploitable, and Dockerfile.snort3, in a working folder. Then from PowerShell:
    docker compose up --build -d
    

    This builds and runs all services in detached mode.

Interacting with the Containers

A. CLI Access
Use these commands from PowerShell:

docker exec -it kali /bin/sh
docker exec -it dvwa /bin/sh
docker exec -it metasploitable /bin/sh
docker exec -it -u root snort3 bash

Type exit to leave any session.

B. GUI/Web Access

ContainerURLCredentials
DVWAhttp://localhost:8080admin / password
Kalihttps://localhost:7002kasm_user / password

Cleanup Commands

To remove containers and free space:

docker compose down
docker system prune

Security Hardening Tips

CategoryRecommendation
Docker DaemonUse TLS with client certs for remote access. Don’t expose Docker API openly.
User PrivilegeAvoid running containers as root unless required (use user: directive).
NetworkUse isolated bridge networks; limit inter-container communication if needed.
Volume StorageAvoid mounting sensitive host folders directly.
SoftwarePeriodically update Kali, Snort, and other tools inside containers.

Bonus: Expand the Testbed

  • Adding OWASP Juice Shop, bWAPP, or Hackazon
  • Deploying a SIEM stack (like ELK Stack) alongside Snort
  • Simulating attacks from one container to another and logging alerts

Conclusion

This testbed gives you a powerful, modular, and safe playground for training, research, and enterprise-grade pentesting. With Docker’s flexibility and Windows’ wide availability, you can create robust simulation environments without the overhead of physical labs or full-blown VMs.