How to Install and Configure Ghost with Docker on Arm64 Debian

How to Install and Configure Ghost with Docker on Arm64 Debian
Photo by Toa Heftiba / Unsplash

Introduction

In this guide, I’ll walk you through setting up Ghost with Docker on a server powered by Arm64 Ampere Altra processors. I’ll run Ghost on Hetzner’s CAX11, which provides two vCPUs and 4GB RAM, ensuring a high-performance Ghost installation with room for other applications. The price starts at €4.51/month, making it affordable for all budgets.

If you follow the complete guide, including establishing the prerequisites, then getting up and running is as easy as installing docker, cloning a git repository and changing variables.

Prerequisites

  • A server with Arm64 architecture and Debian 12 (e.g., Hetzner Cloud CAX11).
  • SSH access to the server as root.
  • A domain name managed by Cloudflare (required for LetsEncrypt DNS validation via the API).
  • A DNS A-record pointing to your server’s IP address.
  • The SSL/TLS encryption mode of the domain in Cloudflare should be set to Full, or the proxy settings against the domain records should be turned off.
  • A Cloudflare API token with rights to manage the domain you will be using with Ghost
  • A Mailgun account with your domain name registered. At the time of writing, you can use the Mailgun Flex plan to send 1000 emails per month for free.
  • The SMTP credential password for your domain in Mailgun

Step 1 - Create a Local User ghostadmin

Before we do anything else, we’ll create a user named ghostadmin for this setup and add it to the sudo group.

adduser ghostadmin
usermod -aG sudo ghostadmin

Log out from root and log back in as our new ghostadmin user via SSH.

Step 2 - Set up Docker’s apt repository and install the required packages

Before installing the Docker Engine for the first time, you must set up the Docker apt repository.

sudo apt update && apt upgrade
sudo apt-get install ca-certificates curl nano git
sudo install -m 0755 -d /etc/apt/keyrings

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

Step 3 - Install Docker

To install the latest version of Docker, run the following:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verify the Docker installation:

sudo docker run hello-world

Add our ghostadmin user to the docker group to run Docker commands without sudo:

sudo usermod -aG docker ghostadmin

Log out and back in to refresh group memberships.

Step 4 - Clone the project template repository

Our Ghost installation is going to be a multi-container application made up of three separate containers:

  • Ghost - The Ghost CMS itself.
  • MySql - The database utilised by Ghost.
  • SWAG - A secure web application gateway that will act as a reverse proxy and automate free SSL certificate generation and renewal from LetsEncrypt.

To get them up and running, we will clone a git repository containing the project files and customise them with your environment’s settings.

git clone https://github.com/stevefisher/ghostcms.git
cd ~/ghostcms

This contains the following six files:

  • .env (Needs customisation) - environment variables.
  • .gitignore - used if you want to create your own git repository. Outside this project template, the .env and cloudflare.ini files should never be source-controlled due to the secrets they will contain.
  • cloudflare.ini (Needs customisation) - contains a Cloudflare API token SWAG uses to create domain validation records.
  • default.conf - a customised NGINX configuration file for SWAG.
  • docker-compose.yml - our docker-compose file used to define our multi-container application.
  • ghost.subdomain.conf (Needs customisation) - A swag configuration file configuring NGINX reverse proxy settings for Ghost.

Step 5 - Customize the project files

To get up and running, customise the following three files with values that fit your environment. All the values that need changing are indicated with < >

.env file

DB_ROOT_PASSWORD = <long and complex password>
DB_GHOST_PASSWORD = <long and complex password>
URL = <yourdomain.com>
EMAIL = <your email>
MAIL_TRANSPORT = SMTP
MAIL_USER = <[email protected]>
MAIL_PASSWORD = <mailgun smtp password>
MAIL_HOST = smtp.eu.mailgun.org
MAIL_PORT = 587
MAIL_SECURE_CONNECTION = true

cloudflare.ini file

dns_cloudflare_api_token = <your cloudflare api token>

ghost.subdomain.conf

server {
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    server_name <yourdomain.com>;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app ghost;
        set $upstream_port 2368;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}

Step 6 - Start the docker containers

It’s time to bring up our docker containers:

docker compose up -d

Now, give your site a few minutes to create the ghost tables in the MySQL database. If everything has gone well, you can browse your new ghost site.

Step 6 - Post-Installation Security

Before wrapping up, we will improve our server’s security by placing it behind a firewall. As you can add a firewall to Hetzners cloud servers, I’ve decided to use that, but you could configure UFW on the server itself if you prefer.

Setup is as simple as adding a firewall to the server and configuring it, as I have done in this screenshot.

Conclusion

Congratulations! You have set up your Ghost blog using Docker for Ghost, MySQL, and SWAG on the Arm64 architecture server.

For more information on Ghost, refer to the official Ghost documentation.