Welcome to Ghost!

After fighting with nameservers, nginx config, and Ghost, I'm finally back up and running with a brand spankin' new Ghost-powered blog!

Since I'm bin-packing (and saving a buck or two), I wanted to figure out how to run multiple blogs off of a single Digital Ocean server. Digital Ocean has a handy guide to doing that, but there are a couple missing steps.

Getting Started

Digital Ocean makes it pretty easy to spin up a small instance with Ghost pre-installed. Once you have that set up, you can start working through the instructions on that link above, with some adjustments.

I'm using Ghost 0.11.4 on Ubuntu 16.04, so your mileage may vary. Anything marked "IMPORTANT" is where the "gotchas" lie.

  1. Stop your ghost and nginx services.
  2. Go to /etc/nginx to duplicate your configuration.
    • I did this a little more explicitly than they did, by first copying the default directory in sites-available, then going into sites-enabled and creating a new symlink.
    • Make sure to change the server_name to match the domain you want to serve, and change the proxy_pass setting to use a new port.
    • Also, on your secondary blog, make sure to remove the default_server and ipv6only=on directives from the server stanza.
  3. Restart nginx with service nginx start. You can confirm it's back up and running with ps -ef | grep nginx and/or get more information with service nginx status.
  4. Copy the Ghost directory into each /var/www/yoursite.com folder.
    • IMPORTANT - make sure to chown -R ghost:ghost /var/www/yoursite.com/ghost! This will prevent EACCESS errors later when starting up Ghost.
  5. Update the relevant ghost config.js files to reflect the correct production.url and server.port
    • IMPORTANT - you'll also need to update your database configuration. I dive into this further below, but you'll at least need to modify your database name to the correct one, and user and password config too if you've changed those. If you don't update this, your two blog instances will be writing to the same database and either trampling each other (in the case of site-wide configs like title), or appending to each other (in the case of blog entries).
  6. IMPORTANT - create a new database for your new blog
    • First, check your .digitalocean_password for your mysql password
    • Login and create a new database create database ghost_yourdomain;.
    • Create a new user and password: create user 'newusername'@'localhost' identified by 'new password';
    • Clone the privileges that the default ghost installation has:
      • use mysql;
      • Test the select statment: select host, 'ghost_yourdomain', 'newusername', select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Create_tmp_table_priv,Lock_tables_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Execute_priv,Event_priv,Trigger_priv from db where db = 'ghost' and user = 'ghost';
      • Re-run the above, preceded with insert into db
      • You can confirm the results by running select * from db and visually inspecting
      • Run flush privileges;
    • Copy the ghost schema into your new database. There are a couple possible ways to do it. I followed the method listed on a stackoverflow entry to mysqldump the database schema and pipe it into my new database.
  7. Change your upstart scripts.
    • IMPORTANT - the method as listed didn't work for me, and I tried modifying /etc/init.d configs, /etc/init configs, and finally what seemed to work was to add a systemd unit.
      • Go to /lib/systemd/system
      • Either copy the ghost.service file, or create a new one called ghost-yourdomain.service
      • Copy in the following:
    [Unit]
    Description=Ghost: Just a blogging platform
    After=network.target

    [Service]
    Type=simple
    WorkingDirectory=/var/www/yourdomain.com/ghost
    User=ghost
    Group=ghost
    ExecStart=/usr/bin/npm start --production
    ExecStop=/usr/bin/npm stop --production
    Restart=always
    SyslogIdentifier=Ghost

    [Install]
    WantedBy=multi-user.target

Finally, restart your ghost service with service ghost-yourdomain start and check its status with service ghost-yourdomain status.

If all goes well, and you've properly configured your domain's nameservers to point to Digital Ocean, you should have a functioning secondary Ghost blog serving from a single droplet!