Introduction
Ghost is a beautifully designed platform dedicated to publishing. it’s an Open Source application which giving you the tools to write and publish your own blog easier. It’s simple, elegant, and designed so that you can spend more time blogging. in other words, Ghost is a very good alternative to WordPress as it’s developed by some of the former developers of the WordPress itself. Ghost is based on modern technology stack using Node.JS to be as fast as possible, with a real quick look at the numbers you can see that Ghost is over 19X faster than WordPress.
In this tutorial, we are going to install Ghost on CentOS 7 with the Nginx as our web server to get the highest possible performance.
We are assuming that you have root permission, otherwise, you may start commands with “sudo”.
Requirments
- EPEL repository
- Node.JS with NPM
- Nginx
Install Prerequisites
For installing the prerequisites you have to install EPEL repository first:
yum update
yum install epel-release
Install Node.JS and NPM
Install Node.JS with NPM included from EPEL repository with the command below:
yum install nodejs
For checking your Node.JS and NPM version:
node --version
npm --version
Install Nginx
You can install the latest stable version of Nginx from EPEL as well:
yum install nginx
Enable and start the Nginx service with the following commands:
systemctl enable nginx
systemctl start nginx
Install Unzip
We are going to need the Unzip to extract the Ghost that we are going to download:
yum install unzip
Install Ghost
Using “Wget” we can download the latest version of Ghost and we will place it in the “/var/www” which is the recommended location:
wget https://ghost.org/zip/ghost-latest.zip
Next, we have to create the “www” directory in “/var”:
mkdir /var/www
Now, we can unzip the Ghost in the preferred path:
unzip -d /var/www ghost-latest.zip
Switch to the “/var/www”:
cd /var/www
Then install the Ghost dependencies:
npm install --production
Ghost is installed once this process completes, but we need to set up the Ghost before we can start it.
Configuring Ghost
First of all, we have to rename the “config.example.js” to “config.js” with the command below:
cp config.example.js config.js
Open the config file for editing
nano config.js
Find the following section and replace your domain or your public IP address with the red area:
...
config = {
// ### Production
// When running Ghost in the wild, use the production environment
// Configure your URL and mail settings here
production: {
url: 'http://your_domain_or_ip_address',
mail: {},
...
Note that, either if you are going to set an IP address or your domain name as a value for “url” section, it has to start with the “http://” for example: “http://example.com” or “http://192.168.1.1”
While we are still in the “www” directory we can start Ghost with the following command:
npm start --production
If you have done everything right the end of your output should be like below:
Ghost is running in production...
Your blog is now available on http://your_domain_or_ip_address
Ctrl+C to shut down
Ghost is running on port 2368, and it’s not listening on the public network interface. Let’s set up Nginx in front of Ghost.
If you don’t see any problem, you can break the process using Ctrl + C. We are going to configure a systemctl service for Ghost and let it run in the background.
Running Ghost with a separate user
We are going to create a user account for Ghost and it will only have access to “/var/www” so if somehow Ghost gets compromised, you could minimize the damage.
Create a new user called “ghost” with the command below:
adduser --shell /bin/bash ghost
Then make “ghost” user as the owner of the “/var/www”;
chown -R ghost:ghost /var/www
Configuring Nginx
It’s time to set up Nginx to proxy your blog with your domain name. Running Ghost with root level permissions on port 80 could be a security flaw so we recommend you to always set up Ghost with a web server:
Switch to the “/etc/nginx” first:
cd /etc/nginx
If you have installed Nginx from EPEL repository, you will not have the “sites-available” and “sites-enabled” directories. Let’s create them:
mkdir sites-available
mkdir sites-enabled
Next, create a new file in “sites-available” called “ghost”:
nano /etc/nginx/sites-available/ghost
The following configuration is telling Nginx that pass every request on “server_name:80” to “127.0.0.1:2368” which is the Ghost service.
Place the following configuration in the file and make sure to replace the red area with your domain name or your public IP address:
server {
listen 80;
server_name your_domain_or_ip_address;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:2368;
}
}
Save and exit.
Now create a symlink from this file to your “sites-enabled” directory with the command below:
ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost
Nginx will not use this new configuration until we modify the default Nginx configuration and tell it to include the configuration file in the “sites-enabled” directory.
Open the “nginx.conf” with your text editor:
nano nginx.conf
Find the “http” directive and add the following line in it:
include /etc/nginx/sites-enabled/*;
Then completely comment out the “server” directive block found inside the “http” directive. you should have something like below:
# server {
# listen 80 default_server;
# listen [::]:80 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
Save and exit.
Test the Nginx configuration and see if everything is OK:
nginx -t
If you have done everything right your output should say:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Now restart Nginx to run the new configurations:
systemctl restart nginx
Make the Ghost to run as a service
In this section, we are going to make Ghost to run as a background process so we can make sure that our blog is running trough reboots and log offs, for that matter, we have to create a “systemd” unit file that can specify for system how to handle Ghost as a service:
Create a new file to hold the definition of the systemd unit file:
nano /etc/systemd/system/ghost.service
Add the following configuration to the file to define the service’s name and information on how it should start as a background process:
[Unit]
Description=Ghost
After=network.target
[Service]
Type=simple
WorkingDirectory=/var/www
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
Save and exit the editor.
Now, you can enable and start your Ghost as a service:
systemctl enable ghost
systemctl start ghost
You can visit your Ghost using your Domain name or your public IP address. and you should see something like the picture below:
Set up your Blog
For getting access to your Ghost’s control panel you have to use the following address:
http://your_domain_IP_address/admin
Then you will see a page like below:
Enter your data and choose a title for your blog and proceed to your control panel which should be like below:
Check out Ghost official website for more information and news!
Thanks for the useful post. I installed Ghost as a node module, but couldn’t get it running as a service under systemd–not sure why (I tried a couple of other variations on the configuration, but systemd seems very picky). I eventually settled on the Node.js module ‘forever’, which worked.
Hello,
Could you tell me if It will work on latest version of Ghost?
thanks