Docker 网络与存储:容器之间怎么通信、数据放哪
Docker 入门之后最先撞上的两个问题:容器之间怎么访问?数据存在哪、删容器会不会丢?这篇讲清这两件事。
一、网络模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
| bridge | 默认,容器在私有网段,通过 NAT 出网 | 绝大多数 |
| host | 直接用宿主机网络栈,无隔离 | 需要最高网络性能 |
| none | 无网络 | 离线任务 |
| container | 共享另一个容器的网络 | sidecar 模式 |
docker network ls
docker network inspect bridge
# 自定义网络(推荐,自带 DNS 解析)
docker network create app-net
docker run -d --name web --network app-net nginx
docker run -d --name db --network app-net postgres二、容器之间怎么访问
用容器名(或服务名)当主机名,Docker 内置 DNS 会解析:
# 在 web 容器里
docker exec web ping db # 通
docker exec web curl http://db:5432# compose 里更简单,服务名即主机名
services:
web:
image: nginx
depends_on: [db]
db:
image: postgres:16-alpine
# web 里连数据库写 db:5432三个高频坑
- 容器内不能用 127.0.0.1 访问其他容器 —— 每个容器有独立网络栈,localhost 是它自己;
- 容器内访问宿主机用
host.docker.internal(Docker 20.10+)或172.17.0.1(bridge 网关); - 默认 bridge 网络不解析容器名,必须用自定义网络(
docker network create)。
# 查 bridge 网关地址
docker network inspect bridge | grep Gateway
# Linux 上让 host.docker.internal 可用
docker run --add-host=host.docker.internal:host-gateway ...三、端口映射
docker run -p 8080:80 nginx # 宿主机 8080 → 容器 80
docker run -p 127.0.0.1:8080:80 nginx # 只监听本机(推荐)
docker run -P nginx # 随机映射所有 EXPOSE 端口ports:
- "127.0.0.1:8080:80" # 只有本机可访问,外网靠 Nginx 反代强烈建议加
127.0.0.1:。直接-p 8080:80会绕过 ufw 防火墙(详见「iptables 与 nftables」那篇),等于把服务直接暴露到公网。
四、存储:三种方式
| 方式 | 写法 | 特点 |
|---|---|---|
| volume | -v mydata:/data | Docker 管理,推荐,易备份迁移 |
| bind mount | -v /host/path:/data | 直接挂宿主机目录,方便改配置 |
| tmpfs | --tmpfs /tmp | 内存,重启丢失 |
# volume
docker volume create pgdata
docker run -v pgdata:/var/lib/postgresql/data postgres
docker volume ls
docker volume inspect pgdata
# bind mount(改配置很方便)
docker run -v /srv/nginx.conf:/etc/nginx/nginx.conf:ro nginx
# 匿名卷(不推荐,难管理)
docker run -v /data postgres选择建议:
- 数据库数据 → volume;
- 配置文件 → bind mount(只读
:ro); - 日志 → bind mount 到宿主机,方便 logrotate;
- 临时文件 → tmpfs。
五、数据会丢吗
| 操作 | volume 数据 | 容器内非挂载目录 |
|---|---|---|
docker stop / start | 保留 | 保留 |
docker rm 删容器 | 保留 | 丢失 |
docker compose down | 保留 | 丢失 |
docker compose down -v | 丢失 | 丢失 |
docker volume rm | 丢失 | — |
所以:数据库必须挂 volume,
docker compose down别加-v(除非你确定要清库)。
六、备份与迁移 volume
# 备份:起个临时容器打包
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
tar czf /backup/pgdata-$(date +%F).tar.gz -C /data .
# 恢复
docker run --rm -v pgdata:/data -v $(pwd):/backup alpine \
tar xzf /backup/pgdata-2026-05-07.tar.gz -C /data
# 或者先导出数据库逻辑备份(更可靠,可跨版本)
docker exec db pg_dump -U postgres mydb > mydb.sql七、看容器用了多少磁盘
docker system df # 总览
docker system df -v # 明细
# /var/lib/docker 占多少
du -sh /var/lib/docker
du -sh /var/lib/docker/*| sort -rh | head
# 清理
docker container prune # 停止的容器
docker image prune -a # 未使用的镜像
docker volume prune # 未使用的卷(谨慎)
docker system prune -a # 全部(谨慎)
docker volume prune会删掉「没有被任何容器引用」的卷。如果你刚down了服务,数据卷就变成未引用了——别在停机维护时跑这条。
八、日志膨胀
容器日志默认无限制增长,能把磁盘写满:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}写进 /etc/docker/daemon.json,重启 Docker 生效(只对新建容器有效)。
# 单个容器日志在哪
docker inspect --format='{{.LogPath}}' <容器>
# 紧急清空某个容器的日志
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' <容器>)九、迁移 /var/lib/docker
空间不够时把 Docker 数据目录挪到大盘:
sudo systemctl stop docker
sudo rsync -avz /var/lib/docker/ /data/docker/
sudo vim /etc/docker/daemon.json
# {"data-root": "/data/docker"}
sudo systemctl start docker
docker info | grep "Docker Root Dir"记住两句:容器之间用服务名访问,重要数据一定挂 volume。
