Self-Hosting a Ghost Blog on Ubuntu 18.04

I've used a lot of blogging platforms over the past few years: WordPress, Jekyll, Medium, even Weebly, once upon a time. But none have been quite as nice as Ghost, a modern, open-source platform that just looks, in my opinion, beautiful. Not to mention the editor is straight simple Markdown, no nonsense.

I'm not really sure what I'm going to post on this new blog of mine, but here's how I set it up!


  • A server. If you're looking for hosting, I love DigitalOcean and I always recommend them to new and old server administrators alike. But of course, there's a ton of hosting providers out there: Azure, OVH, and Linode, to name a few.
  • A domain name. My current favorite registrar is Google Domains. I really like uncluttered designs. A domain is a must-have if you really want to control your own internet content, and from a professional perspective, it really puts you above blogs still using subdomains and the like. Before we begin, you should point your domain to your hosting server.
  • Remote Access Tools. If you use Linux or macOS, like me, ssh is already preinstalled on your system. Windows users might want to consider a program like Bitvise or PuTTY for SSH access.

Creating A New User

Login to your server as root:

ssh [email protected]

Now, the rest of this setup can't be run as root, so we'll need to create a new user for us to use. Do not name this user ghost, as that will interfere with the ghost-cli software we install later.

adduser <username>

Enter a password for your new user, and confirm it. Then, you can just press ENTER six times to confirm the rest of the default values. Now, add that new user to the sudo group so it can perform administrative tasks:

usermod -aG sudo <username>

Then, switch to your new user:

su - <username>

Installing MySQL, Nginx, and Node.js

Before we can get Ghost running, we'll need to install some other software it requires.

First, update your server package lists and make sure everything already installed is up-to-date:

sudo apt-get update
sudo apt-get upgrade

Then, installing MySQL and Nginx is another simple command:

sudo apt install nginx mysql-server

On Ubuntu 18.04, MySQL no longer uses passwords for the root user. While this is actually slightly more secure than before, the new method is incompatible with the ghost-cli tool we will be installing later, so we're going to add a root password now. Login to MySQL:

sudo mysql

In the MySQL prompt, add a password with the following query:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '<YOUR PASSWORD HERE>';

Replacing, of course, <YOUR PASSWORD HERE> with your own password. As an aside, if you don't already use a password manager, now is a great time to start!

Then, quit MySQL:


Now, we're going to install Node.js. Ghost currently recommends Node 8.x LTS, so we'll install that:

curl -sL | sudo -E bash
sudo apt-get install -y nodejs

Installing Ghost-CLI

Now we can install ghost-cli, a commandline tool that helps setup new Ghost installs. This is a super easy install, just run:

sudo npm install [email protected] -g

Installing Ghost

We're going to install Ghost in the /var/www directory, since that's traditionally where websites are stored on Ubuntu systems. We'll make a dedicated ghost/ directory for that now:

sudo mkdir -p /var/www/ghost

Now, we need to change the owner of that directory to your user we created earlier:

sudo chown <user>:<user> /var/www/ghost
sudo chmod 775 /var/www/ghost

Then, navigate to that directory:

cd /var/www/ghost

Installing Ghost

The developers at Ghost have really made it easy to create new blogs since their initial release. Nowadays, a simple command sets up almost the entire thing:

ghost install

The install process will promot you for some information it needs to configure your site. In order:

  • Blog URL: Enter Since we specified https://, Ghost will setup TLS (SSL) for us automatically, with Let's Encrypt. Pretty neat!
  • MySQL Hostname: Just press enter, since localhost is the default value here.
  • MySQL Username: root
  • MySQL Password: The root password we entered earlier.
  • Ghost Database Name: You can just press enter, and the default value will be created for you. In some cases, maybe a second Ghost blog on the same server, you might want to change this to a custom value, which works just as well.
  • Set up "ghost" mysql user? Y for yes, this is the most secure setup.
  • Set up Nginx? Again, Y. This will configure the Nginx webserver for your blog.
  • Set up SSL? Y, as long as your domain is already pointed to your server! This will configure a TLS certificate with Let's Encrypt, as mentioned earlier. If it fails or if you just want to do this later, you can also repeat this step by running ghost setup ssl at any time after.
  • Email: Let's Encrypt needs this information to create your certificate, and they'll also send notifications there if there's an issue with your certificate or renewals in the future.
  • Set up systemd? Y, this will start or restart your Ghost blog if your server is rebooted, etc.

And finally, when it asks if you want to start Ghost, enter Y, and that's it! You can now nagivate to your domain in any web browser and start blogging! Visit the /ghost/ subfolder quick now, to complete the setup.

I hope you found this guide helpful! If you see anything I missed, or if there's some more information you'd find helpful, please reach out and let me know. Happy blogging!

Show Comments

Get the latest posts delivered right to your inbox.