Building a Ghost Blog Server
This post acts more like a checklist of steps to complete when setting up a new Ghost Blog from a base Ubuntu installation. It focuses on doing so on a droplet provided by Digital Ocean, but could be adapted to any other provider.
If you want to set up your own server with Digital Ocean and found this page useful, consider using this affiliated link for which I will receive credit to keep failedtofuncion.com up and running: Digital Ocean
When I set up this blog originally I used the One Click option provided by Digital Ocean. This is a good option as it gets you up and running quickly.
On the other hand it hides some of the initial setup, masking some of the details of what is going on under the hood. Why do I need to know about that? By choosing Digital Ocean, I am committing myself to managing the server completely: applying OS patches, application updates, managing space, etc. To do so effectively, it is good to know everything that is under the hood.
Occasionally it will be necessary to migrate the blog from an older to a newer server, perhaps for additional space or computing power, or more likely to move off an unsupported version. It is good to have knowledge of the parts involved before trying to do so. I feel strongly that if something necessary is difficult, you should try to do it as often as possible. This builds familiarity and allows you to practice and spot easier ways to do it.
One final reason is that I want to be able to spin up a test version of the site for trying out new themes or playing with some of the settings, possibly even developing my own theme. It seems like a good thing to be able to get a facsimile up and running quickly so this list will be invaluable to me in the future.
Resources
I used a number of sources in combination to build up this list of steps. I have not repeated all the details of why something is necessary, so if in doubt you can use these resources for additional information.
There are a few pages offered by Digital Ocean for the various versions of Ubuntu. When I created the server they emailed me a link to the 14.04 page even though I had set up 16.04 - go figure. Here’s both links anyway: 14.04, 16.04
The commands are merged somewhat with the instructions from the ghost installation documentation, available here: https://docs.ghost.org/docs/install
Creating and Securing a Server
Digital Ocean make this simple. Click on the create droplet button, select Ubuntu and the size and speed you want, ensure it’s on the nearest geographic location to you and click create. I’d recommend not adding SSH when creating the droplet, you can add it later. The best practice is to create a super user other than root to do administration work with. It looks like the key added at setup applies to the root user.
Once created, you should get an email with the connection details. Connect using ssh from terminal with:
ssh root@<ip address>
Create an administrator user for doing the rest of the installation:
adduser <user>
usermod -aG sudo <user>
Copy your SSH key to the server. First exit from SSH and then run the copy command. If you don’t already possess a public-private key pair, you can follow the instructions on this page.
exit
ssh-copy-id <user>@<ip address>
You should now be able to connect without entering the password. Note that you will need the password for doing all administration work that requires elevated privileges with the command sudo
.
Connect again, this time as the new user
ssh <user>@<ip address>
Remove the ability to login to the server as root by SSH by changing the line PermitRootLogin yes
after editing the following file:
sudo vi /etc/ssh/sshd_config
Then reload SSH:
service ssh restart
Open a new terminal and verify that you can still connect! If not undo the previous change.
Check that the firewall is set up - the following lists applications for which it is configured:
sudo ufw app list
Ensure the firewall allows ssh connections and then enable the firewall:
sudo ufw allow OpenSSH
sudo ufw enable
It makes sense do double check from a new terminal that you can still log on before going much further.
Another precaution is to disallow connections via ssh with password. That means that the user has to use a private key. Edit the following file:
sudo vi /etc/ssh/ssh_config
Change the line with PasswordAuthentication
so that it looks like this:
PasswordAuthentication no
And then reload the ssh daemon:
sudo systemctl reload sshd
Before disconnecting, test that you can connect with a new terminal window.
Ghost installation
Update and install Nginx:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install nginx
sudo ufw allow 'Nginx Full'
The next step will require a database root password to be set - do not skip this step:
sudo apt-get install mysql-server
Get the repository for and install Node.js
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash
sudo apt-get install -y nodejs
Install Ghost CLI and test it is working:
sudo npm i -g ghost-cli
ghost help
Install Ghost via the CLI (use the user created above):
sudo mkdir -p /var/www/ghost
sudo chown [user]:[user] /var/www/ghost
cd /var/www/ghost
ghost install
The installation prompts for a range of inputs with the default usually sufficing; the following have no default:
- The URL for the site
- MySQL user - root
- MySQL password - as entered above
Say “yes” to Nginx and, if the domain is setup, also say “yes” to creating a SSL.
Note that some of the settings above could be entered differently for a test site compared to a new production site. Also if something fails (for example, if the domain name is not yet pointing at the server IP then the SSL generation step will fail) then the installation will not complete. You can restart later with sudo ghost setup
once the problem has been fixed.
The last option is to start up ghost - this can be done with sudo ghost start
later if you are not ready to bring up the service yet.
Cloudflare
One of the options is to setup the SSL using Let's Encrypt. This will only work if the domain name for the website has been correctly routed to the new server. The steps involved (including using Cloudflare’s content delivery network) are:
- Register a domain name
- Add the domain to Cloudflare - there’s “Add Site” button at the top navigation bar.
- Set up the DNS - an A record pointing to the new IP address and a CNAME record redirecting www traffic to the A record at a minimum.
- Change the settings on the domain registration site to point to the Cloudflare name servers
- Wait - the above can take up to forty eight hours
- Verify the domain name no longer points to a parking web page
Secure the MySQL installation
Run the following and select yes at each prompt. It removes the ability to remotely login as the root user, protecting against a dictionary attack. It also removes test accounts and generally tightens up security.
sudo /usr/bin/mysql_secure_installation
Sign in to Ghost
It would be a good idea to sign into ghost now to verify it works and also as the first login creates the owner. Go to the website and you should see the default Ghost home pages; append /ghost
to the URL and it will prompt you to create an account and invite users.
Disable the Default Nginx Site
Nginx places a default site in /var/www/html
with a short welcome message. This will only be visible if you connect to the server with the IP address from a browser, but it's best to disable it.
sudo rm /etc/nginx/sites-enabled/default
sudo service nginx reload
Now connecting with the IP address should bring back the Ghost blog.
If at First You Don’t Succeed
If all else fails, simply delete the droplet and start again. Don’t leave it around incurring cost. Don’t waste too much time trying to fix something that went horribly wrong. Make sure to backup any posts first.