Ghost is a modern, open-source blogging platform designed to create sleek, professional websites. Introduced in 2013 as a streamlined alternative to the increasingly complex WordPress, Ghost leverages JavaScript and Node.js for its operations.
This step-by-step guide illustrates the installation of Ghost CMS using Docker on an Ubuntu 20.04 server. Additionally, we’ll employ Nginx as a reverse proxy and secure the setup with a Let’s Encrypt SSL certificate.
Prerequisites
- Ubuntu 20.04 server instance.
- A non-root user with sudo privileges.
- Ensure your system is up to date:
$ sudo apt update $ sudo apt upgrade
Step 1 – Configure UFW Firewall
Ensure that your firewall is protecting your server by utilizing Ubuntu’s Uncomplicated Firewall (UFW).
First, verify the firewall status:
$ sudo ufw status
If it reads “inactive,” allow SSH connections to maintain connectivity:
$ sudo ufw allow OpenSSH
Permit traffic on HTTP and HTTPS ports:
$ sudo ufw allow 80
$ sudo ufw allow 443
Activate the firewall:
$ sudo ufw enable
Verify it’s active:
$ sudo ufw status
Step 2 – Install Certbot and Obtain the SSL Certificate
Using Certbot, we can automate the configuration of free SSL certificates from Let’s Encrypt. Update snap:
$ sudo snap install core
$ sudo snap refresh core
Remove any older installations of Certbot:
$ sudo apt remove certbot
Then, install Certbot using Snap:
$ sudo snap install --classic certbot
Create a symbolic link for Certbot:
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Generate your SSL certificate:
$ sudo certbot certonly --standalone -d example.com
Step 3 – Install Docker and Docker Compose
Uninstall outdated Docker versions if present:
$ sudo apt remove docker docker-engine docker.io containerd runc
Install required packages:
$ sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release
Set up Docker’s GPG key and repository:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Now, proceed to install Docker:
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io
Verify Docker installation:
$ sudo docker run hello-world
Allow non-root users to run Docker commands:
$ sudo usermod -aG docker ${USER}
Install Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/download/1.28.6/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
Verify Docker Compose installation:
$ docker-compose --version
Step 4 – Install Ghost
The Ghost setup consists of three components: Ghost itself, a database like MySQL, and Nginx. These will be orchestrated through Docker Compose.
Create Docker Compose File
In your home directory, create a new directory for Ghost:
$ mkdir ghost && cd ghost
Create and edit a docker-compose.yml
file:
$ nano docker-compose.yml
Populate it with this content, substituting placeholders accordingly:
version: '3.3'
services:
ghost:
image: ghost:latest
restart: always
depends_on:
- db
environment:
url: https://example.com
database__client: mysql
database__connection__host: db
database__connection__user: ghost
database__connection__password: ghostdbpass
database__connection__database: ghostdb
volumes:
- /home/<username>/ghost/content:/var/lib/ghost/content
db:
image: mariadb:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_mysql_root_password
MYSQL_USER: ghost
MYSQL_PASSWORD: ghostdbpass
MYSQL_DATABASE: ghostdb
volumes:
- /home/<username>/ghost/mysql:/var/lib/mysql
nginx:
build:
context: ./nginx
dockerfile: Dockerfile
restart: always
depends_on:
- ghost
ports:
- "80:80"
- "443:443"
volumes:
- /etc/letsencrypt/:/etc/letsencrypt/
- /usr/share/nginx/html:/usr/share/nginx/html
Create necessary directories for bind mounts:
$ cd ~/ghost
$ mkdir content mysql
$ sudo mkdir -p /usr/share/nginx/html
Create the Nginx Docker Image
Create a directory for Nginx:
$ mkdir nginx
Create a Dockerfile and ghost.conf
for configuring Nginx:
$ touch nginx/Dockerfile
$ touch nginx/ghost.conf
Edit the Dockerfile:
FROM nginx:latest
RUN rm /etc/nginx/conf.d/default.conf
COPY ghost.conf /etc/nginx/conf.d
Edit the ghost.conf, replacing example.com:
server {
listen 80;
listen [::]:80;
server_name example.com;
location /.well-known/acme-challenge/ { root /usr/share/nginx/html; allow all; }
location / { return 301 https://$server_name$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
access_log /var/log/nginx/ghost.access.log;
error_log /var/log/nginx/ghost.error.log;
client_max_body_size 20m;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ghost:2368;
}
}
Step 5 – Run the Site
From the ghost
directory, initiate the Ghost service:
$ docker-compose up -d
Check your blog by visiting https://example.com
. If it doesn’t appear immediately, monitor the logs:
$ docker-compose down
$ docker-compose up
Step 6 – Complete Setup
Finalize your Ghost blog by accessing https://example.com/ghost
, where you’ll configure your admin account.
Step 7 – Update Ghost
Keeps your Ghost installation current by continuing to update your Docker images:
$ docker-compose down
$ docker-compose pull && docker-compose up -d
Step 8 – Renew your Let’s Encrypt SSL Certificate
Automate certificate renewal with a cron job:
$ sudo crontab -e
Add this:
0 23 * * * certbot certonly -n --webroot -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'
Test using dry-run:
$ sudo bash -c "certbot certonly -n --webroot --dry-run -w /usr/share/nginx/html -d example.com --deploy-hook='docker exec ghost_nginx_1 nginx -s reload'"
Conclusion
Congratulations on setting up Ghost CMS on your Ubuntu server using Docker. For questions or feedback, leave a comment below.
FAQ
What is Ghost CMS?
Ghost CMS is an open-source platform used for building and managing blogs and online publications. It is known for its speed and simplicity.
Why use Docker for installing Ghost?
Using Docker provides a consistent environment for running applications, simplifies the deployment process, and allows easy scalability.
How frequently should I update Ghost CMS?
Regular updates are recommended to keep your platform secure and take advantage of the latest features.
What if I encounter issues with the Ghost setup?
Check Docker logs for errors using docker-compose up
and refer to Ghost’s documentation and forums for troubleshooting tips.