Docker 容器连接
端口映射、容器间通过自定义网络互访、link 的过时用法。
Key Points容器之间用自定义 bridge 网络、按容器名互访;对外暴露才用 -p,不要把数据库端口映射到公网。
端口映射
Bash
docker run -d -p 8080:80 nginx # 宿主 8080 → 容器 80
docker run -d -p 127.0.0.1:8080:80 nginx # 只监听回环,外网访问不到
docker run -d -P nginx # 随机映射,docker ps 看实际端口容器之间怎么通信
On the default bridge, containers can only reach each other by IP, which changes on every recreate. Create a user-defined network and Docker's embedded DNS resolves container names.
Bash
docker network create app-net
docker run -d --name db --network app-net -e MYSQL_ROOT_PASSWORD=secret mysql:8
docker run -d --name api --network app-net -e DB_HOST=db myapi:1.0
# api 容器里直接 ping db / 连 db:3306 即可
docker exec -it api ping -c1 db三种网络驱动
| Driver | Use | DNS by name |
|---|---|---|
| bridge | Default, single host | Only on user-defined |
| host | No isolation, shares host ports | N/A |
| none | No networking | No |
| overlay | Multi-host (Swarm) | Yes |
link 已经过时
Bash
# 旧写法,仅为兼容保留
docker run -d --name api --link db:db myapi:1.0--link is one-way and breaks with scaling; it is deprecated. A user-defined network plus container names does the same job better.
从宿主机访问容器
Bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
curl http://127.0.0.1:8080 # 通过映射端口Do not publish database or Redis ports. If you need temporary access, bind to
127.0.0.1:3306 only.端口映射
Bash
docker run -d -p 8080:80 nginx # 宿主 8080 → 容器 80
docker run -d -p 127.0.0.1:8080:80 nginx # 只监听回环,外网访问不到
docker run -d -P nginx # 随机映射,docker ps 看实际端口容器之间怎么通信
默认 bridge 网络上的容器只能靠 IP 互访,而 IP 每次重建都会变。正确做法是建一个自定义网络,Docker 内置 DNS 会按容器名解析。
Bash
docker network create app-net
docker run -d --name db --network app-net -e MYSQL_ROOT_PASSWORD=secret mysql:8
docker run -d --name api --network app-net -e DB_HOST=db myapi:1.0
# api 容器里直接 ping db / 连 db:3306 即可
docker exec -it api ping -c1 db三种网络驱动
| 驱动 | 用途 | 按名解析 |
|---|---|---|
| bridge | 默认,单机 | 仅自定义网络支持 |
| host | 无隔离,直接用宿主端口 | 不适用 |
| none | 无网络 | 否 |
| overlay | 跨主机(Swarm) | 是 |
link 已经过时
Bash
# 旧写法,仅为兼容保留
docker run -d --name api --link db:db myapi:1.0--link 只能单向连接、不支持动态扩缩容,官方已不推荐。用自定义网络 + 容器名即可,效果一样且更灵活。
从宿主机访问容器
Bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
curl http://127.0.0.1:8080 # 通过映射端口数据库、Redis 这类只给容器内部用的服务不要
-p 3306:3306。要临时连进去调试,就映射到 127.0.0.1:3306。