Ghost is a versatile, open-source platform designed for publishing and blogging, built on Node.js. Renowned for its sleek design and ease of use, Ghost was first released in 2013 under the MIT license.
Traefik, on the other hand, is a modern HTTP reverse proxy and load balancer specifically for microservices. It simplifies the deployment of these services by integrating seamlessly with various infrastructure components like Docker, Swarm Mode, Kubernetes, Amazon ECS, Rancher, Etcd, and Consul.
This tutorial offers a comprehensive, step-by-step guide on how to install and configure Ghost as a Docker container. We will employ the latest version of Docker CE, utilize MySQL as our database, and set up Traefik as a reverse proxy.
Prerequisites
- Ubuntu 18.04 LTS
- Root privileges
What We Will Do
- Install Docker CE on Ubuntu 18.04 LTS
- Setup Docker for Non-root User
- Install Docker Compose
- Configure Ghost Stack
- Create a Custom Network
- Create a Project Directory
- Create and Configure MySQL Container
- Create and Configure Traefik Reverse Proxy
- Create and Configure Ghost Container
- Deploy Ghost with MySQL and Traefik
- Testing
Step 1 – Install Docker CE on Ubuntu 18.04 LTS
Begin by installing the latest docker-ce version for your system, obtainable from the official Docker repository.
Firstly, add the Docker GPG key and the docker-ce repository:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
This command will automatically update all repositories on your system.
Now, install Docker using the command below:
sudo apt install docker-ce -y
After installation, start the Docker service and enable it to run at startup:
sudo systemctl start docker sudo systemctl enable docker
Docker CE has been successfully installed on your Ubuntu 18.04 system.
Step 2 – Setup Docker for Non-root User
To run container microservices under a non-root user, configure the user to run Docker containers and have root privileges via the sudo command.
Create a new user named ‘hakase’:
sudo useradd -m -s /bin/bash hakase sudo passwd hakase
Assign the ‘hakase’ user to the ‘sudo’ and ‘docker’ groups:
sudo usermod -aG sudo hakase sudo usermod -aG docker hakase
Restart the Docker service:
sudo systemctl restart docker
The ‘hakase’ user can now run Docker containers and execute sudo commands for root access.
Log in as user ‘hakase’ and run the Docker hello-world container:
su - hakase docker run -it hello-world
The result of the command is displayed below:
Step 3 – Install Docker Compose
We’ll install Docker Compose version 1.21 from its GitHub repository.
Download the Docker Compose binary to the ‘/usr/local/bin’ directory:
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
Make the ‘docker-compose’ file executable by adjusting file permissions:
sudo chmod +x /usr/local/bin/docker-compose
Verify the installation:
docker-compose version docker version
Docker Compose 1.21 with Docker CE 1.18 is now installed.
Step 4 – Configure Ghost Stack
In this step, we will set up Docker and create a docker-compose.yml file for the Ghost installation. We will establish a Docker custom network and construct a docker-compose file with three primary services: MySQL database, Traefik reverse proxy, and the Ghost blog.
Create a Custom Network
First, display existing Docker networks:
docker network ls
Create a new Docker network for the Traefik reverse proxy named ‘traefiknet’:
docker network create traefiknet
Verify the creation of the new network:
docker network ls
The ‘traefiknet’ network has been created successfully.
Create a Project Directory
Next, create a project directory named ‘ghost’ and a docker-compose.yml file:
Log in as the ‘hakase’ user:
su - hakase
Create a ‘ghost’ directory and navigate into it:
mkdir ghost cd ghost
Create the docker-compose.yml file:
touch docker-compose.yml
Create and Configure MySQL Service
The next task is setting up a MySQL container with the following specifications:
- Use the MySQL 5.7 docker image.
- Mount the MySQL data directory locally.
- Run MySQL service on a private network.
- Set up MySQL user credentials:
- Root password: mypassword
- Database: ‘ghostdb’, User: ‘ghost’, Password: ‘ghostdbpass’
- The container will be named ‘mysql’.
Within the ‘ghost’ directory, create a ‘data’ directory and edit the ‘docker-compose.yml’ file:
mkdir -p data vim docker-compose.yml
Add the following configuration:
services: mysql: image: mysql:5.7 restart: always volumes: - ./data:/var/lib/mysql labels: - "traefik.enable=false" networks: - internal environment: MYSQL_ROOT_PASSWORD: mypassword MYSQL_USER: ghost MYSQL_PASSWORD: ghostdbpass MYSQL_DATABASE: ghostdb container_name: mysql
Save and exit.
Create and Configure Traefik Reverse Proxy
Now, we’ll configure the Traefik reverse proxy container.
Before editing the ‘docker-compose.yml’, create a configuration file ‘traefik.toml’:
vim traefik.toml
Add the following configuration:
# Traefik Global Configuration debug = false checkNewVersion = true logLevel = "ERROR" # Define the EntryPoints for HTTP and HTTPS defaultEntryPoints = ["https", "http"] # Define the HTTP port 80 and HTTPS port 443 EntryPoint # Enable automatic redirection from HTTP to HTTPS [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] # Enable Traefik Dashboard on port 8080 with basic authentication # User 'hakase', password is embedded in the file [entryPoints.dash] address = ":8080" [entryPoints.dash.auth] [entryPoints.dash.auth.basic] users = [ "hakase:$apr1$hEgpZUN2$OYG3KwpzI3T1FqIg9LIbi." ] [api] entrypoint = "dash" dashboard = true # Enable retry for sending a request if there is a network error [retry] # Define Docker Backend Configuration [docker] endpoint = "unix:///var/run/docker.sock" domain = "hakase-labs.io" watch = true exposedbydefault = false # Let's Encrypt Registration # Define the Let's Encrypt ACME HTTP challenge [acme] email = "hakase@gmail.com" storage = "acme.json" entryPoint = "https" OnHostRule = true [acme.httpChallenge] entryPoint = "http"
Save and exit.
Next, create an ‘acme.json’ file to store Let’s Encrypt logs and set permissions to 600:
touch acme.json chmod 600 acme.json
Now, edit ‘docker-compose.yml’ to add the Traefik service configuration:
- Using the latest Traefik Docker image.
- Name the container ‘traefik’.
- Use the custom ‘traefiknet’ network, exposing HTTP and HTTPS ports.
- Mount the Docker sock file, ‘traefik.toml’, and ‘acme.json’.
- Define the Traefik dashboard URL and backend via Docker labels.
Edit the ‘docker-compose.yml’:
vim docker-compose.yml
Insert the Traefik service configuration:
traefik: image: traefik:latest command: --docker ports: - 80:80 - 443:443 labels: - "traefik.enable=true" - "traefik.backend=dashboard" - "traefik.frontend.rule=Host:traef.hakase-labs.io" - "traefik.port=8080" networks: - traefiknet volumes: - /var/run/docker.sock:/var/run/docker.sock - ./traefik.toml:/traefik.toml - ./acme.json:/acme.json container_name: traefik restart: always
Save and exit.
Create and Configure Ghost Service
Following the setup of the Traefik reverse proxy, we proceed to create the Ghost service configuration with the specifications outlined below:
- Use Ghost v1 on the Alpine Docker platform.
- Mount the Ghost content directory to a local ‘blog’ directory.
- Run Ghost on the default port using domain ‘gho.hakase-labs.io’ as configured via Docker labels.
- Join two Docker networks: ‘internal’ and ‘traefiknet’.
- Configure the MySQL database details provided in the MySQL container configuration.
- Ensure Ghost starts once the Traefik and MySQL containers are operational.
Create a ‘blog’ directory and edit the ‘docker-compose.yml’ file:
mkdir -p blog vim docker-compose.yml
Include the following configuration for Ghost:
ghost: image: ghost:1-alpine restart: always ports: - 2368 volumes: - ./blog:/var/lib/ghost/content labels: - "traefik.enabled=true" - "traefik.backend=ghost" - "traefik.frontend.rule=Host:gho.hakase-labs.io" - "traefik.docker.network=traefiknet" - "traefik.port=2368" networks: - internal - traefiknet environment: database__client: mysql database__connection__host: mysql database__connection__user: ghost database__connection__password: ghostdbpass database__connection__database: ghostdb container_name: ghost depends_on: - mysql - traefik networks: traefiknet: external: true internal: external: false
Save and exit.
Now, the directory structure and configuration files are set up as follows:
tree
Step 5 – Deploy Ghost with MySQL and Traefik
Use the command below to build and launch the entire Ghost stack service:
docker-compose up -d
Once complete, check all running services:
docker-compose ps
The expected output is shown below:
If errors arise, inspect the container logs using the following commands:
docker-compose logs mysql docker-compose logs traefik docker-compose logs ghost
The Ghost stack, along with MySQL and Traefik, is now operational.
Step 6 – Testing
Access the Traefik dashboard via its specified URL, for example, http://traef.hakase-labs.io/
Log in using the credentials defined in the ‘traefik.toml’ file.
The Traefik dashboard looks as follows:
To check the Ghost installation, use the Ghost URL in your browser’s address bar. For instance, http://gho.hakase-labs.io/
You should see the Ghost homepage:
Proceed to the admin page to set up and configure a new admin user. The admin URL is similar to: http://gho.hakase-labs.io/admin/
Click the button to create a new admin user:
Complete the user details with your name, email, and password, and click the green button again.
Skip the member invite step for later:
You should now access the Ghost Dashboard:
After creating a sample post, here is the result:
The Ghost blog installation, alongside MySQL and Traefik Reverse Proxy in a Docker environment, has been completed successfully.
References
FAQ
What is Ghost?
Ghost is an open-source platform for publishing and blogging, leveraging Node.js for high performance and ease of customization.
What is Traefik?
Traefik is a modern reverse proxy and load balancer that simplifies deploying microservices by integrating with existing infrastructure components.
Why use Docker for Ghost?
Docker allows you to isolate applications and their dependencies into containers, ensuring consistency across multiple environments and simplifying the deployment and scaling process.
Can I use a different database instead of MySQL?
Yes, while this guide uses MySQL, Ghost can also be configured with other databases such as SQLite and PostgreSQL with appropriate adjustments in configuration files.