I spent a lot of time to find out how I can host a ghost docker image on Azure with mount volume from Azure Storage Account and I couldn't find anything that I could understand and use. That's why I decided to do research and here is step by step documentation of it.

Here I am going to show how to use Azure Web App for containers with ghost image from Docker Hub as example. We will use external mount volume and  utilize for it Azure Storage account. Use Azure MySQL database and use Application Insights to keep our site always "awake", meaning never idle state.

This article is about how to host docker containers on Azure Web Apps for containers with Azure Storage Account for external storage. As example I am using ghost image.

To follow along create Azure account as I described here.

Login to your Azure portal and click on Create a resource

Create a resource

Start to write web app for

New Web App for Containers

Choose Web App for Containers

Click Create

Create Web App for Containers

Fill out information

Web App
New App Service Plan

Choose to create new or use exiting Resource Group, here I am creating a new Resource Group, provide a name for your web site, choose Docker Image, Operating System Linux and Region where you live. For me the closest Region is West Europe. Soon Norway going to have own regions because it is coming to new datacenters in Norway one is in Stavanger and another one in Oslo. Here is announcement.

Choose also to create a new App Service Plan and choose Basic size. I think basic should be enough to run the blog.

Click on Docker tab

Docker

Choose Single Container, Image Source should be Docker Hub if you want to get docker images from Docker Hub. I am going to use ghost image from Docker Hub. Access Type should be Public. Image and tag should be the latest docker image for ghost. Login to Docker Hub or create an account and search for ghost.

Docker Hub

Find official ghost image and take a look at supported tags

ghost tags

Pick any one you like, the alpine is the smallest possible image, that's why I am going to use that one. Image and tag should be: ghost:2.30-alpine or the latest one, ghost is the name of the image and 2.30-alpine is the tag.

Now we are ready to click on Review and create button. Azure portal checking all parameters and create following resources for you.

GhostBlogDocker
Web Apps

Test that everything works by clicking on App Service and copy/paste URL to your favorite web browser.

App Service

It should look like this

Ghost

Now click on Configuration under Settings for App Service

Configuration

and New application setting

Add new Application setting  and call it url. The value should be the same you pasted in the browser before.

url appsetting

Click on OK.

Remember to click on Save.

Application Settings

Other settings was added by default.

Check the values, anyway

DOCKER_REGISTRY_SERVER_URL

And

WEBSITES_ENABLE_APP_SERVICE_STORAGE

Restart the App Service.

Now we are going to mount external storage for the ghost container running on App Service. For external storage we are going to use Azure Storage account. Read this post how to create azure storage account.

Now when we created web app for containers and storage account with file share called ghost-fileshare we can mount our external volume from storage account.

As Microsoft states here we can't use blob containers for read / write scenarios, we have to use File Shares.

Go to App Service and click on Configuration

Overview

Choose Path mappings tab

Path mappings

Click on + New Azure Storage Mount

New Azure Storage Mount

Provide Name, Basic for Configuration options, choose Storage accounts. Storage type has to be Azure Files. Choose Storage container from dropdown list and provide Mount path. Mount path should be

/var/lib/ghost/content

Click on OK and on Save

Save

Now start your browser and check that everything is still working.

Unfortunately ghost can't create all necessary files in the storage account. I am not sure why but hopefully they will fix it.

So, browser looks like this

Application Error

Open storage explorer and take a look.

The structure should be like this

ghost-fileshare

One of the way out is to create all this folders manually. And the easiest way to get all this folders locally is to clone my GitHub repo from

https://github.com/smigalni/GhostContentFolder

git clone https://github.com/smigalni/GhostContentFolder.git

Or go to my public Azure DevOps project and clone repo from there

https://dev.azure.com/sergeydotnet/GhostPlatformPublic/_git/GhostContentFolder

https://[email protected]/sergeydotnet/GhostPlatformPublic/_git/GhostContentFolder

Upload all this folders to the storage account.

Now restart App Service in the Azure portal. And open the browser, wait for a while. You ghost platform should be in a good shape and looks like this.

Ghost

Now we have to set up database, to run on docker we can't use SQLite database, we have to create MySQL.

How to create MySQL database you can read my blog post here.

Now when we created MySQL server and database, we have to configure our App Service.

Click on App Service we created and then click on Configuration under Settings.

Add more application settings by clicking on New application settings

Application settings
database__client: mysql

database__connection__database: ghost (or your database name you created)

database__connection__host: yourservername.mysql.database.azure.com

database__connection__password: your password

database__connection__port: 3306 (if you don't changed the default port)

database__connection__user: [email protected]	

Your configuration should looks like this

Configuration

Remember to save changes. Restart App Service. And check that all tables are created in the ghost database.

ghost database

Remember to set firewall rules for MySql server your created to allow your App Service get access to database.

Go to MySql server your created and choose Connection security under Settings.

MySql server

Provide the Role name and the IP range. Remember to have SSL settings DISABLED.

Now the only thing you have to do to keep up to date with the latest and greatest ghost image is go to your App Service -> Container settings

Container settings

And change the ghost image tag to the latest version.

Now it's time to create a ghost user. Open your site with slash ghost , mine looks like this

https://sergeynetdocker.azurewebsites.net/ghost

And follow all steps to create a user. These steps are pretty easy and strait forward.

There is one more thing I want to mention. All applications hosted on Web Apps become idle if nobody use them. And therefore first request "wake them up" and takes a little bit more time than the others. To keep the application always "awake" the easiest way is to use Application Insights. To read about how to create Application Insights read my blog post here.

Open Application Insights and click on Availability

Availability

Click on Add test

Create test

Provide the name for the test, Test type should be URL ping test and  url for you App Service. Choose also Test frequency, I think each 15 minutes is good enough. Click on Create.

Now your blog will be always alive. In the next blog post I am going to show how we can automate all this manual steps using Terraform and Azure DevOps.

Happy blogging.


Create Azure account

Azure portal

Microsoft announces two new datacentre regions in Norway

Azure Storage account

GitHub Ghost Content Folder

Azure DevOps Ghost Content Folder

Create Application Insights

Create Azure Database for MySQL

Storage options supporting read / write scenarios