Search code examples
dockeramazon-ecs

ECS multi container setup


I need help with the following scenario. I have three containers which need to run on ECS with alb in front. I have nginx-frontend, php, nginx-backend. Both nginx containers depend on the php container. I only want to expose the frontend container. How can I tie them together without added alb's in front of each?

I use terraform to configure all parts including (ALB,ECR, ECS, ...) I wanted to know how can I connect the containers without having each with an alb in front.

Localy I run them with docker-compose.


Solution

  • Nginx and PHP can run side by side. A task definition in ECS can contain both of these containers with the nginx container exposing port 80 and the PHP container exposing 9000 (probably using PHP-FPM). Nginx can be used as a proxy routing requests to the PHP process.

    Example task definition (value simplified to demonstrate multi-container set up):

    {
      "containerDefinitions": [
        {
          "portMappings": [
            {
              "hostPort": 9000,
              "protocol": "tcp",
              "containerPort": 9000
            }
          ],
          "command": [
            "php-fpm"
          ],
          "image": "image-url-for-php:latest",
          "name": "php-fpm"
        },
        {
          "portMappings": [
            {
              "hostPort": 80,
              "protocol": "tcp",
              "containerPort": 80
            }
          ],
          "image": "image-url-for-nginx:latest",
          "dependsOn": [
            {
              "containerName": "php-fpm",
              "condition": "START"
            }
          ],
          "essential": true,
          "name": "nginx"
        }
      ]
    }
    

    The nginx configuration will look something like this:

    server {
        listen 80;
        index index.php index.html;
        root /var/www/html/public; # change this to application files path
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass localhost:9000; # PHP container accessible via localhost:9000 if running side by side
            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;
        }
    }
    

    This task definition can then be used to create a service which the ELB can use as a target group (routing to port 80 for nginx). From there all requests will be proxied to the PHP container.

    As far as the nginx-backend the same set up can be used. However, if this service will not be exposed to public traffic, you will need to use either an Internal ELB or Service Discovery. However, the idea is that the PHP container will not need a dedicated ELB for itself.