Strapi
Overview
Strapi is a leading open-source headless CMS built on Node.js. Teams model content with a visual Content-Type Builder, manage entries in a rich admin panel, and deliver everything through an automatically generated REST and GraphQL API.
This SecureAnyCloud image installs Strapi 5.48.1 on Node.js 22 LTS and builds the admin panel. It runs Strapi as a systemd service behind an nginx reverse proxy on port 80. All application secrets and a unique admin user are generated on the first boot of every VM.
What you get:
- Strapi 5.48.1 on Node.js 22 LTS with the admin panel pre-built
- The admin panel (
/admin) and REST + GraphQL content API published on port 80 via nginx - A dedicated Azure data disk at
/var/lib/strapifor the SQLite database and uploaded media - Per-VM application secrets and a unique admin user generated on first boot
strapi.serviceandnginx.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B2ms (2 vCPU / 8 GiB RAM) is a good starting size.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the admin panel and API. For public exposure, put TLS in front of the VM (see Enabling HTTPS).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Strapi by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the dedicated data disk on the Disks tab, then select Review + create and Create.
Step 2 - Deploy from the Azure CLI
Accept the Marketplace terms once per subscription, then create the VM and open port 80.
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:strapi-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name strapi \
--image sac1647283583153:strapi-ubuntu-24-04:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name strapi --port 80 --priority 1010Step 3 - Connect to your VM
Connect over SSH as azureuser.
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
Check that Strapi and nginx are both active:
systemctl is-active strapi.service nginx.serviceBoth should report active. On first boot, Strapi generates its secrets, creates the admin user and builds a clean database.
Step 5 - Retrieve your admin credentials
The admin password is generated on the first boot of your VM and written to a root-only file. Read it with sudo:
sudo cat /root/strapi-credentials.txtThe file contains strapi.admin.email (admin@sac.local) and strapi.admin.pass. Store the password somewhere safe.
Step 6 - Check the health endpoint
Strapi exposes a liveness endpoint that returns 204:
curl -s -o /dev/null -w '%{http_code}\n' http://localhost/_healthStep 7 - Open the admin panel
Browse to http://<vm-public-ip>/admin. Sign in with admin@sac.local and the password from Step 5.
The admin home gives you an overview of your content and workspace.
Use the Content-Type Builder to model collection types, single types and their fields. Strapi generates a REST and GraphQL API for every type you create.
Create and manage entries in the Content Manager. It supports draft and publish workflows, the media library and fine-grained roles.
Step 8 - Authenticate against the admin API
Strapi issues an admin JWT from /admin/login. Run the following to confirm that the generated credentials work:
curl -s -H 'Content-Type: application/json' --data '{"email":"admin@sac.local","password":"<STRAPI_ADMIN_PASSWORD>"}' http://localhost/admin/login | head -c 80; echoA successful login returns a JSON object containing a "token".
Step 9 - Use the content API
Once you have modelled content and created entries, Strapi serves them over REST and GraphQL on the same port 80. For example, after you create an article collection type with some published entries, request them like this:
# REST curl http://<vm-public-ip>/api/articles
# Generate an API token under Settings -> API Tokens, then:
curl -H "Authorization: Bearer <api-token>" http://<vm-public-ip>/api/articlesTo use GraphQL, install the GraphQL plugin from the Marketplace in the admin panel.
Step 10 - Confirm content lives on the dedicated disk
The SQLite database and uploaded media are stored on the dedicated Azure data disk. They survive OS changes, and you can resize the disk independently. Confirm the mount:
findmnt /var/lib/strapiThe mount is backed by a separate Azure data disk that is captured into the image and re-provisioned on every VM.
Security notes: enabling HTTPS
The nginx reverse proxy serves plain HTTP on port 80. For public exposure, put a certificate in front of it. Add a DNS name for the VM and install certbot, or use the companion SecureAnyCloud nginx-ssl-certbot image as a TLS reverse proxy.
Keep Strapi bound to loopback (127.0.0.1:1337) so the only public surface is the TLS-terminating proxy. Set the url in /opt/strapi/config/server.js to your HTTPS address, then restart Strapi.
Maintenance
- Backups: snapshot the
/var/lib/strapidata disk to back up the database and media. - Database: the image uses SQLite, which suits a single server. For production scale, configure PostgreSQL in
/opt/strapi/config/database.jsand.env. - Service: run
sudo systemctl restart strapiafter configuration changes. Read logs withjournalctl -u strapi. - Security patches: unattended-upgrades stays enabled, so the OS keeps receiving security updates automatically.
Support
SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.
Deploy on Azure
Launch Strapi on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
Strapi is a leading open-source headless CMS built on Node.js. 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. Strapi adds fine-grained roles and permissions, a draft and publish workflow, media management and internationalisation.
This SecureAnyCloud image installs Strapi 5.48.1 on Node.js 22 LTS and puts nginx in front of it. The admin password is unique to every instance, and your content lives on a dedicated EBS data volume.
What you get:
- Strapi 5.48.1 installed under
/opt/strapion Node.js 22 LTS - A dedicated unprivileged
strapisystem account, running Strapi under a systemd service that starts on boot and restarts on failure - A content store at
/var/lib/strapiholding the SQLite database (data.db) and your uploaded media, on a dedicated, independently resizable EBS data volume that survives instance replacement - Strapi bound to the loopback interface only (
127.0.0.1:1337) and never exposed directly - An nginx reverse proxy that publishes the admin panel and the content API on port 80, with WebSocket upgrade support and a generous upload limit for media
- An administrator password generated on the first boot of every instance, so two instances launched from the same Amazon Machine Image never share a password
- Credentials written to
/root/strapi-credentials.txtwith mode 0600, readable only by root
Strapi provides its own admin authentication at /admin. nginx is a plain pass-through proxy and adds no second authentication layer.
Prerequisites
Before you deploy this image, make sure you have:
- 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 that allows 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
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 SecureAnyCloud listing, choose Select, then choose 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. 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.
Launch the Instance from the AWS CLI
Run the following command to launch an instance from the SecureAnyCloud Strapi Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing. Replace <key-name> with your EC2 key pair name and <subnet-id> with your subnet ID. Replace <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. You can read them from the EC2 console or with aws ec2 describe-instances.
Connect to Your Instance
Connect over SSH with 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>Confirm Strapi Is Running
Over SSH, confirm that Strapi 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/_healthBoth 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.
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.txtThe file lists the admin panel URL, the administrator email (admin@sac.local) and the generated password. Keep the password somewhere safe.
Sign In to the Admin Panel
nginx serves the Strapi admin panel on port 80 at the /admin path. In a browser, go to:
http://<instance-public-ip>/adminSign in with the email admin@sac.local and the password from the credentials file. You land on the administration home, which summarises your last edited and last published entries and your profile.
Model Content with the Content-Type Builder
Open the Content-Type Builder from the left navigation. 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, add fields such as text, rich text, media, relations, JSON and dates. Strapi writes the schema to disk.
After you save a content type, create and edit entries in the Content Manager. It 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.
Use the REST and GraphQL Content API
Strapi automatically exposes a fully documented REST API for every content type you create. nginx serves it on port 80 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 you consume it.
- Roles and permissions: in the admin panel, open Settings, then Users and Permissions plugin, then Roles. Enable the
findandfindOneactions for the relevant content type on the Public role to allow anonymous reads. 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 on each request to
http://<instance-public-ip>/api/..., for exampleAuthorization: Bearer <token>.
Strapi also offers an official GraphQL plugin that publishes a single /graphql endpoint with a playground. It is an optional add-on and not 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 strapiAfter the restart the GraphQL endpoint is available at http://<instance-public-ip>/graphql.
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 you can resize or snapshot the volume independently. The application's public/uploads directory is symlinked here, so all media is stored on the data volume. Confirm the mount:
df -h /var/lib/strapiTo grow the content store, expand the EBS volume in the AWS console. Then grow the filesystem on the instance by running sudo resize2fs on the underlying device.
The SQLite database suits 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.
Enable HTTPS
nginx serves the admin panel and the content API over plain HTTP on port 80. In production, place them behind TLS.
Obtain a certificate for your domain, for example a managed certificate on an Application Load Balancer in front of the instance, or 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. Keep 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. This ensures 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.
Backup and Maintenance
Back up the content store by snapshotting the /var/lib/strapi EBS volume. The snapshot captures the SQLite database and all uploaded media in one consistent image. For an application-level backup, copy data.db and the uploads directory off the instance.
Apply operating system security updates with sudo apt-get update && sudo apt-get upgrade. 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. Run it 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 SecureAnyCloud. 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 SecureAnyCloud 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.
Deploy on AWS
Launch Strapi on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com