Search code examples
laravelapidockerdocker-composelumen

Docker web and apis refusing connection


I'm pretty new to docker. I have created a docker-compose which has 1 main app (laravel) site, and 2 apis.

I am trying to access the apis from the laravel site, but keep getting:

cURL error 7: Failed to connect to 0.0.0.0 port 8082: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

my docker-compose.yml is:

version: '3'
services:
  web:
    image: nginx:1.10
    volumes:
    - ./vhost.conf:/etc/nginx/conf.d/default.conf
    ports:
    - "8080:80"
    depends_on:
    - app
    restart: always

  app:
    build: . #run the dockerfile to install whatever
    env_file: .env
    volumes:
    - ./:/var/www
    depends_on:
    - database

  web-api2:
    image: nginx:1.10
    volumes:
    - ../api/api2/vhost.conf:/etc/nginx/conf.d/default.conf
    ports:
    - "8081:81"
    depends_on:
    - app-api2

  app-api2:
    build: . #run the dockerfile to install whatever
    env_file: .env
    volumes:
    - ../api/api2:/var/www
    depends_on:
    - database

  web-api1:
    image: nginx:1.10
    volumes:
    - ../api/api1/vhost.conf:/etc/nginx/conf.d/default.conf
    ports:
    - "8082:82"
    depends_on:
    - app-api1

  app-api1:
    build: . #run the dockerfile to install whatever
    env_file: ../api/api1/.env
    volumes:
    - ../api/api1:/var/www
    depends_on:
    - database

  database:
    image: mysql:5.7
    environment:
    - "MYSQL_ROOT_PASSWORD=IAmSoSecure"
    - "MYSQL_DATABASE=my_app"
    ports:
    - "33061:3306"
    volumes:
    - my_app:/var/lib/mysql
    restart: always


volumes:
  wildfire:

I've looked into docker networking but my attempts have failed. I have a network setup, and the tried using the subnets but it didn't do the trick:

"IPAM": {
        "Driver": "default",
        "Options": {},
        "Config": [
            {
                "Subnet": "172.18.0.0/16",
                "Gateway": "172.18.0.1"
            }
        ]
    },

I have tried accessing the ports I enabled too:

"Ports": {
            "443/tcp": null,
            "80/tcp": null,
            "82/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "8082"
                }
            ]
        },

I am requesting the call as per usual via Guzzle:

$client = new Client();
$res = $client->get('127.0.0.1:8082/accounts');
dd($res->getBody()->getContents());

I have tried different IPs but can't find the correct one to use.

My Current vhost.conf is:

server {
listen 80;
index index.php server.php;
root /var/www/public;

add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

index index.html server.php index.php;

charset utf-8;

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt  { access_log off; log_not_found off; }

error_page 404 /index.php;

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass app:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    #fastcgi_param PATH_INFO $fastcgi_path_info;
    include fastcgi_params;
    include  /etc/nginx/mime.types;
}

location ~ /\.(?!well-known).* {
    deny all;
}

location ~ \.css {
    add_header  Content-Type    text/css;
}

location ~ \.js {
    add_header  Content-Type    application/x-javascript;
}
}

Solution

  • On the default network that docker compose creates, each container managed by the orchestrator is reachable by it's service name that happens to be identical to the name given to it in the docker-compose.yaml file. So in your case each container on the same network may reach app-api2 as your question details with:

    http://app-api2:82/accounts
    

    For a more complete answer using 127.0.0.1 from within your container means that you are trying to reach a service that is within the container itself and listening on, in your case, 82. Since you have no other executables running within the same container and listening on that port you are correctly receiving Connection refused.

    It may also be useful for you to know that you do not strictly need to expose the ports from your docker-compose.yaml file for other containers on the same network to communicate. The exposed ports enable you make requests from the host machine (where in fact you would use 127.0.0.1).

    If for whatever reason you do want to use the IP address of the container to communicate between containers than you can find the current IP for a specific container using docker inspect <container name>. However note that this IP is ephemeral and will likely change each time the container is spun up.

    More detailed information can be found https://docs.docker.com/compose/networking