Ghost is a powerful blog platform written in Node.js. Its simplicity and speed make it an ideal option for hosting a simple
After installing Ghost, the first problem I ran in to was hosting photos. Having migrated data from Wordpress, the images were still hosted on that domain. If I pulled the Wordpress site down, that would mean losing my images.
NextCloud
NextCloud is perhaps the most popular self-hosted cloud service. Think Dropbox or Box, but hosted on your own server. This gives the user a high level of control over the features and security. I figured I could probably host my static and media files here.
What’s even more helpful is that the NextCloud interface has syntax highlighting for files like .js
and .css
. This makes it especially useful as you can edit your public static files directly in the cloud.
I spun up a DigitalOcean droplet and got to work. I was installing on CentOS 7, so your setup may vary.
Installation
We’re going to install in the following steps:
- Install nginx
- Install NextCloud
- Install Ghost
- Additional configuration to serve static files
Installing nginx
Install prerequisites
yum -y install epel-release
yum groupinstall "Development tools"
Create a new Yum repository for nginx:
$ sudo nano /etc/yum.repos.d/nginx.repo
And fill it with the following repository definition:
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
Install nginx
$ yum install nginx
With nginx installed, we want to open the appropriate ports on Centos using Firewalld:
$ firewall-cmd --permanent --add-service=http
$ firewall-cmd --permanent --add-service=https
$ firewall-cmd --reload
Installing NextCloud
Installing on CentOS has some additional requirements, such as using MariaDB in place of MySQL. I won’t be covering the installation of MariaDB.
Create a new table and user for NextCloud:
> create database owncloud_db;
> create user owncloud@localhost identified by 'YOUR_PASSWORD';
And grant that user the necessary privileges:
> grant all privileges on owncloud_db.* to ownclouduser@localhost identified by 'ownclouduser';
> flush privileges;
Install NextCloud. I’m not going to explain these steps, there are tons of resources out there to get NextCloud going.
$ cd ~
$ yum -y install wget
$ wget https://download.owncloud.org/community/owncloud-8.1.0.tar.bz2
$ tar -xjvf owncloud-8.0.0.tar.bz2
$ mv owncloud/ /usr/share/nginx/html/
$ cd /usr/share/nginx/html/
$ mkdir -p owncloud/data/
$ chown nginx:nginx -R owncloud/data/
* Note that you might need to change the user in chown
to your nginx user (maybe www-data
or some other user)
Now let’s generate a self-signed SSL certificate to use. If you already have an SSL certificate, skip this step.
$ mkdir -p /etc/nginx/cert/
$ cd /etc/nginx/cert/
$ openssl req -new -x509 -days 365 -nodes -out /etc/nginx/cert/owncloud.crt -keyout /etc/nginx/cert/owncloud.key
$ chmod 600 owncloud.crt
$ chmod 600 owncloud.key
Once that’s done, we’ll create a new nginx virtualhost for NextCloud:
$ cd /etc/nginx/conf.d/
$ mv default.conf default
$ sudo nano owncloud.conf
Here’s the configuration I’m using:
# /etc/nginx/conf.d/owncloud.conf
upstream php {
server 127.0.0.1:9000;
#server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name cloud.mydomain.com; #Enter your IP or hostname here
return 301 https://$server_name$request_uri; # redirect to ssl
}
server {
listen 443 ssl;
server_name cloud.mydomain.com; #Enter your IP or hostname here
ssl_certificate /etc/nginx/cert/owncloud.crt;
ssl_certificate_key /etc/nginx/cert/owncloud.key;
# Location of our NextCloud files
root /usr/share/nginx/html/owncloud/;
client_max_body_size 100M;
fastcgi_buffers 64 4K;
rewrite ^/caldav(.*)$ /remote.php/caldav$1 redirect;
rewrite ^/carddav(.*)$ /remote.php/carddav$1 redirect;
rewrite ^/webdav(.*)$ /remote.php/webdav$1 redirect;
index index.php;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~ ^/(data|config|\.ht|db_structure\.xml|README) {
deny all;
}
location / {
rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
rewrite ^/.well-known/carddav /remote.php/carddav/ redirect;
rewrite ^/.well-known/caldav /remote.php/caldav/ redirect;
rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
try_files $uri $uri/ index.php;
}
location ~ ^(.+?\.php)(/.*)?$ {
try_files $1 = 404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$1;
fastcgi_param PATH_INFO $2;
fastcgi_param HTTPS on;
fastcgi_pass php;
}
}
Now reload nginx and set up owncloud at cloud.mydomain.com. If you’re using an IP address for now, you can optionally configure nginx to listen on a different port like 81 or 8080 while you finish this configuration. However, it should definitely be hosted at a subdomain at some point.
Installing Ghost
Ghost installation is pretty straightforward. Details on how to get it set up using PostgreSQL and nginx. Basically, we just need to run index.js
from inside the Ghost folder that we download and it’s ready to go! I recommend using PM2 to properly daemonize your Ghost instance.
Here’s an example nginx configuration to get you started with Ghost:
# /etc/nginx/conf.d/ghost.conf
upstream ghost {
server http://127.0.0.1:2368;
}
server {
listen 80;
server_name your-domain-name;
access_log /var/log/nginx/ghost-access.log;
error_log /var/log/nginx/ghost-error.log;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header HOST $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://ghost;
proxy_redirect off;
}
}
Confirm that nginx, NextCloud, and Ghost are up and running before configuring the static files support.
Configuring nginx to serve /static/
We want to set up nginx to serve a directory from within NextCloud. In this case, log in to your NextCloud server and create a directory called static
. Inside here, we can make three more directories:
/static/js
/static/img
/static/css
You can configure whatever directories you need. These are just the ones I used.
You’ll notice that these folders are located on disk at the following location:
/usr/share/nginx/html/owncloud/data/YOUR_OWNCLOUD_USER/files/static/
This is the directory we’re going to serve with nginx. Let’s first create a simlink to that directory:
$ sudo ln -s /usr/share/nginx/html/owncloud/data/YOUR_OWNCLOUD_USER/files/static/ /var/www/static/
Now, we simply need to add one more location block to our ghost.conf
:
# /etc/nginx/conf.d/ghost.conf
upstream ghost {
server http://127.0.0.1:2368;
}
server {
...
location ^~ /static {
alias /var/www/static/;
}
...
}
Now reload nginx
$ sudo nginx -s reload
or
$ sudo systemctl restart nginx
Let’s confirm it’s working. Log in to NextCloud and upload an image under /static/img/
. Then, enter it into a new Ghost post. If you can see the image, you’re good!
Ways I use NextCloud for my static files:
- All images in Ghost posts
- Highlight.js
- Injection in default.hbs so I can see highlighting in the editor
- Injection in Ghost’s Code Injection settings
- Custom CSS injected in Code Injection
- Custom JS injected in Code Injection