• 博客区Docker
  • 跨 docker-compose.yml 配置的 Docker 容器之间的网络互通

背景

一个服务器上分别用单独的 docker-compose.yml 配置了两个单机网站项目

  1. 网站项目(有 nginx、php-fpm、MySQL 等容器)
  2. caddy 反向代理

现在希望 caddy 的容器可以反向代理到项目1里面的 nginx 上,这就涉及到了容器网络互通的问题。

原配置

项目1的配置:

version: "3.6"
services:
  nginx:
    image: nginx:latest
    build: ./nginx
    container_name: site-nginx
    restart: always
    ports:
      - 8080:80
      - 8443:443
    volumes:
      - ./logs:/var/log/nginx
      - ./nginx/nginx-conf/docker-nginx.conf:/etc/nginx/nginx.conf
      - ./wwwroot:/wwwroot
      - ./.well-known:/wwwroot/.well-known

项目2的配置:

version: '3'

services:
  caddy:
    image: abiosoft/caddy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/Caddyfile
      - ./.caddy:/root/.caddy
      - ./wwwroot:/srv
      - ./logs:/opt/logs
    restart: always
    environment:
      - ACME_AGREE=true
      - TZ=Asia/Shanghai

一波操作

Docker Compose 文档 提到 Docker Compose 在不同配置文件的容器默认会用不同的 network,所以目标是让他们容器都绑定到同一个 network 上。

一番寻找发现了 network 和 external 配置,所以剩下要做的事情就是:

  1. 创建一个单独的网络(这里起名 frontend

    sudo docker network create frontend
  2. 两个项目的 docker-compose.yml 文件的所有容器的网络都指定到刚创建的网络,并标记为 external
    项目1:

    version: "3.6"
    services:
      nginx:
        image: nginx:latest
        build: ./nginx
        container_name: site-nginx
        restart: always
        ports:
          - 8080:80
          - 8443:443
        volumes:
          - ./logs:/var/log/nginx
          - ./nginx/nginx-conf/docker-nginx.conf:/etc/nginx/nginx.conf
          - ./wwwroot:/wwwroot
          - ./.well-known:/wwwroot/.well-known
        networks:
          - frontend
    
    networks:
      frontend:
        external: true

    项目2:

    version: '3'
    
    services:
      caddy:
        image: abiosoft/caddy
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - ./Caddyfile:/etc/Caddyfile
          - ./.caddy:/root/.caddy
          - ./wwwroot:/srv
          - ./logs:/opt/logs
        restart: always
        environment:
          - ACME_AGREE=true
          - TZ=Asia/Shanghai
        networks:
          - frontend
    
    networks:
      frontend:
        external: true

    3. 分别 docker-compose up -d 重建容器

    4. Caddyfile 配置文件里面指定服务名即可访问容器(Docker 会自动将容器 IP 绑定到对应的 host,用这个 host 访问即可)

    abcde.cn {
      gzip
      log /opt/logs/access.log
      tls example@gmail.com
      proxy / http://nginx
    }

    简单总结

    1. docker-compose 只是一个编排工具,相当于用配置文件描述了 docker 的命令何时执行
    2. docker-compose 在不指定 network 的配置下,会创建一个单独的 network 作为项目涉及到所有的容器的默认网络
    3. external: true 配置可以指定容器使用外部已有的网络

    Docker 容器的网络的工作细节还待探索。

  • woq 觉得很赞

读了一遍文档,发现直接把默认网络指向外部网络更快
Networking in Compose | Docker Documentation

networks:
  default:
    external: true
    name: frontend

然后就不用每一个容器都改一下 network 了= =

1 年 后

jackadam 什么叫 跨 docker-compose?

docker-compose 只是一种 docker 的编排部署工具。

我可以理解你的意思是如何让两种不同的服务容器,进行通信。
如果是这样的话,docker 创建 ipv6 的网站,然后将两个容器的网络设置在一起就行了。注意网关和 网段的配置。

或许这篇文章能给你带来帮助:https://dev.to/joeneville_/build-an-ipv6-network-with-docker-compose-434i

12 天 后

https://blog.csdn.net/bleatingsheep/article/details/80534153
Docker 对 IPv6 支持不完善之处
Docker 对 IPv6 的支持有待完善(老实说,是很差)。虽然可以使用本文前面提到的方法给容器提供 IPv6 地址,但是以下问题难以解决:

通过上述方式分配的 IPv6 地址开放了所有端口,可能存在安全问题。
必须为每个容器指定 IPv6 地址,非常麻烦,否则每次运行都可能变化。
当使用 -p 开放端口,又访问主机 IPv6 地址的该端口时,容器无法获取访问的源地址。
必须在配置文件或参数中写入固定的 IPv6 前缀。如果你的 IPv6 地址段经常变化(例如:使用家庭宽带),上述方法将完全无效。
为了解决这些问题,可以使用 IPv6 NAT 变通解决。

IPv6 NAT
我们可以使用 robbertkl/docker-ipv6nat 为 Docker 提供 IPv6 NAT 功能。
https://github.com/robbertkl/docker-ipv6nat

目前我就遇到了无法获取访问源地址的问题。
试试IPv6 NAT

2 个月 后

突然看到这个帖子,最近我也又在折腾我的网站部署方式,也是在读了官方文档之后得到的,一个 service 可以同时布两个服务~

© 2018-2025 0xFFFF