Today, let's talk about docker ports in the system. Common ports include program port in container, container port, host port, EXPOSE port in Dockerfile, docker compose and port in docker run.
It seems that there are many ports, but when connecting, the real ports are only program ports and host ports. Others are declarations of ports and will not actually open the service of ports.
Next, take nginx and redis images as examples to introduce the relationship between these ports: nginx program port 80, mapping host port 30080; Redis program port 6379, mapping host port 36379. The actual communication is shown in the figure below
The program port is the container port
The program port is the actual container port. They are the same port. No other configuration is required. After the container is started, the local machine or other containers on the same network access the services of the container through the program port in the container (i.e. container port).
Take nginx as an example, start the container (web name)
[root@localhost ~]# docker run -d --name web nginx 3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3cb58fd8e585 nginx "/docker-entrypoint...." 17 seconds ago Up 15 seconds 80/tcp web
The local server verifies the access to the container port, first check the container ip, and then check the communication of port 80 by telnet. The following highlighted information indicates that the port access is normal
[root@localhost ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2[root@localhost ~]# curl http://172.17.0.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1>
. . . . .
The access to the Internet is verified, and the connection is blocked
$ curl http://192.168.8.190:80 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0 curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused
Export port in Dockerfile
- Conclusion: the export in Dockerfile is only a declaration of the port, which is displayed during ps or inspect, but does not actually open the service of the port. The actual port is determined by the port of the program in the container
1. Modify the port of nginx in the web container to 88, and the restart takes effect
[root@localhost ~]# docker exec -it web /bin/bash root@9ac59b2d523f:/# vi /etc/nginx/conf.d/default.conf modify listen The parameter value is 88 [root@localhost ~]# docker restart web web
2. Check the port of Expose in the Dockerfile file of the image: 80
[root@localhost ~]# docker history nginx IMAGE CREATED CREATED BY SIZE COMMENT 605c77e624dd 9 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon... 0B <missing> 9 days ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B <missing> 9 days ago /bin/sh -c #(nop) EXPOSE 80 0B
3. Check the port displayed in the container information: 80
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c24aa7848e38 nginx "/docker-entrypoint...." 39 seconds ago Up 37 seconds 80/tcp web
4. Verify the actual accessible port. 80 refused to connect, 88 access normal
[root@localhost ~]# curl http://172.17.0.2:80 curl: (7) Failed connect to 172.17.0.2:80; connection denied [root@localhost ~]# curl http://172.17.0.2:88 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> html { color-scheme: light dark; } body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
Container port mapping host port
- Conclusion: if the container does not specify a host mapping port, the network outside the host cannot access the container, and only the local network can access it.
1. When the container is started and the host mapping port is not specified
[root@localhost ~]# docker run -d --name web nginx 3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3cb58fd8e585 nginx "/docker-entrypoint...." 17 seconds ago Up 15 seconds 80/tcp web
Internet access to host port 80 is blocked
2. Start the container and specify host mapping port 30080 mapping container port 80
[root@localhost ~]# docker run -d -p 30080:80 --name web nginx 04ef8440c357b81da934e91e786612b6027d20ea2e7cb3bd81ae91a9ca15a807
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04ef8440c357 nginx "/docker-entrypoint...." 8 minutes ago Up 8 minutes 0.0.0.0:30080->80/tcp, :::30080->80/tcp web
Internet access to host 30080 succeeded
Supplement: use - p to map ports in docker run and - port to map ports in docker compose. The effect is the same.
Connection between containers
Access the started container web above, container port 80, mapping host port 30080, container ip: 172.17.0.2, host ip: 192.168.8.190
- Summary: container ip: container port, host ip: host port. Access can only be accessed when the ip matches the port.
Start a redis container and access the web container service from the redis container.
[root@localhost ~]# docker run -d --name redis redis:6.0.8[root@localhost ~]# docker exec -it redis /bin/bashroot@25d8d484aa5b:/data# curl http://172.17.0.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...........root@25d8d484aa5b:/data# curl http://172.17.0.2:30080
curl: (7) Failed to connect to 172.17.0.2 port 30080: Connection refusedroot@25d8d484aa5b:/data# curl http://192.168.8.190:30080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
............root@25d8d484aa5b:/data# curl http://192.168.8.190:80
curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused