Create a Headless CMS in a few hours with Strapi

Aaron Yu
6 min readApr 17, 2022

When it comes to CMS, most people may have heard of WordPress or Drupal, which are both very popular in the last few years. However, neither is lightweight or easy to use as a headless CMS. Strapi was created as a pure headless CMS and it seems an interesting product that is based on NodeJS. I like the openness of Strapi and decide to give it a try. I want to set up a headless CMS with Strapi on AWS. There were a few things that are not that straightforward, so I’d like to share the key steps to set it up in a few hours.

I assume you know some basics about NodeJs, Git, AWS S3, AWS RDS.

To make it easy, I’d suggest setting up a local instance first before migrating to AWS.

1. Setup a local Strapi

Setting up a local version is really simple, especially before you try to connect with AWS services. Thanks to Strapi’s online documentation, you can set up a project easily.

You need to have NodeJs installed on your machine. Be noted, Strapi v4 support NodeJs v12 and v14. Make sure you have the right version installed.

Run the command below, it will initialize a Strapi project on your local machine.

npx create-strapi-app@latest my-project--After initializing the project,you can run the follow command to start your instancenpm run develop

Congratulations, your Strapi CMS is up and running. You can start exploring how to create content or build content types with your local instance.

2. Set up AWS S3 as the content repository

Strapi uses the default /public/uploads folder as a content repository. This is not ideal in a cloud-native environment. In the next step, I will set up an AWS S3 bucket and configure Strapi to connect to it as the content repository

2.a Create S3 bucket in AWS

I will skip the steps here. You can find many useful online documents about this. You may follow the steps provided by Strapi to configure S3 and link it up with your Stapi. Strapi set up S3 as an alternative Upload provider.

2.b Install S3 provider plugin

However, Strapi requires S3 bucket to be open to the public. This is not acceptable in any production environment. So I’ve followed the steps in the following post and linked Strapi with a private S3.

npm install strapi-provider-upload-aws-s3

Important!: Strapi has a bootstrap script to scan the upload provider. By default, it looks for packages with @Strapi scope. This does not work with the above package. To fix it, you need to modify the boostrap.js (you find it under node_modules/@strapi/plugin-upload/server/)and let Strapi recognize the provider “aws-s3-private”.

modulePath = require.resolve(`strapi-provider-upload-${providerName}`);

2.c create an access key in AWS

Please follow online instruction to create your access key. You can created in AWS IAM Access Key management module. Remember your Key ID and secret

2.d configure Strapi

Create a file named plugins.js if it does not exist already

module.exports = ({ env }) => ({upload: {config: {provider: ‘aws-s3-private’,providerOptions: {accessKeyId: env(‘AWS_ACCESS_KEY_ID’),secretAccessKey: env(‘AWS_ACCESS_SECRET’),region: env(‘AWS_REGION’),params: {Bucket: env(‘AWS_BUCKET_NAME’),},},},}});

You should put your access credentials in a separate .env file in your project folder. Add your S3 connection credentials in the .env file.

// AWS S3AWS_ACCESS_KEY_ID=yourkeyAWS_ACCESS_SECRET=yoursecretAWS_REGION=yourAWSregionAWS_BUCKET_NAME=yourAWSS3bucketName

Now, restart your server and you should have S3 configured as your content repository.

Test a media file upload and you can verify it in your S3 bucket via AWS Console.

3. Setup AWS RDS as backend DB

By default, Strapi creates a local SQLite database for various purposes. I’d like to set up a separate database instance to replace SQLite. I choose to use AWS RDS PostgreSQL in my testing.

3.a create an AWS RDS Instance

Follow Strapi’s online documentation to launch an AWS RDS.

Make sure you do the following:

- Create your DB access user name and password

- Create a database with the name “strapi”

- Create or use an existing security group that allows public access to your DB

The most important thing here is to make your RDS public accessible. You SHOULD NOT do this in a production environment. Doing so is just to test your local Strapi with AWS RDS. You can migrate your Strapi to AWS later and then turn off DB public access.

To make it accessible to the public, you should have a VPC security group allowing so. You should add an inbound rule to allow TCP access from your IP with port 5432.

3.b configure Strapi to connect to RDS

Similar to S3 configuration, you need to add config details in /config/database.js

module.exports = ({ env }) => ({connection: {client: “postgres”,connection: {host: env(“DATABASE_HOST”, env(‘DATABASE_HOST’)),port: env.int(“DATABASE_PORT”, env(‘DATABASE_PORT’)),database: env(“DATABASE_NAME”, env(‘DATABASE_NAME’)),user: env(“DATABASE_USERNAME”, env(‘DATABASE_USERNAME’)),password: env(“DATABASE_PASSWORD”, env(‘DATABASE_PASSWORD’)),},useNullAsDefault: true,},});

DB connection details are maintained in .env file accordingly. You can get everything you need from your RDS instance.

Restart your server. If it’s successful, you are connected to AWS RDS! You know this because Strapi will ask you to create an admin user again because the RDS you just created is empty.

4. Migrate Strapi to AWS

Running Strapi on local is not an option for production use. You can migrate your Strapi server to AWS EC2 or EKS or ECS, etc.

Migrating to EC2 is straightforward because you already have a working code on your local machine. The details of setting up EC2 are not the scope of this document. You can search online for the instructions. The key thing to make sure is that you use the security group that can access your RDS created above.

Once your EC2 is up and running, refer to Strapi’s documentation for SSH connection to it. Then you can set up and migrate your Strapi code to EC2.

4.a check in your code to a git server — I used Bitbucket

4.b install Node on EC2

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash. ~/.nvm/nvm.shnvm install 12.22.10

4.c install git on EC2

sudo yum install git -y

4.d clone your code from your git server

Git clone https://yourgitrepo

4.e install packages in your project

Go to your project folder and run “npm install”

4.f fix the private S3 connection issue as in step 2.b

4.g create .env file in your EC2 Strapi folder

normally .env is not and should not be checked into your git repo. So you should create it in your EC2 Strapi project folder.

Once you completed the above, you can start your Strapi Server from EC2 SSH console.
Congratulation! You have a fully functioning headless CMS on AWS with Strapi, S3 and RDS.

There are many other things to take care of before your server can be used as a production server, such as placing an ELB in front of your EC2, creating an auto-scaling group of your EC2 for redundancy, and removing unnecessary security rules, creating backup rules for your DB….

The above is not in the scope of this post, you may explore it by yourself.

--

--

Aaron Yu

I am not a coder, but I like solving problems programmably