Skip to content
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after any top-up. Until Nov 30.

How it works

OWASP Juice Shop with Docker: a local practice lab

Run OWASP Juice Shop in a Docker container bound to your own machine, confirm it responds, and stop it cleanly.

Beginner5 min readBy NotHoly

OWASP Juice Shop is an intentionally vulnerable web application. You can run it in a Docker container on your own computer, open it in a browser at http://127.0.0.1:3000, and practice web security on it without touching anyone else's systems. The project says it includes vulnerabilities from the entire OWASP Top Ten, plus others found in real applications. Below are the commands, what to check after each one, how to keep the port private, and how to stop the lab.

What you need

  • A computer you own or administer, with permission to run Docker on it.
  • Docker Engine or Docker Desktop. Install it from the official Docker documentation for your operating system.
  • A browser with developer tools. Chrome, Firefox and Edge all include them.
  • Enough disk space and memory for one container. The image size depends on the tag you pick, so check its Docker Hub page first.

Juice Shop contains flaws on purpose. Keep it on a machine and network you control, and never expose it to the internet.

1. Check that Docker is working

Run these two commands in a terminal:

bash
docker --version
docker info

The first command prints the Docker CLI version. The second contacts the Docker engine and prints its configuration. If docker info reports that it cannot connect to the daemon, start Docker Desktop or the Docker service, then run the command again. The exact error text depends on your platform, so follow Docker's install documentation if the fix is not obvious.

2. Start the lab on loopback only

The project documentation names the image bkimminich/juice-shop. The project README runs it without a tag, which pulls latest. If you want a repeatable lab, pick a release tag on the Docker Hub page and append it to the image name (bkimminich/juice-shop:<tag>), so you know which version you are testing.

bash
docker run --rm --name juice-shop-lab \
  -p 127.0.0.1:3000:3000 \
  bkimminich/juice-shop

The -p flag publishes a container port on the host. The value 127.0.0.1:3000:3000 has three parts: the host address, the host port and the container port. Docker's port publishing reference explains that a mapping without an address can listen on every host interface. Putting 127.0.0.1 first keeps the lab reachable only from your own machine.

The --rm flag removes the container when it stops. The command runs in the foreground, so the terminal keeps printing logs until you stop it. The first run downloads the image, which can take a while.

Open http://127.0.0.1:3000 in a browser on the same machine. You should see the Juice Shop home page. If it does not load, read the terminal for errors, then run docker ps in a second terminal to confirm that the container is running and the port mapping is correct. VPN clients, proxies and virtual machine networks can change how local traffic behaves, so check those as well before you change any flags.

Do not change 127.0.0.1 to 0.0.0.0 to make the page load. That setting exposes the lab to other devices on your network.

3. Observe one harmless page load

Before you try any challenge, look at how the browser and the server talk. Open the developer tools, switch to the Network tab and reload the page. Pick one request and note:

  • the request method, such as GET;
  • the response status code;
  • one response header, such as Content-Type;
  • the difference between the HTML document and a JavaScript file.

You can get the same information from a terminal:

bash
curl -I http://127.0.0.1:3000

In Windows PowerShell 5.1, curl is an alias for a different command, so type curl.exe instead.

The -I option sends a HEAD request and prints only the response headers. RFC 9110 defines the methods, status codes and header fields you are looking at. These are the first lines of what the untagged image returned on one run (2026-11-08); other releases may differ:

text
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=UTF-8

Write down what your own server returns and compare.

The project documentation describes the training challenges and their hints. Read that material before you try an exploit, and keep every test pointed at 127.0.0.1. Knowing the request and response cycle first makes scanner results easier to judge later, because you can see the traffic those tools send and receive.

4. Stop and remove the lab

If the container runs in the foreground, press Ctrl+C in its terminal. Because you used --rm, Docker removes the container once it stops.

If you lost that terminal, stop the container from another one:

bash
docker stop juice-shop-lab

Docker sends a stop signal and waits for the container to exit. Confirm that the lab is gone:

bash
docker ps

If the container name does not appear in the list, the lab is stopped. Closing the browser tab does not stop the container, so check docker ps every time.

Common problems

If the port is already in use, docker run fails with Bind for 127.0.0.1:3000 failed: port is already allocated. Choose another host port, such as -p 127.0.0.1:3001:3000, and open http://127.0.0.1:3001 instead. Keep the 127.0.0.1 part.

If the container exits right away, read the logs in the terminal. Look for the first error line, not the last one.

If the first run takes a long time, Docker is downloading the image and its layers. Later runs start faster because Docker keeps the image locally.

Where a language model fits

A language model can explain a status code or help organize your notes, and NotHoly is one place to run that. It can also be wrong about what a response means, and it does not replace authorization or manual validation. Paste only output from your own lab, never session cookies, tokens or data from a real target.

Write your notes from what you observed, then compare them with the references below.

References

Sources

  1. OWASP Juice Shop project
  2. OWASP Juice Shop documentation
  3. Docker port publishing
  4. docker container run reference
  5. docker container stop reference
  6. RFC 9110, HTTP Semantics
  7. OWASP Top 10

More in Hacking labs

Hacking labs

How to Write a Good Pentest Report

Structure a pentest report and write one finding someone else can reproduce, with evidence, impact, a CVSS v4.0 vector and a fix.

Intermediate8 min read

Hacking labs

How to Build a Legal Home Lab

Build a home lab you are allowed to attack: a scope file, Docker ports bound to loopback, an isolated network, a notebook and a clean teardown.

Beginner4 min read