TL; DR
- Get a server with Ubuntu up and running
- Set up a non-root user and add it to superuser group
- Install MySQL and Node.js
- Install Ghost-CLI and start
- Install Caddy as a service and write a simple Caddyfile
- Get everything up and running!
Foreword (Feel-Free-to-Ignore-My-Nonsense™️)
This article is about how I built this blog with Ghost, an open-source blog platform based on Node.js. I used to use WordPress and static website generators like Hexo and Jekyll for my blog. But they turned out either too heavy or too light. Ghost seems like a perfect balance between them. It's open source; it's elegant out-of-the-box. Zero configuration is required; yet it's configurable from top to bottom.
The Ghost project is actually very well-documented – it has a decent official installation guide on Ubuntu with Nginx. But as you can see from the title of this article, I am going to ship it together with my favorite web server – Caddy! It's a lightweight, easy to configure yet powerful web server. To someone like me, who hate to write or read either Nginx conf
files or Apache .htaccess
files, Caddy is like an oasis in the desert of tedious web server configurations.
The web technologies are changing rapidly, especially for open source projects like Ghost and Caddy. From my observation, I would say neither Ghost nor Caddy are going to be backward compatible, which means the newer version of the software may not work as expected in older environment. So I recommend that you should always check if this tutorial is outdated or deprecated before moving on. You can go to their official website by clicking their names in the next section. Also, if you are running the application in production, use a fixed version, preferably with LTS (Long-term support).
Environments and Softwares
- Ubuntu 18.04.3 LTS
- Node.js v10.17.0 LTS (This is the highest version Ghost support as of Dec. 2019)
- Caddy 1 (NOT Caddy 2, which is still in beta as of Dec. 2019)
- MySQL 5.7 (It's gonna consume A LOT of memory! Use a lower version if you're running on a server with <1GB RAM.
Let get started! 👨💻👩💻
Step 1: Get a server
Get a server with Ubuntu up and running! Almost every cloud hosting company will provide Ubuntu 18.04 LTS image as of now.
Step 2: Set up a non-root superuser
# connect with root credentials to the server
ssh root@<server_ip> -p <ssh_port> # Default port: 22
# create a new user
adduser <username>
# add that user to superuser group
usermod -aG sudo <username>
# login as the new user
su <username>
Step 3: Install MySQL and set up
sudo apt update
sudo apt upgrade
# install MySQL
sudo apt install mysql-server
# Set up MySQL password, it's required on Ubuntu 18.04!
sudo mysql
# Replace 'password' with your password, but keep the quote marks!
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
# Then exit MySQL
quit
Step 4: Install Node.js
Method 1: Use apt / apt-get
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash
sudo apt-get install -y nodejs
Method 2: Use nvm (Node Version Manager)
to facilitate switching between Node.js versions
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.1/install.sh | bash
The script clones the nvm repository to ~/.nvm
, and adds the source lines from the snippet below to your profile (~/.bash_profile
, ~/.zshrc
, ~/.profile
, or ~/.bashrc
):
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Install Node.js v10.17.0
# source profile
source ~/.bash_profile # change to your profile
# check if nvm is properly installed
command -v nvm # output will be `nvm` if it is
nvm install v10.17.0
Step 4: Install Ghost-CLI
Method 1: Use npm
sudo npm install ghost-cli@latest -g
Method 2: Use yarn
# install yarn if you don't have it
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
sudo yarn global add ghost-cli@latest
Step 5: Get Ghost up and running
sudo mkdir -p /var/www/ghost
sudo chown <username>:<username> /var/www/ghost
sudo chmod 775 /var/www/ghost
cd /var/www/ghost
ghost install
Install questions
During install, the CLI will ask a number of questions to configure your site. They will probably throw an error or two about you don't have Nginx installed. Just ignore that.
Blog URL
Enter the exact URL your publication will be available at and include the protocol for HTTP or HTTPS. For example, https://example.com
.
MySQL hostname
This determines where your MySQL database can be accessed from. When MySQL is installed on the same server, use localhost
(press Enter to use the default value). If MySQL is installed on another server, enter the name manually.
MySQL username / password
If you already have an existing MySQL database enter the the username. Otherwise, enter root
. Then supply the password for your user.
Ghost database name
Enter the name of your database. It will be automatically set up for you, unless you're using a non-root MySQL user/pass. In that case the database must already exist and have the correct permissions.
Set up a ghost MySQL user? (Recommended)
If you provided your root MySQL user, Ghost-CLI can create a custom MySQL user that can only access/edit your new Ghost database and nothing else.
Set up systemd? (Recommended)
systemd
is the recommended process manager tool to keep Ghost running smoothly. We recommend choosing yes
but it’s possible to set up your own process management.
Start Ghost?
Choosing yes
runs Ghost on default port 2368
.
Step 6: Get Caddy up and running
Caddy has an awesome collection of plugins. You can go to Download Caddy page. First, select the correct platform; then add a bunch of plugins that you're interested. After that, don't click Download
. Copy the link in the Direct link to download
section. Head back to ssh in terminal.
mkdir -p ~/Downloads
cd ~/Downloads
# download caddy binary, the link may differ if you added plugins
curl https://caddyserver.com/download/linux/amd64?license=personal&telemetry=off --output caddy
sudo cp ./caddy /usr/local/bin
sudo chown root:root /usr/local/bin/caddy
sudo chmod 755 /usr/local/bin/caddy
sudo setcap 'cap_net_bind_service=+ep' /usr/local/bin/caddy
sudo mkdir /etc/caddy
sudo chown -R root:root /etc/caddy
sudo mkdir /etc/ssl/caddy
sudo chown -R root:<username> /etc/ssl/caddy
sudo chmod 770 /etc/ssl/caddy
Run Caddy as a service
wget https://raw.githubusercontent.com/caddyserver/caddy/master/dist/init/linux-systemd/caddy.service
sudo cp caddy.service /etc/systemd/system/
sudo chown root:root /etc/systemd/system/caddy.service
sudo chmod 644 /etc/systemd/system/caddy.service
sudo systemctl daemon-reload
sudo systemctl start caddy.service
sudo systemctl enable caddy.service
Create Caddyfile
sudo touch /etc/caddy/Caddyfile
sudo chown root:root /etc/caddy/Caddyfile
sudo chmod 644 /etc/caddy/Caddyfile
sudo vi /etc/caddy/Caddyfile # edit Caddyfile with your preferred editor, here I use vi
We're gonna set up a simple reverse proxy to Ghost's port (2368). Here are 2 sample Caddyfile
s respectively for Auto SSL enabled and disabled.
# auto ssl
example.com, www.example.com {
proxy / 127.0.0.1:2368
tls admin@example.com
}
# no auto ssl
http://example.com, http://www.example.com {
proxy / 127.0.0.1:2368
}
If you want Auto SSL issued by Let's Encrypt, you should put your email after the tls
directive on the 3rd line; otherwise, use the second part of this Caddyfile
. (For me, I was using Cloudflare flexible Auto SSL mode, so I just built a reverse proxy based on HTTP protocol only here)
Fire it up 🔥
sudo systemctl start caddy.service
Top comments (0)