Ghost is lightweight, lightning fast blogging platform with a powerful markdown editor. It is developed in NodeJS and supported under GNU/Linux environments. With some modifications it can run on Windows Server environments through IISNode.
While it is really easy to run Ghost on Azure through a GNU/Linux virtual machine (IaaS approach), Azure has his own web applications PaaS-orented service called Azure WebApps that support GNU/Linux as underlying architecture through Docker containers.
This Docker image is based on: Official Ghost Docker image and inspired by Prashanth Madi's one. The main difference with Prashanth one is the support for fully automated Let's Encrypt request, retrieval and management of TLS certificates for the blog.
The version number in the tag always matches the version number of the base image.
Microsoft Azure subscription. Estimated monthly credit needed is about 80 EUR/month
Azure WebApp for Linux. Plan S1 or superior. (~62 EUR/month)
SQL Database for MySQL. Plan Basic 50 DTU or superior. (~15 EUR/month)
A custom domain name for your blog with www. subdomain.
An email address.
Optionally, a SendGrid (or other SMTP provider) account.
It is NOT supported to use SQLite in Azure WebApp Linux as the persitent storage area at /home is a CIFS share that doesn't support the file locking features demanded by SQLite. MySQL is the only option.
Choose a non used Azure WebApp name (ex: calnus), and a custom DNS name you own (ex: calnus.com).
Create the awverify entries in your public DNS provider you would use to map a custom hostname to an Azure WebApp. Map your custom domain (ex: calnus.com) AND www. subdomain (ex: www.calnus.com).
Create an empty Azure Resource Group, create and Azure AD Service Principal with Contributor permissions in that resource group (sample script here, easily adaptable to bash).
After successfull implementation, allow Docker image to be downloaded and executed. You can follow the progress through Kudu.
If needed, adjust your DNS again so Let's Encrypt can sucessfully verify your site.
Restart the webapp or enter in the SSH console and run /usr/local/bin/init-letsencrypt.sh
Very recommended but not required: by default the SQL Database for MySQL has his firewall wide open. It would be a good practice to check the Outbound IP Addresses of the webapp and allow only these IPs in the database firewall.
Environment variables and ARM template parameters description
WEBAPP_CUSTOM_HOSTNAME. Custom DNS of your webapp. Ex: beta.calnus.com
WEBAPP_NAME. The Azure WebApp name. Ex: calnus-beta
RESOURCE_GROUP. The Azure Resource Group naame where the Azure WebApp is deployed.
GHOST_CONTENT. Ghost installation directory, must be in persistent storage. Default: /home/site/wwwroot.
GHOST_URL. URL used for accesing the blog. It will be HTTPS regardless of TLS termination. Ex: https://beta.calnus.com
DB_TYPE. Database type, that can be 'mysql' or 'sqlite'. For the time being, only 'mysql' is supported in Azure WebApp Linux"
DB_HOST. Hostname of the MySQL database. Ex: calnus-beta. This should create calnus-beta.mysql.database.azure.com by ARM template.
DB_NAME. Name of the MySQL database. This should be created by ARM template.
DB_USER. Database username for authentication. This should be created by ARM template.
DB_PASS. Password for authenticating with database. WARNING: it will be visible from Azure Portal. This should be created by ARM template.
SMTP_PASSWORD. Password used in SMTP authentication. WARNING: It will be clearly visible under Azure portal and stored in plain text in the container.
LETSENCRYPT_EMAIL. Email used for TLS certificate generation in Let's Encrypt. Expiration notifications will be recieved in this mailbox.
AZUREAD_SP_URL. URL of the Azure AD Service Principal used to upload and bind certificates. This should be created by the Create-AzureADSP script. Ex: http://calnus-beta
AZUREAD_SP_PASSWORD. Password of the Azure AD Service Principal.
AZUREAD_SP_TENANTID. Tenant ID of the Azure AD Service Principal
HTTP_CUSTOM_ERRORS. Enable NGINX friendly 404 and 50x errors