How To Install and Configure Ghost on CentOS 7

Published on April 10, 2017
How To Install and Configure Ghost on CentOS 7


Ghost is a light-weight open-source blogging platform which is easy to use. Ghost is fully customizable, with many themes available.

In this tutorial, you’ll set up Ghost on CentOS 7. You’ll also configure Nginx to proxy requests to Ghost, and keep Ghost running in the background as a system service.


To complete this tutorial, you will need:

Step 1 — Installing Ghost

First, we need to install Ghost. We’ll place Ghost in the /var/www/ghost directory, which is the recommended installation location.

Download the latest version of Ghost from Ghost’s GitHub repository using wget:

  1. wget https://ghost.org/zip/ghost-latest.zip

To unpack the archive, first install the unzip program with the package manager. It’s always a good idea to make sure that the system is up-to-date before installing a new program, so update the packages and install unzip with the following commands:

  1. sudo yum update -y
  2. sudo yum install unzip -y

The -y flag in the preceding commands updates and installs packages automatically without asking for a confirmation from the user.

Once unzip is installed, unzip the downloaded package to the /var/www/ghost directory. First, create the /var/www folder, then unzip the file:

  1. sudo mkdir /var/www
  2. sudo unzip -d /var/www/ghost ghost-latest.zip

Switch to the /var/www/ghost/ directory:

  1. cd /var/www/ghost/

Then install the Ghost dependencies, but only the ones needed for production. This skips any dependencies which are only needed by people who develop Ghost.

  1. sudo npm install --production

Ghost is installed once this process completes, but we need to set up Ghost before we can start it.

Step 2 — Configuring Ghost

Ghost uses a configuration file located at /var/www/ghost/config.js. This file doesn’t exist out of the box, but the Ghost installation includes the file config.example.js, which we’ll use as a starting point.

Copy the example configuration file to /var/www/ghost/config.js. We’ll copy the file instead of moving it so that we have a copy of the original configuration file in case we need to revert your changes.

  1. sudo cp config.example.js config.js

Open the file for editing:

  1. sudo vi config.js

We have to change the URL that Ghost uses. If we don’t, the links on the blog will take visitors to my-ghost-blog.com. Change the value of the url field to your domain name, or to your server’s IP address if you don’t want to use a domain right now.



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: {},

The url value must be in the form of a URL, like http://example.com or If this value is not formatted correctly, Ghost will not start.

Ghost can function without the mail settings; they’re only necessary if you need to support password recovery for Ghost users. We’ll skip configuring this setting in this tutorial.

You can customize Ghost further by following the configuration details at the official site.

Save the file and exit the editor.

While still in the /var/www/ghost directory, start Ghost with the following command:

  1. sudo npm start --production

The output should be similar to the following:

> ghost@0.11.7 start /var/www/ghost > node index WARNING: Ghost is attempting to use a direct method to send email. It is recommended that you explicitly configure an email service. Help and documentation can be found at http://support.ghost.org/mail. Migrations: Creating tables... ... Ghost is running in production... Your blog is now available on http://your_domain_or_ip_address Ctrl+C to shut down

Ghost is listening on port 2368, and it’s not listening on the public network interface, so you won’t be able to access it directly. Let’s set up Nginx in front of Ghost.

Step 3 — Configuring Nginx to Proxy Requests to Ghost

The next step is to set up Nginx to serve our Ghost blog. This will allow connections on port 80 to connect through to the port that Ghost is running on, so people can access your Ghost blog without adding the :2368 to the end of the address. It also adds a layer of indirection and sets you up to scale out your blog if it grows.

If Ghost is still running in your terminal, press CTRL+C to shut down the Ghost instance before you continue.

Now let’s configure Nginx. Change to the /etc/nginx directory first:

  1. cd /etc/nginx/

If you installed Nginx from the CentOS EPEL repository as shown in the prerequisite tutorial, you will not have the sites-available and sites-enabled directories, which are used to manage web site configurations. Let’s create them:

  1. sudo mkdir sites-available
  2. sudo mkdir sites-enabled

Next, create a new file in /etc/nginx/sites-available/ called ghost:

  1. sudo vi /etc/nginx/sites-available/ghost

Place the following configuration in the file and change your_domain_or_ip_address to your domain name, or your servers IP address if you don’t have a domain:

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;

This basic configuration sends all requests for this server to the Ghost blog running on port 2368, and it sets the appropriate HTTP headers so that when you look at your Ghost logs, you’ll see the original IP address of your visitors. You can learn more about this configuration in Understanding Nginx HTTP Proxying, Load Balancing, Buffering, and Caching.

Save the file, exit the editor, and enable this configuration by creating a symlink for this file in the /etc/nginx/sites-enabled directory:

  1. sudo ln -s /etc/nginx/sites-available/ghost /etc/nginx/sites-enabled/ghost

Nginx won’t use this new configuration until we modify the default Nginx configuration file and tell it to include the configuration files in the sites-enabled folder. In addition, we have to disable the default site. Open up the nginx.conf file in your editor:

  1. sudo vi nginx.conf

Include the following line inside the http block to include the configuration files in the sites-enabled folder:


http {
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

Then completely comment out the server block found inside the http block:


    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

#    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 the file and exit the editor. Test the configuration to ensure there are no issues:

  1. sudo nginx -t

You’ll see the following output if everything is correct:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful

If you see any errors, fix them and retest the configuration.

With a working configuration file, restart Nginx to apply the changes:

  1. sudo systemctl restart nginx

Before we start Ghost again, let’s create a new user account to run Ghost.

Step 4 – Running Ghost as a Separate User

To improve security, we’ll run Ghost under a separate user account. This user will only have access to the /var/www/ghost directory and its home folder. This way, if Ghost gets compromised, you minimize the potential damage to your system.

Create a new ghost user with the following command:

  1. sudo adduser --shell /bin/bash ghost

Then make this new user the owner of the /var/www/ghost directory:

  1. sudo chown -R ghost:ghost /var/www/ghost/

Now let’s make sure this user can run Ghost. Log in as the ghost user:

  1. sudo su - ghost

Now start Ghost under this user and ensure it runs:

  1. cd /var/www/ghost
  2. npm start --production

You should be able to access your blog at http://your_domain_or_ip_address. Nginx will send requests to your Ghost instance.

Things are working great, but let’s make sure Ghost continues to run well into the future.

Step 5 — Running Ghost as a System Service

Currently, Ghost is running in our terminal. If we log off, our blog will shut down. Let’s get Ghost running in the background and make sure it restarts when the system restarts. To do this, we’ll create a systemd unit file that specifies how systemd should manage Ghost. Press CTRL+C to stop Ghost, and log out of the ghost user account by pressing CTRL+D.

Create a new file to hold the definition of the systemd unit file:

  1. sudo vi /etc/systemd/system/ghost.service

Add the following configuration to the file, which defines the service’s name, the group and user for the service, and information on how it should start:




ExecStart=/usr/bin/npm start --production
ExecStop=/usr/bin/npm stop --production


If you’re not familiar with systemd unit files, take a look at the tutorial Understanding Systemd Units and Unit Files which should get you up to speed quickly.

Save the file and exit the editor. Then enable and start the service:

  1. sudo systemctl enable ghost.service
  2. sudo sytemctl start ghost.service

Once again, visit http://your_domain_or_ip_address and you’ll see your blog.


In this tutorial, you installed Ghost, configured Nginx to proxy requests to Ghost, and ensured that Ghost runs as a system service. There is a lot more you can do with Ghost, though. Take a look at these tutorials to learn more about how to use your new blog:

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I am getting prompted for the pw for ghost. What have I done wrong? I followed the guide to the tee.

config file location has changed, so better update it accordingly…

minor typo –

sudo sytemctl start ghost.service

should be:

sudo systemctl start ghost.service

great tutorial!

There may be a small omission in this article. If you do not “Install Node from the EPEL Repository” when you install Node.js (https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-a-centos-7-server) then “sudo yum install npm” never gets run so starting Ghost with the “sudo npm start --production” will fail. I could be wrong about this, but thought you should know. Thanks for a great tutorial.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel