Sitemap

Tutorial: Strapi (v4.x) on Azure - Web and Static Apps with Github CD/CI and PostgreSQL server

10 min readNov 7, 2021
Press enter or click to view image in full size

Introduction

The Azure ecosystem is not the same as it has been a few year ago, they’re pushing hard to make all the opensource tools, specially NodeJS based ones, to be easy to integrate into their ecosystem. Strapi (Node based Headless CMS) is one of the tools I’ve been trying to integrate fully into Azure, and it took me a while to finally understand how it’s done. I want to share this knowledge with you.

Requisites

  • Azure account — to create Web and Static Web Apps and a PostgreSQL server
  • Github account — you’ll be using Github workflows to build and deploy Strapi
  • Node — version >=10.16.0 <=14.x.x
  • Yarn — you can use npm if you prefer
  • Git — so we can create/manage local/remote git repositories

Goal

  • Create an Azure Web App for the server-side of Strapi with CI/CD
  • Create an Azure Static Web App for the Strapi Admin Panel with CI/CD
  • Make sure Strapi Admin Panel connects to Strapi

Steps

  1. Create a local Strapi project
  2. Setup the Github repo
  3. Prepare for Azure integration
  4. Create an Azure Web App
  5. Create an Azure Static Web App
  6. Update the Github workflow for the Azure Web App
  7. Update the Github workflow for the Azure Static Web App
  8. Create an Azure Database for PostgreSQL
  9. Create a remote database for Strapi
  10. Add database configurations to the Strapi Web App
  11. Add production configuration to Strapi project

1. Create a Strapi project

So, let’s create our Strapi project by running:

yarn create strapi-app strapi-on-azure --quickstart

This will create a quick Strapi project with all the relevant dependencies and, by default, it’ll use Sqlite3 as the database.

If you haven’t tried Strapi feel free to create a local admin user through the Strapi Admin Panel. You can find all the resources you need in strapi.io/resource-center.

2. Setup the Github repo

At this point, I’d recommend initialising a git repo inside the newly created project folder and sync it with your Github repository.

git add .
git -m commit "Initial strapi project"
git remote add origin git@github.com:<your-username>/strapi-on-azure.git
git push --set-upstream origin master

Now you’re ready to make the relevant changes.

3. Prepare project for Azure integration

First we’ll have to create a JavaScript file in the root of our project that will be the entry point for our Strapi app, i.e. node server. I called mine server.js.

/* ./server.js */const strapi = require('@strapi/strapi')
strapi().start()

After this, edit your package.json file and update the start script so it looks like this:

“start”: “NODE_ENV=production node server.js”,

Commit and push your code:

git add .
git commit -m "Start script updated"
git push

4. Create an Azure Web App

Log into your Azure account and create a new Web App.

Press enter or click to view image in full size
Create Azure Resource

Fill the relevant fields. You might need to create a new Resource Group and/or a new App Service Plan

Press enter or click to view image in full size
Create Azure Web App

Make sure you select the correct spec for your Web App. Strapi recommends 2 GB of memory but it should work fine with 1.75 GB because we’ll be running the server side Strapi only. Click on Apply.

Press enter or click to view image in full size
Select Azure Web App SPA

Once you’re happy with your spec click the Next: Deployment button. On the next screen we are going to enable Continuous Development.

You’ll have to authorise Azure to access your Github account.

Press enter or click to view image in full size
Setup Azure Web App Deployment

Now you can choose you can choose your Strapi project from the Github repo and the relevant branch. In our case we select the master branch. In a production scenario you’ll probably want to have a production branch.

Azure will generate a Github workflow configuration file (that we’ll be changing below). If you inspect the file (by clicking the Preview file button) you’ll be able to understand, roughly, what’s going to happen every time you push changes to the master branch.

Let’s ignore, the next two steps, i.e. Monitoring and Tags by pressing the Next button twice.

Press enter or click to view image in full size
Select Azure Web App Deployment git repo source

On the last step you configuration will be validated, and if there’s nothing amiss you can now create the Web App by pressing the Create button.

Press enter or click to view image in full size
Review and Create Azure Web App

Once the resource is created the Continuous Development task will kick in. Unfortunately, the provided workflow template is not sufficient to make the build and deploy work. We’ll get to that later.

You can see the workflow running under you Github repo and the Actions tab.

Press enter or click to view image in full size
Watch workflow run

I recommend you stop this build and deploy job by pressing the three dots, at the end of the running workflow, and select Cancel run. Otherwise, you’ll end up having to clean your Github storage.

One thing that I found useful was to use a Github workflow to clean my artifacts storage every day for the Strapi Web App builds. There’s a good article to help you with that.

Next step will be to create the Static Web App.

5. Create an Azure Static Web App

Under Create a resource we need to search for static web app and select it from the dropdown.

Press enter or click to view image in full size
Create Azure resource Static Web App

Click on Create.

Press enter or click to view image in full size
Press Create Static Web App button

Fill all the required fields, and choose Github under your Deployment details.

Press enter or click to view image in full size
Fill form to create Azure Static Web App

Under Build details for the Build process select Custom. Then for the Output location write build. Click on Review + create button.

Press enter or click to view image in full size
Setup build details for Azure Static App

And finally click on Create.

Press enter or click to view image in full size
Review and Create Azure Static App

6. Update the Github workflow for the Azure Web App

Next step is to change the Build and deploy workflow for our Azure Web App, i.e. Strapi. You can do that buy selecting the View workflow file for a specific run (as shown below). Alternatively, you can just git fetch and git rebase to get the new workflow in your local project — you’ll see it under .github/workflows.

Press enter or click to view image in full size
Find Azure App workflow build

Now click on the edit icon.

Press enter or click to view image in full size
Edit Azure App workflow

The final workflow should look like the one below. Make sure you DON’T edit the line that starts with publish-profile — we want to keep the secret that was generated for you.

name: Build and deploy Strapi to Azure Web App - strapi-on-azureon:
push:
branches:
- master
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js version
uses: actions/setup-node@v1
with:
node-version: '14.x'
- name: npm install, build, and test
run: |
npm install
npm run test --if-present

- name: 'Tar files'
run: tar -cf node-app.tar .
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: node-app
path: node-app.tar
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: 'Production'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v2
with:
name: node-app

- name: 'Untar files'
run: 'tar -xf node-app.tar'
- name: 'Deploy to Azure Web App'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: 'strapi-on-azure'
slot-name: 'Production'
publish-profile: ${{ secrets.<auto generated azure secret name> }}
package: .

Finally, commit the changes.

Press enter or click to view image in full size
Commit new Azure App workflow changes

Now, we’ll have to tweak the Static Web App build and deploy workflow too.

7. Update the Github workflow for the Static Azure Web App

Select View workflow file for the Actions tab in Github.

Press enter or click to view image in full size
Select Azure Static App workflow

Now edit the file and add the following line

app_build_command: "NODE_ENV=production yarn build"

Right before the line

app_location: "/" # App source code path
Press enter or click to view image in full size
Edit Azure Static App workflow

Commit your changes.

8. Create an Azure Database for PostgreSQL

For the sake of this tutorial I was hoping to use Sqlite3 as the database, but unfortunately I wasn’t able to have it running in a Azure Web App (Linux), yet. Therefore, I’ve decided to connect our Strapi Web App to an Azure PostgreSQL server because I thought it would be a valid option for those who want to use Strapi in production.

Press enter or click to view image in full size
Create Azure resource — PostgreSQL

Click on Create.

Press enter or click to view image in full size
Press create database for PostgreSQL button

Then Create a Flexible server — this will allow you to start with a Development server and scale it up later when you need more CPU cores or memory.

Press enter or click to view image in full size
Select the Flexible server option and click create

Fill in the form. For the purpose of this article, we’re going to create a Development database. Also, make sure you remember the user name and password, you’ll need it for the Strapi Web App configurations — so Strapi can connect to the Postgres server, obviously.

Press enter or click to view image in full size
Fill the form to create PostgreSQL server

Make sure you allow public access from Azure service within Azure to this service. In a later stage you might just specify a range of IP addresses that you can get from the Networking section of your Azure Web App.

Press enter or click to view image in full size
Review PostgreSQL server firewall rules

Review your choices and press Create.

Press enter or click to view image in full size
Create the PostreSQL server

9. Create a remote database for Strapi

Connecting to remote postgres server. The first time we connect we need to specify the default database name, i.e. postgres

Press enter or click to view image in full size
Find postgreSQL connection strings
psql "host=strapi-on-azure.postgres.database.azure.com port=5432 dbname=postgres user=malhao password=YourPassword123 sslmode=require"

After connecting to the database you’ll have to create the database for Strapi to use.

create database strapi_on_azure;

We can check if the database was created by listing all existing databases:

postgres=> \l

After that we disconnect from our database.

postgres=> \q

10. Add database configurations to the Strapi Web App

Now, let’s add the database configurations to our Strapi Web App. Go to Settings > Configurations section and click on Advanced edit.

Press enter or click to view image in full size
Add postgreSQL server configurations to Azure Web App

The final Settings file should look something like this:

[
{
"name": "DATABASE_HOST",
"value": "strapi-on-azure.postgres.database.azure.com",
"slotSetting": false
},
{
"name": "DATABASE_NAME",
"value": "strapi_on_azure",
"slotSetting": false
},
{
"name": "DATABASE_PASSWORD",
"value": "YourDatabasePassword",
"slotSetting": false
},
{
"name": "DATABASE_PORT",
"value": "5432",
"slotSetting": false
},
{
"name": "DATABASE_SSL",
"value": "true",
"slotSetting": false
},
{
"name": "DATABASE_USERNAME",
"value": "malhao",
"slotSetting": false
},
{
"name": "WEBSITE_HTTPLOGGING_RETENTION_DAYS",
"value": "30",
"slotSetting": false
}
]

Finally save your changes.

Press enter or click to view image in full size
Save Azure Web App configurations

11. Add production configuration to Strapi project

Now we need to create the server configuration in our Strapi project.

/* ./config/env/production/server.js */module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
url: 'https://strapi-on-azure.azurewebsites.net',
});

And the admin panel configuration. There’s no need to set the full path to your front-end (i.e. https://witty-sky-061465203.azurestaticapps.net). “/” will suffice.

module.exports = ({ env }) => ({
auth: {
secret: env('ADMIN_JWT_SECRET'),
},
url: '/',
serveAdminPanel: false
});

In order to use the PostgrSQL server we’ll have to install the pq node package.

yarn add pg

And add the configuration file.

/* ./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: env.bool('DATABASE_SSL', false),
},
},
});

Now, commit and push your code. Go make yourself a cuppa, you deserve it if you came this far.

Once the builds finish open your Static Web App URL. In my case: https://witty-sky-061465203.azurestaticapps.net

If everything went according to plan, you should be able to create your admin credentials and login into the admin portal for the very first time.

Hurrah! It’s all done.

The next step is probably to configure an email provider. With previous Strapi instances I’ve used SendGrid and I’m still happy with it — make sure you always have a whitelisted IP address so you can login into your account. Otherwise, you’ll have to raise a customer support ticket — happened to me.

--

--

Responses (2)