ECS: Connection refused between Nginx and PHP-FPM containers in the same task

0

So I have spent the past two weeks learning about ECS and trying to setup a very basic task (on EC2) with an nginx container and and a PHP app in another container. It seems like I'm very close, but I'm now getting this connection refused error from nginx: **[error] 29#29: *9 connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.16.34, server: , request: "GET / HTTP/1.1", upstream: "fastcgi://172.17.0.4:8000", host: "##########:48152"**

Here is my task definition from my CloudFormation template:

     ContainerDefinitions:
        - Name: nginx
          Cpu: 10
          Essential: true
          Image: ###################
          Memory: 128
          MountPoints:
            - ContainerPath: /var/www
              SourceVolume: my-vol
          PortMappings:
            - ContainerPort: 80
          Links:
            - app
        - Name: app
          Cpu: 10
          Essential: true
          Image: #############
          Memory: 128
          MountPoints:
            - ContainerPath: /var/www
              SourceVolume: my-vol
          PortMappings:
            - ContainerPort: 8000
      Volumes:
        - Name: my-vol
          DockerVolumeConfiguration:
            Scope: task
            Driver: local

My nginx Dockerfile:

FROM nginx:alpine
RUN apk update && apk add bash
COPY ./default.conf /etc/nginx/conf.d/default.conf

The config file:

server {
    listen 80;
    listen 443;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:8000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

And my app Dockerfile:

FROM php:8.2-fpm
...
EXPOSE 8000

So, why am I using bridge mode, you ask? Well all of the examples I could find were using bridge mode, and I know that this is supposed to be like using networks in Docker, which I actually got working locally, so I thought this looked like the simplest solution. Also yes, I know that using Links is deprecated, but I couldn't find any recommended alternative.

So I can see that nginx is able to resolve the app host to the IP address of the container, so I'm guessing maybe the problem is on the PHP-FPM side, although in my app's logs I see fpm is running and ready to handle connections. Anyway I don't want to just go messing around making changes that I don't fully understand the consequences of. So if anyone could explain what's going on, that'd be great.

asked a year ago1367 views
1 Answer
0

Hello,

Thank you for all provided information. It was really helpful in order to reproduce it from my side.

I have used a pretty similar configuration files and Dockerfiles to create my images. Please find below what I've used:

App Container

$ cat app/Dockerfile
FROM php:8.2-fpm
COPY index.php /var/www/html

$ cat app/index.php
<html>
    <head>
        <title>PHP Hello World!</title>
    </head>
    <body>
        <?php echo '<h1>Hello World</h1>'; ?>
        <?php phpinfo(); ?>
    </body>
</html>

Nginx Container (All the same as you've shared except the app container port for configuration file)

$ cat nginx/default.conf
(...) 
        fastcgi_pass app:9000;
(...)

Task Definition:

{
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "<IMAGE>",
      "memory": 256,
      "cpu": 256,
      "essential": true,
      "mountPoints": [
	      {
      	"containerPath": "/var/www",
	"sourceVolume": "my-vol"
	      }
      ],
      "portMappings": [
        {
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "links": [
        "app"
      ]
    },
    {
      "name": "app",
      "image": "<IMAGE>",
      "memory": 256,
      "cpu": 256,
      "essential": true,
      "mountPoints": [
              {
        "containerPath": "/var/www",
        "sourceVolume": "my-vol"
              }
	]
    }
  ],
  "volumes": [
	  {
		  "name": "my-vol",
		  "dockerVolumeConfiguration": {
			  "scope": "task",
			  "driver": "local"
		  }
	  }
  ],
  "networkMode": "bridge",
  "placementConstraints": [],
  "family": "application-stack"
}

As you can see above, there are 2 differences mainly. One is about the application port and the other is the portMapping from app container that I've removed as it is not needed.

Regarding the application port, which I really think that is the issue here, checking the official php-fpm documentation, it informs that: By default, php-fpm will respond to CGI requests listening on localhost http port 9000.. Thus, this is the port that should be used while connecting from Nginx container to App container.

Hope this helps you to overcome the issue!

profile pictureAWS
answered 10 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions