How to deploy Strapi on AWS
Published: 2022-02-11 15:39:55

This is a guide for deploying Strapi on AWS. At [Devtastic](https://devtastic.co) I have multiple Strapi projects so I needed a way to quickly deploy Strapi instances that could easily scale, were easy to manage and were costs efficient. I decided to go with Elastic Beanstalk as this allowed me to deploy on cheap EC2 instances while offloading most of the devops work. Although I already had some experience with EB I hit some major roadblocks 🚧 while trying to get things running. Hopefully this guide will save you some time 🙏

In this guide we will:

- Use Strapi v4
- Use Elastic Beanstalk with Docker
- Use a load balancer for adding HTTPS

I assume you have an AWS account and a Strapi project.

That said, let's go!

## Creating a Dockerfile
The first step is to create a `Dockerfile` that will build and run the application.

```Dockerfile
FROM node:14-buster

WORKDIR /opt/

COPY ./package.json ./
COPY ./yarn.lock ./

ENV NODE_ENV production
RUN yarn install

# Remove this if you only want to run the API
RUN yarn build

COPY . .

EXPOSE 1337

CMD ["node", "node_modules/@strapi/strapi/bin/strapi", "start"]
```
Please note that:
- I'm using a node image instead of `strapi/base` as the latter doesn't work with the graphql package due to the node engines not matching.
- I lost a lot of time with the `CMD` part. I tried running `yarn start` (I know, ridiculous). It kept complaining it couldn't find `strapi`. I tried setting the path variable and switching to npm but ended with this monstrosity. At least it works 😓.

# Creating an Elastic Beanstalk environment
Create a new EB environment with a load balancer and at least a `small` EC2 instance (you need at least 2GB of memory). I managed to get away with a `micro` instance when not using the admin (I build and host the admin on Vercel).

Take care when using the new (and recommended) arm64 based `t4g` instances. I spend a lot of time trying to solve issues with `libvips`, `glibc` and Sharp only to find out it worked out of the box on x86 machines 🤦‍♂️. I'm sure it's fixable, just not by me. At least not today.

## Save costs with a shared load balancer
You actually don't need a separate load balancer for each EB application. This can be a huge cost-saver as a load balancer is $20-something a month. You can route based on the host header and add multiple SSL certificates to the same load balancer, allowing you to use it for different domains.

Create a new Application Load Balancer from the EC2 dashboard. Once created you can select it in Elastic Beanstalk when creating a new environment. Choose Shared Load Balancer, in the load balancer section of the configuration. It took some time to show up in my case. EB will add a new target group and a listener for the auto-generated domain. You have to add a new listener for _your_ domain yourself. Just point it to the new target group.

## Security group issue
One thing that took me some time to figure out was that the security group `AWSEBManagedLBSecurityGroup` which is added by Elastic Beanstalk to the load balancer did not allow for incoming requests at port 80 and 443. The result was that any request to the environment just timed out. I didn't expect EB not to add these rules. Add them and everything will be fine.

## Database and admin
Adding a database is straightforward and depends on your choice of database. I'm using one RDS instance, creating a new database for each project.

You can run Strapi in API-only mode by setting the `serveAdminPanel` key in `config/admin.js` to `false`. This allows you to run on micro instances, which is a small cost-saver for sandbox/hobby projects. You can build and host the admin on another platform, such as AWS CodeBuild  + CloudFront or Vercel. 

Now we can deploy Strapi projects with just a few clicks in a way that is scalable and manageable. EB gives us health checks, CloudWatch integration and automatic updates with rollback strategies. I'm excited for Strapi's own cloud service but at least we now have a good alternative.

If you have any questions feel free to leave a comment or talk to me on Discord (`catfish314#8009`) 🙌