Skip to content

Using NextCloud for Ghost Static Files

Posted on:July 20, 2015

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:

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:

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: