duanre1891 2018-08-01 10:36
浏览 75
已采纳

如何正确链接2个容器?

This is kinda a newbie question since I'm still trying to understand how containers "communicate" to each other.

This is roughly what my docker-compose.yml looks like

...
  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 configs have blocks referring to upstream exposed by those 2 php-fpm containers, like this:

  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;
  }

similar for the api block.

I can hit each container individually from the web browser/postman (from the host).

Inside the laravel app, there is some php_curl to call a REST service exposed by the api service. I got 500, with this error (from the nginx container):

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"

I tried hitting the api from the laravel container using wget

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.

It resolves to localhost, but I believe 127.0.0.1 in this context seems to be the laravel container itself, not the host/nginx services. I used to have all the services in a single centos VM for development, which didn't have this problem.

Can anyone give some advice on how I could achieve this environment?

EDIT: I found the answer (not long after posting this question). Refer to here: https://medium.com/@yani/two-way-link-with-docker-compose-8e774887be41

To get the laravel container reaches back to nginx services (so nginx can resolve api request to the api container), use internal network. So something like:

networks:
  internal-api:

Then alias the laravel and nginx containers, like so:

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

networks:
  internal-api:
  • 写回答

2条回答 默认 最新

  • douxin9135 2018-08-01 11:34
    关注

    Newer versions of Docker Compose will do all of the networking setup for you. It will create a Docker-internal network and register an alias for each container under its block name. You don't need (and shouldn't use) links:. You only need depends_on: if you want to bring up only parts of your stack from the command line.

    When setting up inter-container connections, always use the other container's name from the Compose YAML file as a DNS name (without Compose, that container's --name or an alias you explicitly declared at docker run time). Configuring these as environment variables is better, particularly if you'll run the same code outside of Docker with different settings. Never directly look up a container's IP address or use localhost or 127.0.0.1 in this context: it won't work.

    I'd write your docker-compose.yml file something like:

    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"
    

    You will probably need to write a custom entrypoint script for your nginx proxy that fills in the config file from environment variables. If you're using a container based on a full Linux distribution then envsubst is an easy tool for this.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料