Ian's blog
Jun 13 2020

Building a Pentest lab with Docker

What is Docker?

Docker Logo

Docker is a container platform that is similar to a Hypervisor like Virtualbox. Containers use less storage and RAM and are portable.

Docker can run on:

In this article I will go over how to set up a penetration testing lab entirely in docker

It will consist of two types of containers.

  1. Attacker Machine
  2. Target Machines

Installation on Linux

The Docker engine is in the official repositories of most Linux distributions.


Anything that uses apt to install software is Debian based.

To install docker:

$ sudo apt install docker.io


To install on fedora:

$ sudo dnf install docker

Start the Docker service

$ sudo systemctl start docker


To install Arch based distros:

$ sudo pacman -Syu

Enable the loop kernel module

$ sudo tee /etc/modules-load.d/loop.conf <<< "loop"
$ modprobe loop

Install Docker

$ sudo pacman -S docker

Start and enable the service

$ sudo systemctl start docker.service
$ sudo systemctl enable docker.service

Hello World

After you have installed docker, run this command as a test

$ sudo docker run hello-world

If it completes successfully, you can follow along

![](/img/docker-lab/Server status-pana.svg)

The Network

The network will be called vulnerable. It will have a 10.0.0/24 subnet

Create it with this command

$ sudo docker network create vulnerable --attachable --subnet

Attacker Container

For this, I will use Parrot OS. It’s docker images are better Kali Linux Images.

First download the Parrot OS Docker image. This command will take a while depending on your internet connection.

$ docker pull parrotsec/security:latest

Create and run the container .

sudo docker run \
    --name parrot \
    -it \
    --hostname parrot \
    --network vulnerable \
    --ip="" \
    --env DISPLAY=$DISPLAY \
    -v /dev/shm:/dev/shm \
    --device /dev/snd \
    --device /dev/dri \
    --mount type=bind,src=/tmp/.X11-unix,dst=/tmp/.X11-unix \
    parrotsec/security:latest \

All tools available in Parrot OS are now an apt-get away.

Use this command to restart the parrot OS container after a reboot.

$ sudo docker start -a parrot

Target container:Metasploitable2

This is a very vulnerable test machine. It is what I recommend for anyone starting out.

Open another terminal and pull the metasploitable image. The image is around 500MB.

$ docker pull tleemcjr/metasploitable2

To run a metasploitable container:

docker run \
    -it \
    --network vulnerable \
    --ip="" \
    --name metasploitable \
    --hostname metasploitable2 \
    tleemcjr/metasploitable2 \

You should see a terminal prompt like this


Start the vulnerable services

root@metasploitable2:/# services.sh

You can now access metasploitable from

If you want to stop the container, close the terminal with CTRL + D

Run this command to start metasploitable again

$ sudo docker start -a parrot

Then start the vulnerable services.

root@metasploitable2:/# services.sh

Guides & Tutorials

There are tons of free guides out there on metasploitable.

  1. The Easiest Metasploit Guide You’ll Ever Read
  2. Metasploit Unleashed
  3. Metasploitable 2 Exploitability Guide
  4. Youtube Tutorials

If you don’t know what guide to use, I recommend this one.

More vulnerable containers 🧑‍💻

You can extend the lab with any of these containers depending on your learning goal.

OWASP Juiceshop

This container focusses on web application security.

To create and start the juiceshop container for the first time

docker run -d \
    --name juiceshop \
    --network vulnerable \
    --ip="" \

Check if it is running

$ docker ps

Access the web interface from this URL

Stop the container when you’re done

docker stop juiceshop

Start the container again

docker start juiceshop

Juiceshop Guides

OWASP Webgoat 🐐

Webgoat is a ctf-style vulnerable container focused on web application security.

Create and run the container for the first time

docker run  -d \
    --name webgoat \
    --network vulnerable \
    --ip="" \
    -e TZ=$(cat /etc/timezone) \

Access Webgoat and Webwolf from these URLs

To stop the container

docker stop webgoat

To Start the container again.

docker start webgoat

If you can’t access the url, check if it is running.

$ docker ps -a

Why I use docker for a pentest lab

Two Operating systems make my computer painfully slow. Containers aren’t resource-intensive and perform well. This fits my use case.

If you have RAM to spare then it’s really not that much of a difference.

When not to use Docker

If you want to run Windows containers on a Linux host. You can run linux containers on WIndows though

Common Docker Commands

Stop a container:

$ sudo docker stop containerName

Start a container

$ sudo docker start containerName

List running and stopped containers

$ sudo docker ps -a

Spawn a bash shell in a running container

$ sudo docker exec -it containerName bash

Docker has tab completion for each of these commands.

Graphical apps inside docker

Sometimes you may want to run a GUI tool like firefox or burpsuite.

The Parrot OS commands above are already set for running graphical apps. You only need to install these packages

$ apt install hicolor-icon-theme \
    libcanberra-gtk* libgl1-mesa-dri \
    libgl1-mesa-glx libpangox-1.0-0 \
    libpulse0 libv4l-0 fonts-symbola \

You can run a few commands to avoid some errors encountered when running GUI apps


Burp Suite is a web app pentesting tool for monitoring http requests and responses.

To install and run burpsuite inside the parrot os container.

# sudo apt update
# sudo apt install burpsuite
# java -jar -Xmx2G /usr/bin/burpsuite

You can then point your browser to use as the proxy and burp will intercept everything


Firefox, is a free and open-source web browser.

To install and run firefox:

$ apt install firefox ca-certificates


Illustrations from Freepik

Further reading/research

Jess Frazelle has written an awesome blog post with details on running graphical apps inside Docker containers. She’s also given this awesome Talk/Demo on running various applications and retro games inside docker containers.