Skip to content

Instantly share code, notes, and snippets.

@fire
Last active August 29, 2015 13:59
Show Gist options
  • Save fire/10691747 to your computer and use it in GitHub Desktop.
Save fire/10691747 to your computer and use it in GitHub Desktop.
Install Ghost

#Install Ghost on smartos

*Guide is out of date for Ghost 0.5 *

Sources

Guide

ssh root@<IP-ADDRESS> ## Use your server 'IP-ADDRESS'
pkgin install gmake unzip nano build-essential clang sqlite

Create ghost user and group.

groupadd ghost
useradd \
-s /bin/false \
-c 'ghost blog' \
-g ghost \
-d /home/ghost -m ghost
sudo -u ghost /bin/bash
git clone https://github.com/tryghost/Ghost  tmp && mv tmp/.git . && rm -rf tmp && git reset --hard
git submodule update --init  
git checkout stable

# Now we need to configure Ghost to use PostgreSQL instead of SQLite3. 
# First we need to edit package.json to include a new dependency:
nano package.json
# in the dependencies section add:
# "pg": "latest",

CC="gcc -std=gnu99" npm install
npm install -g grunt-cli
echo PATH=$PATH:~/node_modules/.bin > ~/.profile
source ~/.profile
grunt init
grunt prod
cp config.example.js config.js
chmod 600 config.js
nano config.js ## Edit host: to 'localhost'; Edit port: to '2368'
npm start --production

In your config.js find the database section and replace it with the following replacing host, user, password, and database with the information from the Heroku website:

database: {
    client: 'postgres',
    connection: {
          host: 'database address',
          user: 'username',
          password: 'password',
          database: 'databasename',
          port: '5432'
    }

Create a manifest.

nano node-ghost-manifest.xml

Enable it.

svccfg import node-ghost-manifest.xml
svcadm enable node-ghost

Test if it works.

tail -f -n 50 "/var/svc/log/site-node-ghost-service:default.log"

Install nginx:

pkgin in nginx -y

Copy the nginx config:

mkdir -p /opt/local/etc/nginx/sites-available
mkdir -p /opt/local/etc/nginx/sites-enabled
cp srvconf/nginx-site-api.conf /opt/local/etc/nginx/sites-enabled
Edit nginx.conf and add the include line after http {

nano /opt/local/etc/nginx/nginx.conf
#add this line after http {
include /opt/local/etc/nginx/sites-enabled/*.conf;

Enable nginx:

svcadm enable nginx
# Note: view logs with tail -f -n 50 /var/svc/log/pkgsrc-nginx\:default.log
# to read the errors

Put at /opt/local/etc/nginx/sites-available/ and then go to that directory and ln -s <name of website> ../sites-enabled/

server {
  listen   80; ## listen for ipv4; this line is default and implied
  #listen   [::]:80 default ipv6only=on; ## listen for ipv6

  root /home/ghost/public;
  index index.html index.htm;

  # Make site accessible from http://example.com/
  server_name example.com;

  location / {
      proxy_pass http://localhost:2368;
      proxy_buffering off;
      proxy_connect_timeout 66;
      proxy_read_timeout 66;
      proxy_send_timeout 66;
      proxy_hide_header X-Powered-By;
      proxy_hide_header X-Response-Time;
      proxy_set_header Host $host;
  }
}

Alternative Ssl setup

Generate a ssl key

cd /opt/local/etc/nginx
mkdir keys
cd keys 
openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr
# Get your key signed by a certificate authority and bundle the crts together
# Example for a namecheap ssl certificate
# cat example_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > server.crt
# The following is how to sign the key by yourself.
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# You may wish to get the key signed by a certificate authority.
chmod 600 *

Replace nginx.conf with:

server {
  listen 80;

  root /home/ghost/public;
  index index.html index.html;

  server_name example.com;

  location / {
        return 301 https://$server_name$request_uri;
  }
}

server {
  listen   443; ## listen for ipv4; this line is default and implied
  #listen   [::]:443 default ipv6only=on; ## listen for ipv6

  root /home/ghost/public;
  index index.html index.htm;

  ssl on;
  ssl_certificate /opt/local/etc/nginx/keys/server.crt;
  ssl_certificate_key /opt/local/etc/nginx/keys/server.key;

  # Make site accessible from https://example.com/
  server_name example.com;

  location / {
      proxy_pass http://localhost:2368;
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_buffering off;
      proxy_connect_timeout 66;
      proxy_read_timeout 66;
      proxy_send_timeout 66;
      proxy_hide_header X-Powered-By;
      proxy_hide_header X-Response-Time;
      proxy_set_header Host $host;
  }
  
  location = /robots.txt { access_log off; log_not_found off; }
  location = /favicon.ico { access_log off; log_not_found off; }
}
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type="manifest" name="node-ghost">
<service name="site/node-ghost" type="service" version="1">
<create_default_instance enabled="true"/>
<single_instance/>
<dependency name="network" grouping="require_all" restart_on="refresh" type="service">
<service_fmri value="svc:/milestone/network:default"/>
</dependency>
<dependency name="filesystem" grouping="require_all" restart_on="refresh" type="service">
<service_fmri value="svc:/system/filesystem/local"/>
</dependency>
<dependency name="nginx" grouping="require_all" restart_on="refresh"
type="service">
<service_fmri value="svc:/pkgsrc/nginx:default"/>
</dependency>
<dependency name="postgresql" grouping="require_all"
restart_on="refresh" type="service">
<service_fmri value="svc:/pkgsrc/postgresql:default"/>
</dependency>
<method_context working_directory="/home/ghost/">
<method_credential user="ghost" group="ghost" privileges='basic,net_privaddr' />
<method_environment>
<envvar name="PATH" value="/home/ghost/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin"/>
<envvar name="HOME" value="/home/ghost"/>
<envvar name="NODE_ENV" value="production"/>
</method_environment>
</method_context>
<exec_method
type="method"
name="start"
exec="/opt/local/bin/node /home/ghost/index.js"
timeout_seconds="60"/>
<exec_method
type="method"
name="stop"
exec=":kill"
timeout_seconds="60"/>
<property_group name="startd" type="framework">
<propval name="duration" type="astring" value="child"/>
<propval name="ignore_error" type="astring" value="core,signal"/>
</property_group>
<property_group name="application" type="application">
</property_group>
<stability value="Evolving"/>
<template>
<common_name>
<loctext xml:lang="C">node.js Ghost blog service</loctext>
</common_name>
</template>
</service>
</service_bundle>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment