| Work | Research and Development (R&D) | Engineering | Infrastructure | How to deploy Ghost blog into a Rails app subdirectory using Digital Ocean
How to deploy Ghost blog into a Rails app subdirectory using Digital Ocean

Overview

This guide is a continuation of How to deploy a Rails app using Digital Ocean. In this guide, we'll walk through how to deploy Ghost blog on a separate Digital Ocean Droplet with all requests proxied through a subdirectory on your Rails application.

The end result is to have this setup:
* Rails app: https://myapp.com
* Ghost blog: https://myapp.com/blog/
* Ghost blog: https://myapp.com/blog/my-article

One Click Deploy Ghost

Go to DigitalOcean's Marketplace and Create a Ghost Droplet.

Setup Your Droplet

Open your local terminal and SSH into the droplet

ssh root@ipaddress

The first time you SSH in, press enter and ghost will be automatically setup. You will be prompted for your blog URL and optionally for your email address.

After the setup is complete, your blog will be accessible at http://ipaddress.

Point Ghost to Subdirectory

Modify your ghost config to serve your ghost blog from /blog. Open your config file:

sudo nano /var/www/ghost/config.production.json

Replace your config file with the following. Make sure to replace myapp your domain name. Also, continue to use http instead of https - the SSL/https will be handled by the rails app.

{
  "url": "http://myapp.com/blog/",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "localhost",
      "user": "ghost",
      "password": "eb0eb67893804e4aa04cf7663bb59bb9aed5a60708fddf3d",
      "database": "ghost_production"
    }
  },
  "mail": {
    "transport": "Direct"
  },
  "logging": {
    "transports": [
      "file",
      "stdout"
    ]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/www/ghost/content"
  },
  "bootstrap-socket": {
    "port": 8000,
    "host": "localhost"
  }
}

Restart ghost by first switching to ghost user and running:

sudo -i -u ghost-mgr
cd /var/www/ghost/
ghost restart

Confirm that ghost is running:

ghost ls

If you need more ghost help, run:

ghost help

Point Nginx to Subdirectory

Modify your nginx web server to serve your ghost blog from /blog. Open your conf file:

sudo nano /etc/nginx/sites-enabled/ipaddress.conf

Replace your nginx conf file with the following:

server {
    listen 80;
    listen [::]:80;

    server_name 68.183.205.5;
    root /var/www/ghost/system/nginx-root; # Used for acme.sh SSL verification (https://acme.sh)

    location ^~ /blog {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;

    }

    location ~ /.well-known {
        allow all;
    }

    client_max_body_size 50m;
}

Restart nginx and verify it is running by checking the status:

sudo service nginx restart
sudo service nginx status

Verify nginx is working by visiting http://ipaddress/blog. Incase you run into any errors, check the logs by running:

tail -f /var/log/nginx/error.log
tail -f /var/log/nginx/access.log

Reverse Proxy Rails Requests

We'll be using rails to proxy all our requests to ghost blog through the /blog/ subdirectory.

First, install rack-reverse-proxy gem by adding it to your Gemfile

gem 'rack-reverse-proxy', '~> 0.11.0', :require => "rack/reverse_proxy"

Install the gem

bundle install

Next, update config.ru to rewrite requests matching the regex /^\/blog(\/.*)$/ to http://ipaddress/blog/$1. Your config file should look similar to this:

require_relative 'config/environment'

require 'rack/reverse_proxy'

use Rack::ReverseProxy do  
  reverse_proxy(/^\/blog(\/.*)$/,
    'http://ipaddress/blog/$1',
    opts = {:preserve_host => true})
end  

run Rails.application

Next, add a redirect for /blog (without trailing slash) to /blog/ (with trailing slash) to your config/routes.rb. The reason for adding this is rails does not use trailing slashes in URLs where as ghost blog does use trailing slashes.

  get "/blog", to: redirect('https://myapp.com/blog/', status: 301)

Commit, push, and deploy your changes.

git add .
git commit -m 'Add rack reverse proxy'
git push
cap production deploy

Visit https://myapp.com/blog/ and you should see your ghost blog. Click on the different articles and ensure linking has the correct domain and subdirectory such as https://myapp.com/blog/welcome also have the correct domain and subdirectory.

Setup Ghost

Visit https://myapp.com/blog/ghost/ and setup your ghost blog and admin user. Choose a cool theme and start publishing content!

Redirect DNS

If using namecheap:

@ ip_address A Record 1 min
www ip_address A Record 1 min