docker expose port can mean three different things: documenting a port with EXPOSE, publishing a container port to your host with -p, or making that host port reachable by someone outside your machine.
Docker handles the first two. A tunnel handles the third when you need to send a browser link for review.
docker expose port versus publish
Docker’s EXPOSE instruction does not publish a port. The Dockerfile reference says EXPOSE informs Docker that the container listens on a port at runtime. It works as documentation between the image author and the person running the container.
Example Dockerfile:
FROM nginx:alpine
COPY ./site /usr/share/nginx/html
EXPOSE 80
That image says the app expects port 80. It does not make the container reachable from your host browser by itself.
To publish the port, use docker run -p:
docker run --rm -p 8080:80 my-site
Now traffic to http://localhost:8080 on your machine forwards to port 80 inside the container.
The Docker docs also show -P or --publish-all, which publishes all exposed ports to ephemeral host ports:
docker run --rm -P nginx
docker ps
Use docker ps to see which host port Docker chose.
Make a Docker container reachable on localhost
For local browser testing, publish a host port and open it.
docker build -t review-app .
docker run --rm -p 3000:3000 review-app
Then open:
http://localhost:3000
With Docker Compose, use the ports field:
services:
app:
build: .
ports:
- "3000:3000"
Then start it:
docker compose up
This solves access from your machine, not from a remote client, QA teammate, or investor. Their localhost points to their machine, not yours.
Make a Docker container public for review
Once the container is published to a host port, tunnel that host port.
docker run --rm -p 3000:3000 review-app
npx wiremaven-cli 3000 --expires 30m --name docker-review
wiremaven creates a temporary encrypted public link for the local dev server or container reachable on that host port. Your machine opens an outbound-only WebSocket connection to the relay. The reviewer gets a browser link. You see viewer joins, request outcomes, failures, and the remaining TTL.
During beta, no account is required. You can choose 15, 30, or 60 minute review windows.
This is useful when the app runs in Docker but the review problem is still a localhost problem. The container is on your machine. The reviewer is somewhere else. The tunnel bridges that gap without a staging deployment.
EXPOSE, -p, and tunnel compared
| Step | Command or config | What it does | Who can use it |
|---|---|---|---|
| Document port | EXPOSE 3000 | Records intended container port | Image users and tooling |
| Publish to host | -p 3000:3000 | Maps host port to container port | Your machine, and sometimes LAN |
| Share publicly | npx wiremaven-cli 3000 | Creates a temporary public HTTPS link | Remote reviewer with the URL |
If you only need local testing, stop after -p. If you need a remote review link, add a tunnel. If you need release validation, deploy to staging.
Common Docker port mistakes
Mistake one: adding EXPOSE and expecting localhost to work. You still need -p or Compose ports.
Mistake two: reversing the port order. -p 8080:80 means host 8080 goes to container 80. The left side is the host port. The right side is the container port.
Mistake three: binding a sensitive service to all interfaces. Docker’s docs warn that published ports can be available on all network interfaces by default. Be careful with databases, admin panels, and internal APIs.
Mistake four: sending http://localhost:3000 to a client. That address will open the client’s machine. Send a tunnel URL instead.
Mistake five: using staging for every container review. Staging is useful for release checks. It can slow feedback when the reviewer only needs the current local build.
When to use staging instead
Use staging when:
- The review needs shared test data.
- Multiple reviewers need access over days.
- You need production-like auth, storage, queues, or domains.
- You need deployment artifacts for signoff.
Use a tunnel when:
- The review lasts 15, 30, or 60 minutes.
- The app is already running in Docker on your machine.
- You want viewer and request signals during the session.
- You do not want a staging deploy for draft feedback.
For setup details, read the wiremaven docs. For the relay model, read how wiremaven works.
FAQ
Does Docker EXPOSE publish a port?
No. EXPOSE documents the port the container listens on. Use docker run -p HOST_PORT:CONTAINER_PORT to publish it to your host.
How do I access a Docker container on localhost?
Publish the container port to a host port, such as docker run -p 8080:80 nginx, then open http://localhost:8080.
How do I share a Docker container with a client?
Publish the container to a host port, then create a temporary public tunnel link for that port.
Is publishing a Docker port safe?
It depends on what you publish and where it binds. Do not publish databases, admin panels, or sensitive services without access controls.
Start with the host port
Run the container, confirm it on localhost, then create the review link.
docker run --rm -p 3000:3000 review-app
npx wiremaven-cli 3000 --expires 30m
Related: What Is a Localhost Tunnel? | How to Share Localhost with a Client | HTTPS Localhost: mkcert, Self-Signed Certs, and Tunnels