Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Connection Refused Between Nginx And PHP Containers

I'm creating a cluster with my php-fpm compiled from source image and the nginx official image, but when I try to run a phpinfo() file the nginx returns the error below:

*5 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /phpinfo.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "127.0.0.1:8000"

The docker-compose.yml file:

version: '2'
services:
  php:
    restart: always
    build: data/php
    image: php:7.1
    ports:
      - "9000:9000"
    expose:
      - 9000
    volumes:
      - ./app:/usr/share/nginx/html
  web:
    restart: always
    build: data/nginx
    image: nginx:1.10.2
    ports:
      - "8000:80"
    links:
      - php
    volumes:
      - ./data/nginx/vhost.conf:/etc/nginx/conf.d/default.conf
      - ./data/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./app:/usr/share/nginx/html
      - ./data/log/nginx:/var/log/nginx

I checked the 9000 port in my host and the netstat -an | grep :9000 command and the port are alive:

tcp6       0      0 :::9000                 :::*                    OUÇA

For more details see the files in this github repo (with the Dockerfile for that images):

https://github.com/mayconfsbrito/docker

like image 792
mayconfsbrito Avatar asked Jan 10 '17 16:01

mayconfsbrito


People also ask

How do I connect to a nginx container?

Copy the Docker container's Nginx config file to your local file system. Add proxy_pass entries that point to your backend origin servers. Copy the config file back into the Nginx Docker container. Reload the Nginx configuration and test the setup.

Should nginx be in a Docker container?

If nginx is running in a container then your site is going to be 100% dead to the world while Docker isn't running. Users will get a connection error. When nginx is installed directly on your host you can serve a 503 maintenance page that doesn't depend on Docker or any containers running.

What is bridge mode Docker?

In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.


1 Answers

Each container has its own localhost

Nginx and PHP are running in two different containers, so PHP is not running on localhost (from Nginx's perspective).

Since your PHP container is named "php", you don't want to connect to this:

fastcgi://127.0.0.1:9000

You would want Nginx to connect to this instead:

fastcgi://php:9000

Looking at your repo on Github, I believe you need to change fastcgi_pass in data/nginx/vhost.conf to this:

fastcgi_pass phpserver;

And add an upstream to match. An upstream in Nginx is a way to define another server you are pointing to. You would put this outside of the server {} block, not inside.

upstream phpserver {
    server php:9000
}

What this does is define an upstream server in Nginx, named phpserver. That points to the hostname php on port 9000. Because your PHP container is named php in Docker, that is the hostname you can use to talk to it (within the Docker bridge network).

Then we tell fastcgi_pass it should use the upstream server called phpserver.

"ports" is only needed to expose a port outside of Docker

Unless you need to independently connect to fastcgi/PHP from outside of Docker, you do not need the ports config on the php container. You need only expose in order to have nginx able to talk to php internally.

It's possible you need to define a Docker network

Recently I have noticed sometimes people need to specifically create a Docker network to make this sort of scenario work. I'm not sure why that is, but here is how you would do that.

First, create a network. Pick whatever name you like, I will use myapp in the below example.

docker network create myapp

You should now see this new network in docker network ls:

$ docker network ls
NETWORK ID          NAME                DRIVER       SCOPE
c39b88eb8450        bridge              bridge       local
175efb89adef        docker_default      bridge       local
b34434cc8b1c        myapp               bridge       local

Next, tell docker-compose to use this network. Add this block to the bottom of your docker-compose.yml file. It is at the top level of the YAML, meaning it should start at the left margin, not indented.

networks:
  default:
    external:
      name: myapp

After doing this, you will want to stop your containers and restart, so they will pick up changes. You do not need to do a rebuild to change the network config.

like image 58
Dan Lowe Avatar answered Sep 24 '22 18:09

Dan Lowe