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
Start to write web app for
Choose Web App for Containers
Fill out information
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
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.
Find official ghost image and take a look at supported 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.
Test that everything works by clicking on App Service and copy/paste URL to your favorite web browser.
It should look like this
Now click on Configuration under Settings for App Service
and New application setting
Add new Application setting and call it url. The value should be the same you pasted in the browser before.
Click on OK.
Remember to click on Save.
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 blob called ghost-container we can mount our external volume from storage account.
Go to App Service and click on Configuration
Choose Path mappings tab and click on + New Azure Storage Mount
Somehow it doesn't work properly with Internet Explorer, so you have to use f.ex. Google Chrome.
Click on OK.
And on 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
Open storage explorer and take a look
There is nothing has been created in the blob, but the structure should be like this
The only way out, I found is to create all this folders manually. And the easiest way to get all this folders locally for you is to clone my GitHub repo from https://github.com/smigalni?tab=repositories
git clone https://github.com/smigalni/GhostContentFolder.git
Or go to my public Azure DevOps project https://dev.azure.com/sergeydotnet/GhostPlatformPublic/_git/GhostContentFolder
and clone repo from here
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.
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 in my this 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
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]
Remember to save changes. Restart App Service. And check that all tables are created in the ghost database.
Remember to set firewall rules for MySql database for your App Service otherwise you will not get access to database.
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
And change the ghost image tag to the latest version.
Now it's time to create a ghost user. Open your site with backslash ghost, mine looks like this
And follow all steps to create a user. This is pretty easy step.
There is one more thing I want to mention. All applications hosted on Web Apps become idle if nobody use them. And to "wake them up" therefore first request takes a little bit more time then 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
Click on Add 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.