php - 如何正确链接 2 个容器?

标签 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 容器公开的上游的 block ,如下所示:
  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 block 。

我可以从网络浏览器/ postman (从主机)单独点击每个容器。

在 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 容器本身,而不是主机/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:

最佳答案

较新版本的 Docker Compose 将为您完成所有网络设置。它将创建一个 Docker 内部网络并在其 block 名称下为每个容器注册一个别名。你不需要(也不应该使用)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是一个简单的工具。

关于php - 如何正确链接 2 个容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51631193/

相关文章:

python - 运行 Docker 镜像给出 : Unable to load configuration from app. py

nginx - docker自定义nginx容器启动失败

php - Nginx 从不同的服务器提供 php 文件

nginx - Kubernetes Nginx Ingress Controller 应该在什么命名空间?

php - WooCommerce:根据自定义元值更改订单状态

php - 如何通过运行其他几个查询的 php 从 mysql 列中获取最后一条记录

php - PHP 中的完美枚举

mysql - 将mysql容器的日志挂载到宿主目录

php - Laravel 应用程序共享托管,存储文件夹符号链接(symbolic link)问题

node.js - 在 Jenkins docker 实例上找不到 Node