19
votes

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;
    }
}
3
Looks like, but it seems that I can't apply any suggestions in my task description configuration on ECS. :/FredRoger
with Fargate, try replacing app:9000 with 127.0.0.1:9000David Lin
Did you manage to made it work? Can you show me how your task definition looks like?Cliff Richard Anfone
What command is capable to use Docker Compose to create such stack?Roman Newaza

3 Answers

5
votes

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

1
votes

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
0
votes

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;