I originally contributed the following as a guide for the official Strapi docs, but as they are working on v4 of Strapi at the moment, I figured it would still be good to include somewhere, so here it is on my blog! As a result, the layout of the content won't be my normal blog style, it's more documtation-esq, but it should still do the job.
If you're new to Strapi, Strapi is a headless CMS that you would host somewhere and use their API to pull the content into an application, be it a SPA in your favourite JavaScript framework, a mobile app, or something else.
These guides are tested against the v3 release of Strapi, as v4 is in beta at the time of writing. It's likely that much of the content covered here will be applicable for v4, the only thing I expect to change is how to use the file upload provider, I'm unsure if the existing plugin will work with v4.
There are three resources in Azure that are required to run Strapi in a PaaS model, AppService to host the Strapi web application, Storage to store images/uploaded assets, and a database, Azure has managed MySQL and Postgres to choose from (for this tutorial, we'll use MySQL, but the steps are the same for MySQL).
In this section we'll use the Azure Portal to create the required resources to host Strapi.
Navigate to the Azure Portal
Click Create a resource and search for Resource group from the provided search box
Provide a name for your Resource Group, my-strapi-app
, and select a region
Click Review + create then Create
Navigate to the Resource Group once it's created, click Create resources
and search for Web App
Ensure the Subscription and Resource Group are correct, then provide the following configuration for the app:
- _Name_ - `my-strapi-app`
- _Publish_ - `Code`
- _Runtime stack_ - `Node 14 LTS`
- _Operating System_ - `Linux`
- _Region_ - Select an appropriate region
Use the App Service Plan to select the appropriate Sku and size for the level of scale your app will need (refer to the Azure docs for more information on the various Sku and sizes)
Click Review + create then Create
Navigate back to the Resource Group and click Create then search for Storage account and click Create
Ensure the Subscription and Resource Group are correct, then provide the following configuration for the storage account:
- _Name_ - `my-strapi-app`
- _Region_ - Select an appropriate region
- _Performance_ - `Standard`
- _Redundancy_ - Select the appropriate level of redundancy for your files
Click Review + create then Create
Navigate back to the Resource Group and click Create then search for Azure Database for MySQL and click Create
Select Single server for the service type
Ensure the Subscription and Resource Group are correct, then provide the following configuration for the storage account:
- _Name_ - `my-strapi-db`
- _Data source_ - `None` (unless you're wanting to import from a backup)
- _Location_ - Select an appropriate region
- _Version_ - `5.7`
- _Compute + storage_ - Select an appropriate scale for your requirements (Basic is adequate for many Strapi workloads)
Once all the resources are created, you will need to get the connection information for the MySQL and Storage account to the Web App, as well as configure the resources for use.
strapi-uploads
, and set Public access level to Blob
, then click CreateAllow access to Azure services
to Yes
and click Savemysql
cli:- `mysql --host <server> --user <username> -p`
CREATE DATABASE strapi;
then close the Cloud Shell
In this section, we'll use the Azure CLI to create the required resources. This will assume you have some familiarity with the Azure CLI and how to find the right values.
Create a new Resource Group
rgName=my-strapi-app
location=westus
az group create --name $rgName --location $location
Create a new Linux App Service Plan (ensure you change the number-of-workers
and sku
to meet your scale requirements)
appPlanName=strapi-app-service-plan
az appservice plan create --resource-group $rgName --name $appPlanName --is-linux --number-of-workers 4 --sku S1 --location $location
Create a Web App running Node.js 14
webAppName=my-strapi-app
az webapp create --resource-group $rgName --name $webAppName --plan $appPlanName --runtime "node|10.14"
Create a Storage Account
saName=mystrapiapp
az storage account create --resource-group $rgName --name $saName --location $location
# Get the access key
saKey=$(az storage account keys list --account-name $saName --query "[?keyName=='key1'].value" --output tsv)
# Add a container to the storage account
container=strapi-uploads
az storage container create --name $container --public-access blob --access-key $saKey --account-name $saName
Create a MySQL database
serverName=my-strapi-db
dbName=strapi
username=strapi
password=...
# Create the server
az mysql server create --resource-group $rgName --name $serverName --location $location --admin-user $username --admin-password $password --version 5.7 --sku-name B_Gen5_1
# Create the database
az mysql db create --resource-group $rgName --name $dbName --server-name $serverName
# Allow Azure resources through the firewall
az mysql server firewall-rule create --resource-group $rgName --server-name $serverName --name AllowAllAzureIps --start-ip-address 0.0.0.0 --end-ip-address 0.0.0.0
Add configuration values to the Web App
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting STORAGE_ACCOUNT=$saName
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting STORAGE_ACCOUNT_KEY=$saKey
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting STORAGE_ACCOUNT_CONTAINER=$container
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting DATABASE_HOST=$serverName.mysql.database.azure.com
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting DATABASE_USERNAME=$username@$serverName
az webapp config appsettings set --resource-group $rgName --name $webAppName --setting DATABASE_PASSWORD=$password
To deploy using an Azure Resource Manager template, use the botton below, or upload this template as a custom deployment in Azure.
As AppService is a PaaS hosting model, an upload provider will be required to save the uploaded assets to Azure Storage. Check out https://github.com/jakeFeldman/strapi-provider-upload-azure-storage for more details on using Azure Storage as an upload provider.
For local development, you can either use the standard Strapi file/image upload provider (which stored on the local disk), or the Azurite emulator.
Azure AppService can be deployed to using CI/CD pipelines or via FTPS, refer to the Azure docs on how to do this for your preferred manner.
To start the Node.js application, AppService will run the npm start
command. As there is no guarantee that the symlinks created by npm install
were preserved (in the case of an upload from a CI/CD pipeline) it is recommended that the npm start
command directly references the Keystone entry point:
"scripts": {
"start": "node node_modules/strapi/bin/strapi.js start"
}
This has been a look at how we can use the different PaaS features of Azure to host Strapi, and the different ways in which you can setup those resources. I prefer to use the Resource Manager template myself, and then configure GitHub Actions as the CI/CD pipeline so that deployments all happen smoothly in the future.
Hopefully this makes it easier for you to also get your Strapi sites running in Azure, and once Strapi 4 is out, I'll get some updated content on the differences that you need to be aware of when hosting in Azure.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.