A CTF Practice Environment with Docker

Tutorial · General

A lot of practice CTF content ships as a Docker image specifically so you can run the vulnerable target locally, isolated from your real system, and reset it instantly if you break or crash it.

1. Installing Docker

Install Docker Desktop (Mac/Windows) or Docker Engine (Linux) from docker.com, then confirm it's working:

docker --version
docker run hello-world

2. Pulling and running a target

Most vulnerable-practice images are published on Docker Hub. Pull one and run it, mapping its internal port to one on your own machine:

docker pull vulnerables/web-dvwa
docker run -d -p 8080:80 vulnerables/web-dvwa

The target is now reachable at http://localhost:8080 — isolated inside the container, with nothing it does able to touch your actual filesystem.

3. Resetting instantly when something breaks

Practice challenges sometimes end up in a broken state after an exploit attempt (a crashed service, a corrupted database). Rather than debugging the container's internal state, just throw it away and start fresh:

docker rm -f $(docker ps -aq --filter ancestor=vulnerables/web-dvwa)
docker run -d -p 8080:80 vulnerables/web-dvwa

This is the actual point of containerizing practice targets — a clean restart costs seconds, not a system reinstall.

4. Building your own target from a Dockerfile

For a custom practice setup (your own deliberately vulnerable script, a specific library version with a known CVE), a minimal Dockerfile is usually enough:

FROM python:3.11-slim
COPY vulnerable_app.py /app/
WORKDIR /app
CMD ["python3", "vulnerable_app.py"]

Build and run it the same way: docker build -t my-target . && docker run -p 8080:8080 my-target.

Wrapping up

Once you're comfortable running targets this way, OverTheWire's Bandit wargame is a natural next step that needs no Docker at all — just SSH. Our Bandit Level 0 writeup covers getting started there, and how CTF scoring works if you're about to join a timed event for the first time.

← Back to Blog