20

Edit: My first question was "how to link containers inside task definition on AWS ECS using Fargate?" But, may be I'm wrong from the start, so I changed my question and keep the content below:

I'm trying to deploy a simple Laravel based app on AWS via ECS. My service works as expected in local using docker-compose-yml file.

But on AWS I get: "nginx: [emerg] host not found in upstream "app" in /etc/nginx/conf.d/default.conf:12" from my web container log.

Here the containers of my service: web (nginx), app (Laravel), database (MySQL) and cache (redis).

I understand that all containers of the task description share the same namespace, so there no need for linking container (we can't anyway use links attribute with Fargate).

May you help me finding the problem here? I'm blind.

Here my working local docker-compose.yml file:

version: '2'
services:

  #  The Application
  app:
    image: 696759765437.dkr.ecr.us-east-1.amazonaws.com/ali-
maison/tribe-migrate
    volumes:
      - /var/www/storage
    env_file: '.env'
    environment:
      - "DB_HOST=database"
      - "REDIS_HOST=cache"

  # The Web Server
  web:
    image: 696759765437.dkr.ecr.us-east-1.amazonaws.com/ali-maison/laravel-web
    ports:
      - 80:80

  # The Database
  database:
    image: mysql:5.6
    volumes:
      - dbdata:/var/lib/mysql
    environment:
      - "MYSQL_DATABASE=homestead"
      - "MYSQL_USER=homestead"
      - "MYSQL_PASSWORD=secret"
      - "MYSQL_ROOT_PASSWORD=secret"

  # redis
  cache:
    image: redis:3.0-alpine

volumes:
  dbdata:

Here my web container Dockerfile:

FROM nginx:1.10

ADD vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www

And my vhost.conf:

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

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

    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;
    }
}
FredRoger
  • 1,545
  • 1
  • 12
  • 17
  • Looks like a related problem at https://stackoverflow.com/questions/33639138/docker-networking-nginx-emerg-host-not-found-in-upstream – randominstanceOfLivingThing Jan 18 '18 at 18:43
  • Looks like, but it seems that I can't apply any suggestions in my task description configuration on ECS. :/ – FredRoger Jan 18 '18 at 18:54
  • 1
    with Fargate, try replacing `app:9000` with `127.0.0.1:9000` – David Lin May 18 '18 at 03:57
  • Did you manage to made it work? Can you show me how your task definition looks like? – Cliff Richard Anfone Jul 11 '18 at 07:11
  • What command is capable to use Docker Compose to create such stack? – Roman Newaza Jul 12 '18 at 07:58
  • Did you ever find a working solution to this? I'm facing the same problem and using localhost doesn't appear to work either. – urchino Aug 08 '18 at 09:51
  • Are each of your containers in their own task definition, or are all three containers in one task definition? – bluescores Aug 09 '18 at 12:10
  • @bluescores for me there are two containers - nginx and php-fpm - and they're in a single docker image and so defined as a single task within ECS. Should they perhaps be defined as two different tasks with separate containers? It's not clear that this would solve the comms issue, and since the combined image works everywhere else why should it be necessary? – urchino Aug 23 '18 at 13:59

3 Answers3

5

The solution is:

  1. Make sure both containers are defined in the same task eg nginx-php
  2. use localhost:port eg localhost:9000 for php-fpm

The second part was mentioned above but it was not clearly said that both containers have to be in the same task.

More information you can find here: https://github.com/aws-samples/amazon-ecs-fargate-aspnetcore/blob/master/README.md

poldek
  • 137
  • 2
  • 8
1

From the vhost.conf:

fastcgi_pass app:9000;

The hostname "app" works for docker-compose because that's what you've named the service in the docker-compose.yml. docker-compose creates a new network for the containers it has to manage, and that network enables the containers to reference each other by hostname with no further configuration.

Fargate doesn't have this feature, so "app" won't resolve.

The only networking mode Fargate currently allows you to use is a special AWS mode called awsvpc. Each task running in Fargate gets its own elastic network interface (ENI), which means each task gets it's own private IP address. You can additionally configure the ENI to have a public IP address as well, just like you can with an ENI on an EC2 instance.


How to resolve your app container from the nginx container

In Fargate, drill down into your running task definition for the app server (Cluster > Tasks tab > click the container ID in the Task column for your app server). The Network section will have the private IP.

Replace the host name "app" with this ip in your conf:

fastcgi_pass <private_ip>:9000;

bluescores
  • 4,437
  • 1
  • 20
  • 34
  • 1
    Hardcoding an address is really bad practice. There should be the other way. Can we use `localhost`? – Roman Newaza Jul 12 '18 at 07:57
  • Whilst the information about why it doesn't work is helpful - your proposed solution is not a good one as @RomanNewaza points out. Building a task-specific IP address into the container config is not a good option, as it means the container isn't going to work elsewhere or if the IP address isn't consistent across tasks. Using localhost on port 9000 for the fastcgi_pass param results in a 502 error from nginx for me. – urchino Aug 08 '18 at 09:48
  • I'm going to try to get more info from OP and update this answer. Hardcoding the IP would work, but doing so isn't useful in the real world while using Fargate (i.e. it's a bad practice) – bluescores Aug 09 '18 at 12:12
  • It is very important to re-iterate the point made by others here. If the nginx and php containers are configured to run within the same fargate task, then you need to use 127.0.0.1 as the IP for the nginx configuration for fastcgi_pass i.e. `fastcgi_pass 127.0.0.1:9000;` – Phillip Hartin Feb 15 '20 at 05:13
1

For others that might run across this, I had the same issue connecting two container running in the same task on aws ecs fargate and found that I had to replace 'app' with 'localhost' in the vhost.conf, and it worked. (This was mentioned in some of the comments on another answer) So the vhost.conf would look like:

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

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

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

I also made sure that port 9000 was mapped and exposed on the app container (might be unnecessary)

#  The Application
app:
  image: 696759765437.dkr.ecr.us-east-1.amazonaws.com/ali-maison/tribe-migrate
  volumes:
    - /var/www/storage
  env_file: '.env'
  environment:
    - "DB_HOST=database"
    - "REDIS_HOST=cache"
  ports:
    - 9000:9000
grizzb
  • 329
  • 5
  • 8