Application Stacks AWS

Strapi on AWS User Guide

| Product: Strapi on AWS

Overview

This image runs Strapi, the leading open source headless CMS. Strapi is a flexible content platform built on Node.js that lets teams model content with a visual Content-Type Builder, manage entries in a polished admin panel, and deliver everything through an automatically generated REST and GraphQL API with fine grained roles and permissions, a draft and publish workflow, media management and internationalisation.

Strapi 5.48.1 is installed under /opt/strapi on Node.js 22 LTS and runs as a dedicated unprivileged strapi system account under a systemd service that starts it on boot and restarts it on failure. The content store, holding the SQLite database (data.db) and your uploaded media, lives at /var/lib/strapi, which is a dedicated, independently resizable EBS data volume that survives instance replacement.

Strapi binds to the loopback interface only (127.0.0.1:1337) and is never exposed directly. An nginx reverse proxy publishes the admin panel and the content API on port 80, adding WebSocket upgrade support and a generous upload limit for media. Strapi provides its own admin authentication at /admin; nginx is a plain pass through proxy and adds no second authentication layer. The administrator password is generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share a password. It is written to /root/strapi-credentials.txt with mode 0600 so that only the root user can read it.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and port 80 for the admin panel and the content API
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Strapi. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of t3.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network and port 80 for the admin panel and the content API. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation generates the application secrets, creates the admin user and starts the services; this takes up to a minute after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Strapi Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22 and 80 as described above.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type t3.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=strapi}]'

When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.

Step 3: Connect to Your Instance

Connect over SSH using your key pair and the login user for your operating system variant.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i <key-name>.pem ubuntu@<public-ip>

Step 4: Confirm Strapi Is Running

Over SSH, confirm the Strapi application and the nginx proxy are active and that Strapi answers its health check on loopback:

sudo systemctl is-active strapi nginx
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:1337/_health

Both services should report active and the health check should return 204. Strapi listens on 127.0.0.1:1337 (loopback only) and nginx publishes it on port 80.

Step 5: Retrieve the Admin Password

The Strapi administrator password is unique to your instance and was generated on first boot. Read the credentials file as root:

sudo cat /root/strapi-credentials.txt

The file lists the admin panel URL, the administrator email (admin@cloudimg.local) and the generated password. Keep this password somewhere safe.

Step 6: Sign In to the Admin Panel

The Strapi admin panel is served on port 80 by nginx at the /admin path. In a browser, go to:

http://<instance-public-ip>/admin

Sign in with the email admin@cloudimg.local and the password from the credentials file. After signing in you land on the administration home, which summarises your last edited and last published entries and your profile.

The Strapi admin panel home after signing in

Step 7: Model Content with the Content-Type Builder

Open the Content-Type Builder from the left navigation to model your content. Create collection types for repeatable content such as articles or products, single types for one off content such as a homepage, and reusable components. For each type you add fields — text, rich text, media, relations, JSON, dates and more — and Strapi writes the schema to disk.

The Strapi Content-Type Builder, where you model collection types, single types and components

After you save a content type, create and edit entries in the Content Manager, which lists the entries for each type and supports the draft and publish workflow. A fresh image ships with the built in User collection type from the Users and Permissions plugin and no custom content yet.

The Strapi Content Manager listing entries for a content type

Step 8: Use the REST and GraphQL Content API

Strapi automatically exposes a fully documented REST API for every content type you create, served on port 80 through nginx alongside the admin panel. A collection type named article, for example, is available at http://<instance-public-ip>/api/articles. By default the API is locked down; grant public read access, or issue API tokens, before consuming it.

  • Roles and permissions — in the admin panel open Settings, then Users and Permissions plugin, then Roles, and enable the find and findOne actions for the relevant content type on the Public role to allow anonymous reads, or use the Authenticated role for signed in users.
  • API tokens — open Settings, then API Tokens, and create a token with read only or full access. Send it as a bearer token, for example Authorization: Bearer <token>, on each request to http://<instance-public-ip>/api/....

Strapi also offers an official GraphQL plugin that publishes a single /graphql endpoint with a playground. It is an optional add on rather than part of the base image; install it from the application directory and rebuild the admin panel:

cd /opt/strapi
sudo -u strapi npm install @strapi/plugin-graphql
sudo -u strapi env NODE_ENV=production npm run build
sudo systemctl restart strapi

After the restart the GraphQL endpoint is available at http://<instance-public-ip>/graphql.

Step 9: The Data Volume

The content store lives on a dedicated EBS volume mounted at /var/lib/strapi. This keeps the SQLite database (data.db) and your uploaded media off the operating system disk and lets you resize or snapshot it independently. The application's public/uploads directory is symlinked here so all media is stored on the data volume. Confirm the mount with:

df -h /var/lib/strapi

To grow the content store, expand the EBS volume in the AWS console, then grow the filesystem on the instance with sudo resize2fs on the underlying device. The SQLite database is suitable for development and small to medium production workloads; for larger deployments point Strapi at an external PostgreSQL database by editing the DATABASE_ settings in /opt/strapi/.env.

Step 10: Enable HTTPS

The admin panel and the content API are served over plain HTTP on port 80 by nginx. For production use, place them behind TLS. Obtain a certificate for your domain (for example with a managed certificate on an Application Load Balancer in front of the instance, or with Certbot installed on the instance), then configure nginx to listen on 443 with your certificate and proxy to 127.0.0.1:1337 exactly as the bundled site does for port 80, keeping the WebSocket upgrade headers in place. When you serve the panel over HTTPS, set url and the public URL in /opt/strapi/config/server.js to your https://your-domain so admin and API links are generated correctly. Restrict the security group so ports 80 and 443 are reachable only from the networks that use the panel and the API.

Step 11: Backup and Maintenance

Back up the content store by snapshotting the /var/lib/strapi EBS volume, which captures the SQLite database and all uploaded media in one consistent image. You can also copy data.db and the uploads directory off the instance for an application level backup. Apply operating system security updates with sudo apt-get update && sudo apt-get upgrade and reboot when a new kernel is installed; Strapi and nginx start automatically on boot. To update Strapi itself, follow the upgrade guidance in the Strapi documentation from the /opt/strapi application directory as the strapi user, then rebuild the admin panel and restart the service.

Support

This image is published and supported by cloudimg. Support covers deployment, content modelling, the REST and GraphQL API, roles and permissions, media and upload configuration, database and storage, TLS and runtime tuning. Contact cloudimg through the support channel listed on the AWS Marketplace listing.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.