Strapi blog featured image

Deploying Strapi on AWS EC2: A Comprehensive Guide

Strapi is a powerful, open-source headless CMS built on Node.js that helps you manage content and deliver it via API. Deploying it to production requires a reliable server—AWS EC2 fits that need perfectly, offering flexibility, scalability, and global reach. In this guide, you’ll learn how to deploy Strapi on Ubuntu EC2, set up a secure PostgreSQL database (via RDS), and configure S3 for storing media assets.

1. Prepare and Launch Your EC2 Instance 

  1. Open the AWS Console and navigate to EC2.

  2. Choose a modern region (e.g., us-east-1).

  3. Click Launch Instance, select Ubuntu Server 22.04 LTS.

  4. Choose an instance type (t2.small recommended; 2 GB RAM is ideal)

  1. Configure storage (20–32 GB SSD is a good starting point).

  2. Add a Security Group:

    • SSH (port 22) from your IP

    • HTTP (80) and HTTPS (443) from anywhere

    • Optionally, TCP 1337 for testing locally (remove later)

  3. Create or select a key pair (.pem file).

After review, launch the instance. Save your .pem key in a safe, accessible location and this pem key will be used to ssh into the instance. 

 

woman-working-on-her-system

2. Connect and Prepare the Server

Once your instance starts:

ssh -i ~/path/my-strapi.pem ubuntu@<EC2_PUBLIC_IP>
sudo apt update && sudo apt upgrade -y

Then install essentials:

# Install Node.js v18 via nvm
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs build-essential git nginx pm2
  • We use nvm/Node18 (Strapi requires Active LTS)

  • PM2 ensures Strapi restarts on failures or server reboot.

3. Deploy Your Strapi App

A. Clone Your Code

git clone https://github.com/you/your-strapi-project.git
cd your-strapi-project
npm install

B. Setup Environment Variables

Create .env with:

 
HOST=0.0.0.0

PORT=1337
NODE_ENV=production
DATABASE_CLIENT=postgres
DATABASE_HOST=<YOUR_RDS_ENDPOINT>
DATABASE_PORT=5432

DATABASE_NAME=strapi
DATABASE_USERNAME=<DB_USER>
DATABASE_PASSWORD=<DB_PASS>
AWS_ACCESS_KEY_ID=<KEY>
AWS_ACCESS_SECRET=<SECRET>
AWS_REGION=us-east-1
AWS_BUCKET_NAME=<S3_BUCKET>

4. Configure the Database (RDS)

Strapi’s default is SQLite—not ideal for production. Use AWS RDS with PostgreSQL or MariaDB 

  • Go to RDS, create a PostgreSQL database.

  • Disable public access.

  • Attach the EC2 Security Group to allow only the Strapi server’s IP 

Configure Strapi for Production

goto the config folder in your strapi project

config/env/production/database.js:

 
module.exports = ({ env }) => ({
connection: {
client: 'postgres',
connection: {
host: env('DATABASE_HOST'),
port: env.int('DATABASE_PORT'),
database: env('DATABASE_NAME'),
user: env('DATABASE_USERNAME'),
password: env('DATABASE_PASSWORD'),
ssl: { rejectUnauthorized: false },
},
debug: false,
},
});

Install the Postgres driver:

npm install pg pg-connection-string

 

5. Setup S3 for Media Uploads 

Strapi saves uploads locally by default, which isn’t suitable for production 

Steps:

  1. Create an S3 bucket.

  2. Attach correct IAM policies to your EC2 role (or use access keys).

  3. Install the AWS provider:

npm install @strapi/provider-upload-aws-s3
  1. Create config/env/production/plugins.js:

 
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
region: env('AWS_REGION'),
params: { Bucket: env('AWS_BUCKET_NAME') },
},
},
},
});

Your media assets will now be stored securely in S3.

 

6. Manage the Process with PM2

Install and configure PM2:

 
npm install pm2 -g
pm2 start npm --name strapi -- start
pm2 save
pm2 startup systemd

This ensures Strapi starts on reboot

 

7. Set Up Nginx as a Reverse Proxy

Nginx secures your Strapi instance and enables HTTPS:

  1. Install Certbot:

sudo apt install certbot python3-certbot-nginx
  1. Configure Nginx:

 
server {
listen 80;
server_name cms.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name cms.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/cms.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cms.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:1337;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
}
}
  1. Reload Nginx:
sudo nginx -t && sudo systemctl restart nginx
sudo certbot --nginx -d cms.yourdomain.com

Now your Strapi is live at https://cms.yourdomain.com, secure with HTTPS.

 

8. Secure and Optimize

  • Close direct port 1337 access in the Security Group

  • Use AWS CloudWatch for logs and performance monitoring

  • Use SSM Parameter Store or AWS Secrets Manager to manage secrets securely

  • Regularly run npm audit and update dependencies .

  • Consider enabling rate-limiting and strong Content Security Policy (CSP).

 

9. Cost and Maintenance Notes

  • A t2.small EC2 instance + RDS + S3 generally costs $30–40/month for light workloads

  • Pay attention to instance type—free-tier micro instances often lack memory to run Strapi 

 

Final Note

Deploying Strapi on AWS EC2 + RDS + S3 gives you a scalable, secure, production-ready CMS. You’ll learn valuable DevOps skills as you:

  • Launch and secure an EC2 server

  • Configure node with PM2 and environment variables

  • Set up a managed PostgreSQL database (RDS)

  • Store media assets in S3

  • Reverse-proxy traffic through Nginx with HTTPS

  • Monitor performance in CloudWatch

Once you have this foundation, you can easily scale out with load-balancers, containerization (ECS/EKS), or automated deployments.

 

Related reads:

External resources:

Leave a Comment

Your email address will not be published. Required fields are marked *