Running Laravel Artisan commands on AWS Fargate – Hacker Noon

I’ve recently published my thoughts on running a scalable, highly available Laravel project behind AWS VPC. In this post I want to talk about running Laravel Artisan commands on Fargate.


AWS Fargate is an AWS managed service that allows us to deploy Docker containers on ECS without having to manage the underlying infrastructure (EC2 cluster). That means it’s no longer possible to use a bastion host to get shell access to one of the container instances and interact with the container via docker exec.

One key concept that allows artisan to run on Fargate is the Docker Command, which is responsible for executing the command that gives the container a reason to exist. For instance, when running Apache on an alpine image, the command will be httpd -DFOREGROUND. This command holds the container running indefinitely because it’s implementation is an event loop that is suppose to never finish. If we prepare a Docker image with a command of php artisan my:command, then this command will be executed as soon as the container starts. If the command ever finishes with a status code of 0, it means it successfully executed and the container is now ready for a graceful shutdown. This is specially good because AWS Fargate charges on a per-minute basis, which means we are able to start a container and pay for only a few minutes while the command is being executed.


The first step for implementing a Docker image to run artisan on Fargate is Docker Multi Stage Build. The following Dockerfile is divided into Base, Dependencies, Artisan and App.

| Layer | Description |
| base | Operating System dependencies / PHP Extensions |
| dependencies | Application Dependencies / Composer |
| artisan | Layer used for running Artisan commands |
| app | Web Application |

By using multi stage build, we can choose which stages we want to push to AWS Elastic Container Registry (ECR). The following snippet is an example of a buildspec.yaml used by AWS CodeBuild in conjuction with AWS CodePipeline.

Notice that AWS ECR now has two images, one for the app and another forartisan.

Note: the configuration of AWS ECR, CodeBuild and CodePipeline are beyond the scope of this article. The following steps assumes that a Task Definition has been created for the artisan image.

After creating a Task Definition for the Artisan image it will be possible to use AWS CLI to start a container to run an artisan registered command. Make sure to fill your_cluster_name, your_task_definition_name-artisan, your_aws_profile and the correct path for a network-configuration file. Below you’ll find a sample of a network.json.


You can now run commands via sh my:command. By issuing this command, the bash script will instruct AWS CLI to start a new container on Fargate with a Docker Command override that runs php /app/artisan $1 where $1 is the first argument, in this case my:command. Amazon will start a container on your ECS Cluster with this command and, as soon as the command finishes, the container will exit. You should be able to redirect any information from stderr and stdout to CloudWatch to be able to figure out any output message the command gave you.

The command you desire to run should already be inside the source code that was pushed to AWS ECR and tagged with -artisan suffix. This means that as soon as you write your custom command, you’ll have to push your code changes first and only then run the bash script.


As mentioned on my previous post, this is particularly important for running long-running processes without being subjected to HTTP Request limitations. It also enforces a due deployment process before being able to run arbitrary commands on your production VPC, which works well if your workplace have a well established Code Review process before pushing to production. Not having to write API endpoints to run one-off processes after a release cycle improved the development process greatly for me, specially because I can comfortably work with the Laravel mindset of easy console commands provided by Artisan.

This process will allow for a team to run php artisan migrate on production without having to open Amazon RDS to the outside of the VPC. However, since migrate is a command that is constantly executed upon every release, I plan on writing another post explaining how to prepare a Task Definition dedicated for migration that will start automatically after every deploy.

If you enjoy reading about how I deploy microservices on AWS Fargate behind a VPC, follow me on and

read original article here