Docker port mapping 8080:80 explained (not localhost:8080:80)
What -p 8080:80 and ports: "8080:80" mean in Docker: the first number is on your computer, the second is inside the container. Which URL to open and how to fix it.
In Docker, <code>8080:80</code> is not a web address. It is a pair of port numbers written HOST:CONTAINER. The first number is the port on your computer, and the second is the port the program uses inside the container. You open <b>http://localhost:8080</b>, never <code>localhost:8080:80</code>.
How to use a port mapping
- Read the mapping from left to right: HOST_PORT:CONTAINER_PORT. Only the left number is used from your computer.
- Open http://localhost: followed by the left number, for example http://localhost:8080.
- Check what is really published with
docker ps. The PORTS column shows lines such as0.0.0.0:8080->80/tcp.docker port NAMEshows one container’s mappings. - If you want a different address on your computer, change the left number only, then recreate the container.
- Other containers on the same Docker network use the container name and the right number, not your computer’s port.
Commands you can copy
docker run -d -p 8080:80 --name web nginxdocker run -d -p 127.0.0.1:8080:80 --name web nginxservices:
web:
image: nginx
ports:
- "8080:80"docker ps
docker port webExamples: what to type in the browser or client
| Mapping | Meaning | Open or connect to |
|---|---|---|
| -p 8080:80 | Your port 8080 goes to port 80 in the container | http://localhost:8080 |
| -p 8081:80 | A second container, also port 80 inside | http://localhost:8081 |
| -p 5433:5432 | PostgreSQL inside uses 5432; you reach it on 5433 | localhost, port 5433 (a database client, not a browser) |
| -p 3306:3306 | MySQL on the same number on both sides | localhost, port 3306 |
| -p 127.0.0.1:8080:80 | Only your own computer can use it | http://localhost:8080 |
| -p 8080:80/udp | The UDP port, not TCP | A UDP client on port 8080 |
Docker’s documentation describes the host IP and protocol parts of the -p flag. Database ports are not web pages, so a browser shows nothing useful there.
If it does not work
- localhost:8080:80 shows an error or a search page
- That text is a port mapping, not a URL. A web address has only one port: http://localhost:8080. The same goes for localhost:8081:80, localhost:5433:5432 and localhost:3306:3306.
- Compose: always quote the mapping
- Docker’s Compose reference warns that YAML can read numbers like
22:22as a base-60 value, so write"8080:80"as a quoted string. - The page refuses to connect after I published the port
- Publishing is not enough. The app inside the container must listen on 0.0.0.0, not only on 127.0.0.1, and the right number must match the port the app really uses. See the refused to connect checklist.
- EXPOSE in the Dockerfile did not open the port
- EXPOSE only documents the port. To reach it from your computer, publish it with -p or with ports: in Compose.
- Port is already allocated
- Another container or program holds the left number. See Docker: port is already allocated.
- Published ports are visible to other computers
- Without a host IP, a published port is available to the outside world as well as your computer, and Docker’s documentation says publishing is insecure by default. Use
127.0.0.1:in front, as in-p 127.0.0.1:8080:80, to keep it on your computer. - My app in another container cannot connect
- Between containers on the same network, use the container or service name with the right number, for example
db:5432. See Docker container cannot reach localhost.
Questions about Docker port mapping
- What does 8080:80 mean in Docker?
- Port 8080 on your computer is forwarded to port 80 inside the container. You open localhost:8080.
- Which number is which?
- The left number is the host (your computer). The right number is the container. Remember it as FROM your side TO the container.
- Can I use the same left number twice?
- No. Each host port can belong to only one container or program at a time. Use 8081:80 for the second container.
- Why does 5433:5432 appear for PostgreSQL?
- The database always uses 5432 inside the container. Using 5433 on your computer avoids a clash with a PostgreSQL that is already installed there.
- What is -P (capital)?
- It publishes the container’s exposed ports to random free ports on your computer. Use docker ps to see which.
Free tools that help
- Common ports listSearch a list of common TCP and UDP port numbers: SSH 22, HTTP 80, HTTPS 443, MySQL 3306, PostgreSQL 5432 and more, with dev server ports.
Config generators for this
- Dockerfile for Node.jsA small, working Dockerfile for a Node.js app, with build step, non-root user and health check options.
- Dockerfile for PythonA working Dockerfile for a Python web app, with Gunicorn, Uvicorn or a plain script.
- docker-compose for MySQLRun a local MySQL database in Docker with your own user, password and port, and keep the data between restarts.
- docker-compose for PostgreSQLRun a local PostgreSQL database that keeps its data.
- docker-compose for MongoDBRun a local MongoDB database with a password that keeps its data.
- docker-compose for RedisRun Redis in Docker with a password, saved data and a memory limit.
- docker-compose for WordPressRun WordPress and its database locally in Docker with one command and keep your site between restarts.
- Docker Compose for MailpitRun a fake mail server on your computer, so test emails from your app show up in a web page instead of being sent.
- Docker Compose for MySQL and phpMyAdminRun MySQL and the phpMyAdmin web page on your computer with one docker compose command.
- Docker Compose for PostgreSQL and pgAdminRun PostgreSQL and the pgAdmin web page on your computer with one docker compose command.