如何正确链接两个容器?

时间:2018-08-01 10:36:06

标签: php docker nginx docker-compose

这是一个新手问题,因为我仍在尝试了解容器如何相互“通信”。

这大致就是我的docker-compose.yml的样子

...
  api:
    build: ./api
    container_name: api
    volumes:
      - $HOME/devs/apps/api:/var/www/api

  laravel:
    build: ./laravel
    container_name: laravel
    volumes:
      - $HOME/devs/apps/laravel:/var/www/laravel
    depends_on:
      - api
    links:
      - api    
...
  nginx-proxy:
    build: ./nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
    links:
      - api
      - laravel
      - mysql-api

nginx的配置有一些块,这些块指向由这2个php-fpm容器公开的上游,例如:

  location ~* \.php$ {
    fastcgi_pass            laravel:9000;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_index           index.php;
    include                 fastcgi_params;
  }

类似于api块。

我可以从Web浏览器/邮递员(从主持人)单独访问每个容器。

在laravel应用程序内部,有一些php_curl可以调用api服务公开的REST服务。我有500个错误(来自nginx容器):

PHP message: PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 32768 bytes) in /var/www/laravel/vendor/symfony/debug/Exception/FatalErrorException.php on line 1" while reading response header from upstream, client: 172.22.0.1, server: laravel.lo, request: "POST {route_name} HTTP/1.1", upstream: "fastcgi://172.22.0.5:9000", host: "laravel.lo"

我尝试使用wget从laravel容器中击中api

root@a34903360679:/app# wget api.lo
--2018-08-01 09:57:51--  http://api.lo/
Resolving api.lo (api.lo)... 127.0.0.1
Connecting to api.lo (api.lo)|127.0.0.1|:80... failed: Connection refused.

它解析为localhost,但我认为在这种情况下127.0.0.1似乎是laravel容器本身,而不是host / nginx服务。我曾经将所有服务都放在单个centos VM中进行开发,但是没有这个问题。

任何人都可以就如何实现这种环境提供一些建议吗?

编辑:我找到了答案(发布此问题后不久)。 请参阅此处:https://medium.com/@yani/two-way-link-with-docker-compose-8e774887be41

要使laravel容器返回到nginx服务(以便nginx可以将api请求解析为api容器),请使用内部网络。像这样:

networks:
  internal-api:

然后为laravel和nginx容器添加别名,如下所示:

  laravel:
  ...
    networks:
      internal-api:
        aliases:
          - laravel
  ...
  nginx-proxy:
  ...
    networks:
      internal-api:
        aliases:
          - api

networks:
  internal-api:

2 个答案:

答案 0 :(得分:0)

我找到了答案(发布此问题后不久)。请参阅此处:https://medium.com/@yani/two-way-link-with-docker-compose-8e774887be41

要使laravel容器返回到nginx服务(以便nginx可以将api请求解析为api容器),请使用内部网络。像这样:

networks:
  internal-api:

使用网络配置,可以删除所有链接配置。然后为laravel和nginx容器添加别名,如下所示:

  laravel:
  ...
    networks:
      internal-api:
        aliases:
          - laravel
  ...
  nginx-proxy:
  ...
    networks:
      internal-api:
        aliases:
          - api

networks:
  internal-api:

然后laravel可以按以下方式访问api网址:

.env:

API_BASEURL=http://api/{rest_endpoint}

答案 1 :(得分:0)

较新版本的Docker Compose将为您完成所有网络设置。它将创建一个Docker内部网络并在其块名称下为每个容器注册一个别名。您不需要(也不应使用)links:。如果只想从命令行启动堆栈的一部分,则只需要depends_on:

设置容器间连接时,请始终将Compose YAML文件中的另一个容器的名称用作DNS名称(没有Compose时,该容器的--name或您在docker run时明确声明的别名) )。将它们配置为环境变量会更好,特别是如果您将在Docker外部使用不同设置运行相同代码的情况下。在这种情况下,切勿直接查找容器的IP地址或使用localhost127.0.0.1:它将不起作用。

我会像这样写您的docker-compose.yml文件:

version: '3'
services:
  api:
    build: ./api
  laravel:
    build: ./laravel
    env:
      API_BASEURL: 'http://api/rest_endpoint'
  nginx-proxy:
    build: ./nginx-proxy
    env:
      LARAVEL_FCGI: 'laravel:9000'
    ports:
      - "80:80"

您可能需要为nginx代理编写一个自定义入口点脚本,该脚本会从环境变量中填充配置文件。如果您使用的是基于完整Linux发行版的容器,那么envsubst是一个简单的工具。