Docker 连接停靠的应用程序网络以执行api调用

Docker 连接停靠的应用程序网络以执行api调用,docker,docker-compose,Docker,Docker Compose,我在连接点方面有点问题 我成功地对接了我们的旧应用程序和新应用程序,但现在我需要让它们通过API调用彼此进行对话 项目: Project1=使用Project1\u appnet(桥接驱动程序) Project2=使用Project2\u appnet(桥接驱动程序) Project3=使用Project3\u appnet(桥接驱动程序) 在我的本地服务器上,我在3个单独的文件夹中有这3个项目。每个项目都有自己的应用程序、数据库和缓存服务 这是其中一个项目的docker compose.y

我在连接点方面有点问题

我成功地对接了我们的旧应用程序和新应用程序,但现在我需要让它们通过API调用彼此进行
对话

项目:

  • Project1=使用
    Project1\u appnet
    (桥接驱动程序)
  • Project2=使用
    Project2\u appnet
    (桥接驱动程序)
  • Project3=使用
    Project3\u appnet
    (桥接驱动程序)
在我的本地服务器上,我在3个单独的文件夹中有这3个项目。每个项目都有自己的
应用程序
数据库
缓存
服务

这是其中一个项目的
docker compose.yml
。(它们几乎都有相同的docker-compose.yml,只是图像和卷路径不同)

问题:

  • 我如何使他们能够通过API调用相互交谈?(关于我的本地开发和产品环境)
  • 在生产中,设置会有点不同,它们将在不同的机器中,但仍然在同一个专有网络中,甚至通过公共网络。设置是什么
注:

  • 我一直在查看
    链接
    ,但显然它在
    v3
    中不受欢迎,或者不推荐使用
  • 通过执行以下操作,尝试了从project1容器到project2容器的
    curl

如果您在本地运行此docker compose;给定应用程序和数据库在同一网络上-appnet-应用程序应该能够使用localhost:${db_PORT}与数据库通信


在生产中,如果app和db在不同的机器上;应用程序可能需要使用ip或域名与数据库通信。

考虑到不同的docker部署使用不同的机器,您最好将它们放在常规Web服务器(Apache2,Nginx)后面,然后使用简单的vhost将流量从特定域路由到
$app\u PORT
。我更喜欢这样做,而不是直接将容器公开给网络。这样,您还可以在同一台计算机上承载多个应用程序(如果愿意)。因此,我建议您不要尝试连接docker网络,而应该连接“常规”网络。

正在使用inspect和cURL。我想我找到了解决办法

本地:

  • 在本地,我检查了容器并查看了
    NetworkSettings.Network..Gateway
    ,即
    172.25.0.1
  • 然后我得到暴露的端口,它是
    8050
  • 然后我在app1容器中执行了一个curl
    curl 172.25.0.1:8050/login
    ,以检查
    app1
    是否可以对app2容器执行http请求。或
    docker exec-it项目1\u应用程序1 curl 172.25.0.1:8050/登录
  • 反之亦然,我为
    app2->app1
    docker exec-it项目2\u app\u 1 curl 172.25.0.1:80做了
    curl 172.25.0.1:80
唯一的问题是,当我们通过
docker compose up-d
重启时,
Gateway
值会发生变化

生产:

我对网络和其他东西不是那么专业。我估计产量为:


执行Web服务器指向应用程序的
curl app2 domain.com
,因为它们在自己的计算机中(即使有负载平衡器)。

如果最终设置为每个服务将在物理上不同的系统上运行,那么实际上没有任何选择。一个系统不能直接访问另一个系统上的Docker网络;服务1能够到达服务2的唯一方式是通过其主机的DNS名称(或IP地址)和发布的端口。因为这在不同的环境中是不同的,所以我建议将该值设置为一个已配置的环境变量

环境:
服务\u 2\u URL:'http://service-2-host.example.com/“#默认端口80
一旦您确定了这一点,您就可以对单个主机部署使用相同的设置。如果您的开发人员系统使用Docker for Mac或Docker for Windows,您应该能够使用访问其他服务

环境:
服务\u 2\u URL:'http://host.docker.internal:8082/'
(如果您在桌面上使用Linux,您必须知道主机的一些IP地址;而不是
localhost
,因为这意味着“这个容器”,而不是
docker0
接口地址,因为它将位于特定的网络上,而是类似于主机的
eth0
地址。)

您的另一个选项是“借用”另一个Docker Compose网络作为外部网络。如果所有Docker Compose设置都有相同的名称,则会有一些技巧;从一些实验来看,Docker内部DNS似乎总是首先解析为您自己的Docker Compose文件,并且您必须知道Compose分配的容器名称(不难重构且稳定)之类的内容才能到达其他服务

版本:“3”
网络:
附录2:
外部:
名称:app2_appnet
服务:
应用程序:
网络:
-应用程序网
-app2_appnet
环境:
服务\u 2\u URL:'http://app2_app_1/“#使用服务内部端口
MYSQL_HOST:db#在这个docker-compose.yml中
(我建议使用over-declaration-your-one;这将主要允许您删除文件中的所有
网络:
块,而不会产生任何不良影响,但在这种特定情况下,您需要声明
网络:[default,app2\u default]
,才能连接到这两个网络。)

您也可以考虑多宿主容器解决方案。Kubernetes有点重,但它将在集群中的任何节点上运行容器(您不必特别担心放置问题),它为您提供名称空间和自动DNS解析;您只需设置

服务\u 2\u URL:'http://app.app2/“
指向另一个名称空间,而不必担心这些网络细节。

您尝试过访问吗
version: '3'
services:
  app:
    build: ./docker/app
    image: 'cms/app:latest'
    networks:
      - appnet
    volumes:
      - './:/var/www/html:cached'
    ports:
      - '${APP_PORT}:80'
    working_dir: /var/www/html
  cache:
    image: 'redis:alpine'
    networks:
      - appnet
    volumes:
      - 'cachedata:/data'
  db:
    image: 'mysql:5.7'
    environment:
      MYSQL_ROOT_PASSWORD: '${DB_ROOT_PASSWORD}'
      MYSQL_DATABASE: '${DB_DATABASE}'
      MYSQL_USER: '${DB_USER}'
      MYSQL_PASSWORD: '${DB_PASSWORD}'
    ports:
      - '${DB_PORT}:3306'
    networks:
      - appnet
    volumes:
      - 'dbdata:/var/lib/mysql'
networks:
  appnet:
    driver: bridge
volumes:
  dbdata:
    driver: local
  cachedata:
    driver: local

root@bc3afb31a5f1:/var/www/html# curl localhost:8050/login
curl: (7) Failed to connect to localhost port 8050: Connection refused