Docker curl: (7) Failed to connect to localhost port 80: Connection refused

dockerdocker-compose

I execute from native host and

$ curl localhost

or

$ curl

http://usuariointerno:governance@beneficiarios.dev/app_dev.php/actividad

and response its ok.

if execute from container name "php" and :

$ curl localhost –ipv4

Failed to connect to localhost port 80: Connection refused

or

$curl
http://usuariointerno:governance@beneficiarios.dev/app_dev.php/actividad

curl: (7)Failed to connect to localhost port 80: Connection refused

When connect from docker container faill, if connect outside of docker container its OK, What its the problem?

docker-compose:

version: '2'
services:
  php:
    container_name: php
    build: ./php
    volumes:
      - ./www/:/var/www/html/
      - ./php/.bashrc:/root/.bashrc
      - ./php/.gitconfig:/root/.gitconfig
    depends_on:
      - postgres
      - mysql

  nginx:
    container_name: nginx
    image: nginx
    ports:
      - 80:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
      - ./www/:/var/www/html/
      - ./logs:/var/log/nginx
    depends_on:
      - php
    
  postgres:
    container_name: postgres
    image: postgres:9.5.5
    volumes:
      - ./data/postgresql:/var/lib/postgresql/data
      - ./postgres/dumps:/dumps
    environment: 
     - POSTGRES_PASSWORD=0000
     - POSTGRES_USER=postgres

  mysql:
    container_name: mysql
    image: mysql:5.7.16
    volumes:
      - ./data/mysql:/var/lib/mysql
    environment: 
      - MYSQL_ROOT_PASSWORD=0000

nginx.conf

server {
    listen 80;
    server_name beneficiarios.dev;
    root /var/www/html/beneficiarios/web;
    
    
    add_header Access-Control-Allow-Origin *;

    location / { try_files $uri /app.php$is_args$args;}
   
   #dev
    location ~ ^/(app_dev|config)\.php(/|$) {
        add_header Access-Control-Allow-Origin *;
        fastcgi_buffers 16 256k; 
        fastcgi_buffer_size 256k;
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
       
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
    }

    location ~ ^/app\.php(/|$) {
        fastcgi_buffers 16 256k; 
        fastcgi_buffer_size 256k;
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
       
        internal;
    }

    location ~ \.php$ {
      return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}

Best Answer

Localhost, or 127.0.0.1, always means the same host as the command is currently running on. So on your host, it will call your host, but when running inside your container, it will call to your container.

I'm going to assume that you have a DNS resolver that points the .dev domain to localhost. The nginx container has port 80 from the host forwarded to it, so it's as if it was running on your host. So when you call it from your host, it succeeds because the call goes to port 80 of your host.

But when you call it inside the php container, it's not calling to your host, it's calling to port 80 of your php container, and you don't have a webserver running inside your php container. If you made this call inside your nginx container it would work.

You should ask yourself why your php container would need to call to your nginx container, this sounds strange to me since usually nginx would just forward the "work" to php anyway. Could you, for example, just create a php script that does what you want and call that directly?

If you really need to call nginx, keep in mind that containers from the same docker-compose.yml file can call each other by name, so you could just use nignx as the hostname.