Ghost on Azure with docker

I spent a lot of time to find out how I can host a ghost docker image on Azure. 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.

I am going to show how to use Azure Web App for containers with ghost image from Docker Hub. We'll use external mount volume and utilize for it Azure Storage account, 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.

We are going learn how to:

Prerequisites

To follow along create Azure account as I described here.

Create Web App for Containers

Login to 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 two datacenters: one 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. Resource group

GhostBlogDocker Resource group

App Service plan and App Service

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

Add Application Settings

Now click on Configuration under Settings for App Service

Configuration

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.

Mount External Storage

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
 
git clone https://sergeydotnet@dev.azure.com/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

Create MySQL Database

Now it's time to set up database. You can use to types of databases with Ghost: SQLLite or MySQL. I prefer to use MySQL and herefrom I am going to show how to configure Ghost with MySQL database.

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: your_db_username@yourservername	

Your configuration should look 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.

Update to latest and greatest ghost image

Update to latest and greatest Ghost image

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.

Create your Account

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

https://sergeynetdocker.azurewebsites.net/ghost

And follow all steps to create an account. These steps are pretty easy and strait forward.

Never IDLE state with Azure Application Insights

There is one more thing I want to mention. All applications hosted on Web Apps become idle if nobody use them.

Read here how to avoid idle state using Azure Application Insights.


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 Azure Database for MySQL

Storage options supporting read / write scenarios

Never IDLE state with Azure Application Insights