Search code examples
dockercurlstackcontainersbad-request

Is it possible to curl external container by host instead of IP?


I have two separate docker stacks. From stack 1, I’d like to know if it is possible to curl a container from stack 2 using the container name instead of its IP address?

When curling to IP address, I get a response with HTTP code 200. When curling to name, I get HTTP 400 Bad Request.

I have tried several different docker-compose config. Here is the latests:

Stack A

version: '3'
services:
    php:
        build:
            context: .
            dockerfile: ./dev.dockerfile
        container_name: arm_php
        ports:
          - "8000:8000"
        volumes:
            - ./:/app
        links:
            - maildev:maildev
            - redis:redis
        external_links:
            - a25_mysql_1:a25_mysql
        networks: 
            - default
            - a25dashboardad_default
    maildev:
        image: djfarrelly/maildev
        hostname: residencia-maildev
        container_name: arm_maildev
        ports:
          - "1025:25"
          - "1080:80"
    redis:
        image: "redis"
        container_name: arm_redis
        ports:
            - "6379:6379"
networks:
    a25dashboardad_default:
        external: true

Stack B

version: '3'
services:
    php:
        image: armcanada/php7-mssql
        container_name: a25_php
        ports:
          - "8001:8000"
        volumes:
            - ./:/app
        links:
            - maildev:maildev
            - database:database
    database:
        image: mysql:5.7.18
        container_name: a25_mysql
        environment:
            - "MYSQL_DATABASE=a25_db"
            - "MYSQL_USER=user"
            - "MYSQL_PASSWORD=password"
            - "MYSQL_ROOT_PASSWORD=password"
        ports:
            - "33060:3306"
        volumes:
             - db:/var/lib/mysql
    maildev:
        image: djfarrelly/maildev
        hostname: residencia-maildev
        container_name: a25_maildev
        ports:
          - "1026:25"
          - "1081:80"
volumes:
    db:
networks:
    default:
        driver: bridge

From arm_php:

Works: curl 172.19.0.4:8000/api/dmt

Doesn’t work: curl a25_php:8000/api/dmt?key=8009829dedabad1e44263cf845484f14


Solution

  • I was finally able to make it work by using a user defined network in combination with an alias. Here is the details:

    Stack A

    version: '3'
    services:
        php:
            build:
                context: .
                dockerfile: ./dev.dockerfile
            container_name: arm_php
            ports:
              - "8000:8000"
            volumes:
                - ./:/app
            links:
                - maildev:maildev
                - redis:redis
            external_links:
                - a25_mysql_1:a25_mysql
            networks: 
                - default
                - a25dashboardad_default
                - a25dashboardad_armnet
        maildev:
            image: djfarrelly/maildev
            hostname: residencia-maildev
            container_name: arm_maildev
            ports:
              - "1025:25"
              - "1080:80"
        redis:
            image: "redis"
            container_name: arm_redis
            ports:
                - "6379:6379"
    networks:
        a25dashboardad_default:
            external: true
        a25dashboardad_armnet:
            external: true
    

    Stack B

    version: '3'
    services:
        php:
            image: armcanada/php7-mssql
            container_name: a25_php
            networks:
              default:
                aliases:
                    - default
              armnet:
                aliases:
                  - a25php
            ports:
              - "8001:8000"
            volumes:
                - ./:/app
            links:
                - maildev:maildev
                - database:database
        database:
            image: mysql:5.7.18
            container_name: a25_mysql
            ports:
                - "33060:3306"
            volumes:
                 - db:/var/lib/mysql
        maildev:
            image: djfarrelly/maildev
            hostname: residencia-maildev
            container_name: a25_maildev
            ports:
              - "1026:25"
              - "1081:80"
    volumes:
        db:
    networks:
      armnet:
        driver: bridge
    

    I could then curl form arm_php using curl a25php:8000.

    The reason is, as doc says: Docker does not support automatic service discovery on the default bridge network. If you want containers to be able to resolve IP addresses by container name, you should use user-defined networks instead. https://docs.docker.com/v17.09/engine/userguide/networking/#user-defined-networks