docker和docker compose中的网络

一切的问题根源都来自于我用 docker compose 来启动 npm 容器，我发现 网上的其他教程都是可以通过 docker0 网关来访问的，但是 docker compose 编排的容器每个容器都不在同一个子网，造成 docker0 网关访问不到，也是自己才疏学浅，实践太少了。

docker 网络中的 host 和 bridge 模式

想要使用 docker，那就必须对 docker 中的两个基础网络模式有所了解，这样才能知道出错后如何的调试。

host 模式

主机模式 ，docker 中如果使用host 模式，那么该容器类似于宿主机直接运行的应用，它不需要配置端口映射，因为它就是宿主机下的应用，使用的端口直接是宿主机上的端口。该模式的优势在于无论是通过宿主机访问容器 、容器访问宿主机 和容器访问容器 都可以通过localhost:port 或者127.0.0.1:port 来直接访问，简单来说host 模式可以认为没有容器网络的概念，同时因为直接访问不需要流量的转发，所以网络上来说是最快的方式。劣势也是非常的明显，那就是宿主机和容器网络之间没有隔离，端口的使用上要注意是否冲突等。没有网络隔离的容器应用还是 docker 的目的嘛？

bridge 模式

NAT 模式， docker 容器创建时如果未指定网络模式，那么默认就是bridge 模式，创建时会自动创建一个appname_default 的网络。该模式的优势在于宿主机和容器网络是隔离的，通过docker0 网关来相互访问，同时因为使用NAT 那么不同的容器应用网络就可以自由的配置，比如某些应用在一个子网内，另外一些应用在另外一个子网内。劣势在于NAT 需要流量转发，网络性能要差一些，同时宿主机到容器 ，容器到容器 的访问都是比较简单的，但是容器到宿主机 的访问就比较麻烦了。

两种模式没有绝对的优和差，更多的还是适用的场景不同。

NPM 的两种网络模式配置

如果你是用docker 命令行的方式来运行的容器，那么你可以直接用docker0 的网关：端口，如172.17.0.1:prot 来访问其他的容器。
如果你是用docker compose 配置文件启动的容器，我相信你会出现和我一样的网络问题，那就是172.13.0.1:port 访问不到其他的容器，同时也无法访问宿主机，这对于npm 是致命的，因为这样以来npm 毫无意义。

Docker compose 下的host 模式

使用host 模式是配置 npm 最简单的方法，如果你运行的容器不多，同时端口也没有冲突，不需要过多的关注细节，那么这种模式是最优的。而需要做的也只是在每个docker-compose.yml 文件中将network_mode: "host" 这一行添加到容器应用中即可。这样一来，你可以直接在npm 配置中的hostname/IP 这一项中填入localhost 或者127.0.0.1 即可访问其他容器以及宿主机应用。

Docker compose 下的bridge模式

bridge 模式下有两种配置方式来通信

通过 docker 命令行来组建内网
好处是不需要改动配置文件，坏处是每次停止容器都需要重新将该容器的网络加入到子网中

创建一个网络 $ docker network create npm

把其他容器加入到该网络$ docker network connect npm <容器的名字>

查看npm网络下有哪些容器以及 ip $ docker network inspect npm

可以用容器的名字 互相访问，比如有一个alist 容器加入到网络，可以在npm 容器中用ping alist 来访问。npm 中的hostname/IP 也可以用容器的名字

通过docker-compose.yml 配置网络
例如：npm 的docker-compose.yml

Copy
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
networks:
- npm
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

networks:
npm:
driver: bridge

alist 的docker-compose.yml

Copy
version: '3.3'
services:
alist:
restart: always
volumes:
- '.data/alist:/opt/alist/data'
networks:
- npm
ports:
- '5244:5244'
environment:
- PUID=0
- PGID=0
- UMASK=022
container_name: alist
image: 'xhofe/alist-aria2:latest'
networks:
npm:
driver: bridge

如果npm 网络已经通过其他命令创建了，那么可以通过外链的形式

Copy
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
networks:
- npm
ports:
- '80:80'
- '81:81'
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt

networks:
npm:
external: true

Docker compose 下的link 模式

我用的不多，参考官方文档吧

Enjoy!

docker 很好，只要玩的转。

参考：[docker network 官方文档](Networking in Compose | Docker Docs)