Installing and Using curl in Docker Desktop with WSL 2 — A Practical, No-Nonsense Guide
When you first open a Docker Desktop + WSL 2 Linux shell and type curl, only to be greeted by “command not found”, it feels wrong. After all, curl is one of the most fundamental tools in modern development.
The confusion usually comes from not knowing which Linux environment you are actually inside. Docker Desktop with WSL 2 runs multiple Linux layers, and each one has different rules.
This article explains what is really going on, where you should install curl, where you should not, and how to structure your setup professionally so this never becomes a recurring issue.
Understanding the Three Linux Environments in Docker Desktop + WSL 2
Before installing anything, you must clearly distinguish these environments:
1. Your own WSL Linux distribution (Ubuntu, Debian, Alpine, etc.)
This is what you get when you run:
wsl
or:
wsl -d Ubuntu
✔ You control it
✔ Persistent
✔ Best place for developer tools
2. docker-desktop (internal VM)
This is Docker Desktop’s internal Linux VM.
- Minimal
- Ephemeral
- Not intended for human interaction
❌ Do NOT install tools here
❌ Changes are lost on restart
You can see it using:
wsl -l -v
If you see docker-desktop, leave it alone.
3. Linux inside containers
This is the Linux environment inside a running container.
✔ Controlled by your Dockerfile
✔ Reproducible
✔ Correct place for runtime dependencies
Correct Way to Install curl (Based on Context)
Install curl in Your WSL Distro (Recommended for Developers)
If you are using Ubuntu / Debian:
sudo apt update
sudo apt install -y curl
Verify:
curl --version
This is where tools like curl, git, node, php, composer, rust, go belong.
Install curl Inside a Container (Temporary or Debugging)
If you entered a container using:
docker exec -it <container> sh
Then install based on the image:
Debian / Ubuntu image
apt update && apt install -y curl
Alpine image
apk add --no-cache curl
RHEL / UBI image
microdnf install curl
⚠️ Important:
This installation is temporary unless defined in the Dockerfile.
The Professional Way: Install curl in the Dockerfile
If your application or debugging process requires curl, the Dockerfile is the only correct place.
Debian / Ubuntu example
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
Alpine example
RUN apk add --no-cache curl
Why this matters:
- Repeatable builds
- CI/CD safe
- No “works on my machine” issues
- Team consistency
Why docker-desktop Does NOT Have curl (By Design)
This is not a bug.
Docker Desktop intentionally:
- Keeps the VM minimal
- Avoids exposing it as a development environment
- Prevents users from treating it like a normal Linux server
Any manual installation there:
- Will be lost
- Is unsupported
- Is a dead end
Docker expects tooling to live either:
- In containers
- Or in your own WSL distro
A Clean, Scalable Mental Model
Use this rule of thumb:
| Location | Purpose |
|---|---|
| WSL Ubuntu | Developer tools (curl, git, CLI utilities) |
| Dockerfile | Runtime & app dependencies |
| docker-desktop VM | Ignore completely |
If you follow this, your setup will scale from solo dev → team → CI/CD without refactoring.
Additional Points Developers Often Miss
1. curl is NOT always required at runtime
Sometimes curl is only needed for:
- Health checks
- Debugging
- Local testing
In those cases:
- Use multi-stage builds
- Keep
curlonly in the debug stage
2. Prefer wget or native HTTP libraries when possible
If your app already has:
- Node →
fetch - PHP →
Guzzle - Go →
net/http - Rust →
reqwest
Then installing curl inside production containers may be unnecessary.
3. Alpine images trade size for convenience
Alpine:
- Smaller images
- Different libc (
musl) - Different tooling
Sometimes Debian-based images are better for debugging, especially when you rely on curl, bash, or CA bundles.
4. CA certificates matter
If curl fails with TLS errors inside containers, you may need:
RUN apt-get install -y ca-certificates
or (Alpine):
RUN apk add --no-cache ca-certificates
Recommended Setup for Serious Development
Best-practice stack:
- Ubuntu WSL → daily tools
- Docker Desktop → orchestration only
- Well-defined Dockerfiles → runtime dependencies
This setup:
- Avoids confusion
- Keeps environments clean
- Matches how production actually works
Finally
If curl is missing, the problem is not the tool — it’s usually the mental model.
Once you clearly separate:
- Developer environment
- Container runtime
- Docker’s internal VM
Everything becomes predictable, clean, and maintainable.
Comments ()