Multi-Containers App on AWS Fargate

Yosi Pramajaya
4 min readSep 14, 2019

Containers allow developers to build their code as one package of software that can be deployed virtually anywhere. Still, scaling a containerised app can take quite an amount of configuration. This configuration involves setting up Network, Load Balancer, Auto-Scaling policy, and other.

Serverless products such as AWS Lambda, Google Cloud Functions, or Azure Functions allow you to scale your app easily, but it limits your language preference, framework, and dependencies.

AWS Fargate is a service that allows you to run a container app without having to manage your cluster or server. This means you can run any app and scale easily without thinking about your server.

When to use Fargate?

The downside of AWS Fargate is that it can be expensive. If you compare to an EC2 instance with the same memory and CPU capacity, Fargate can cost you up to 3x more.

Fargate may not be suitable to run tasks continuously, like a web service. But given the ability to start and scale very fast, Fargate can be very useful and cost-saving to run task in a short period of time.

New Kind of Networking

One big difference between Fargate and EC2-based Cluster is that Fargate uses native-networking mode called awsvpc.

Fargate Task Definition only supports awsvpc Network Mode

What really is the difference between awsvpc and other Network Mode?

Bridge networking mode uses Docker’s built-in virtual network. Host networking mode will bypass Docker’s virtual network and map the ports directly to the EC2 instance network interface.

With awsvpc, a Task will have its own Elastic Network Interface (ENI), that is AWS native network interface. This means you can integrate your Task Network with other AWS services such as Security Group.

Host port mappings are not valid when the network mode for a task definition is host or awsvpc. This might seem as an obstacle when we want to deploy multi-containers on the same task definition. However, this would allow simpler and easier configuration of containers networking.

Configure Task Networking

Because our containers shared the same ENI, we only need to make sure they run at the right ports. For example, consider the previous article I wrote.

In the EC2-based Task Definition, I have to set link nginx to laravel-app and from my laravel-app to redis. I also need to map the ports of the containers.

With Fargate, all those containers can communicate through localhost. I don’t need to set up docker networking, link the containers, or set port mapping. Let’s see how we can configure our Task Definition to deploy our Laravel app.

Step-by-Step

Before we start, I assume you have read the previous article on deploying Laravel to ECS. The sample code is also in this GitHub repository.

Step 1. Dockerfile on Laravel-app

Since there will be no Host port mapping, we have to make sure that our Laravel-app image runs at the right port. PHP-FPM usually run on port 9000, this is good because we need port 80 for Nginx.

So instead of exposing port 80, we have to change to port 9000.

EXPOSE 9000

Step 2. Setting up Nginx

In EC2-based Task Definition, we should link nginx to app, and configure nginx to pass request to app:9000. With Fargate, nginx can communicate with app through localhost, therefore we can easily change the vhost like this:

Use localhost:9000

We also have to configure our nginx Dockerfile to make sure it exposes port 80.

EXPOSE 80

Step 3. Build and Push

After we have made those changes, we need to build and push our images to ECR.

Step 4. Create Fargate Task Definition

The Fargate Task Definition will be quite similar with the EC2 Task Definition. We need to set up Task size and add the containers. Leave the networking and port mapping blank.

Task size and Container Definitions setting

We can also set our laravel-app to connect to redis by adding up the values below as the environment variables in Container Definitions.

REDIS_HOST=localhost
REDIS_PORT=6379 #The default port of our redis container

And don’t forget to create and mount shared volume for web and app.

Mount the volume in Container Definitions

Step 5. Run the Task

Let’s find out by running the Task! If you do it correctly, you will see the Task running.

Task is running

Now we can visit the Public IP in the browser to check if your app is working. And that’s it! We successfully deployed Laravel app on AWS Fargate.

Thanks for reading! Let me know your opinion below.

--

--

Yosi Pramajaya

Tech Lead, Cloud Architect, Machine Learning Practicioner