Using AWS S3 as Primary Storage on Nextcloud

I have been testing/using Nextcloud for the last couple of months in hopes of getting rid of Dropbox, Google Drive, etc. I recently experimented with having external storage connected to it. That’s all fine and dandy, but then I wondered if an external storage could be used as the primary storage? A little searching revealed I wasn’t the first person to think of that. In fact it is supported by Nextcloud and is documented. To get started create a bucket with the desired settings and create an IAM user that has access.

The official Nextcloud documentation gives this example:

‘objectstore’ => array(
‘class’ => ‘OC\\Files\\ObjectStore\\S3’,
‘arguments’ => array(
‘bucket’ => ‘nextcloud’,
‘autocreate’ => true,
‘key’ => ‘EJ39ITYZEUH5BGWDRUFY’,
‘secret’ => ‘M5MrXTRjkyMaxXPe2FRXMTfTfbKEnZCu+7uRTVSj’,
‘hostname’ => ‘example.com’,
‘port’ => 1234,
‘use_ssl’ => true,
‘region’ => ‘optional’,
// required for some non amazon s3 implementations
‘use_path_style’=>true
),
),

Based on my experience using AWS S3 as an external storage device, I ended up with this as my config:

‘objectstore’ => array(
‘class’ => ‘OC\\Files\\ObjectStore\\S3’,
‘arguments’ => array(
‘bucket’ => ‘<my_bucket>’,
‘key’ => ‘<key>’,
‘secret’ => ‘<so_secret>’,
‘use_ssl’ => true,
‘region’ => ‘<region>,
// required for some non amazon s3 implementations
‘use_path_style’=>true
),
),

Specifically, I found it necessary to specify the region (i.e. us-west-2) and SSL otherwise I got errors.

I have been running this for a few days now and have not seen any issues.

Nextcloud, Docker, and upgrades

I have been running Nextcloud via a Docker image for a few months and recently a new version of Nextcloud was released. This seemed like the perfect opportunity to test out upgrading to a newer Nextcloud Docker image and keeping my data. Since I mount a volume to keep the configuration data in, it will be a fairly easy to upgrade.

First step is to make sure we have backups and verify their integrity. The Nextcloud backups page details these instructions pretty well, but just to cover the basics you need to backup your data and database at a minimum. I also went ahead and grabbed a copy of the config.php by itself and stored it outside of the container. Tip: I didn’t initially know which volume store was the right one, so I entered the container by loading bash and created a temporary file named ‘findmehere’ that I could search for from the host.

Next we will stop the existing container by issuing a ‘docker stop <id>’ where <id> is the container id listed in the output of ‘docker ps’. Then we will start a new docker image using the same command we did the first time. For me this looked like ‘docker run -d -v nextcloud:/var/www/html -p 8181:80 nextcloud’ but YMMV.

The occ script should detect the new version of Nextcloud and start the upgrade. Check the status by visiting your Nextcloud web page. Since we used a volume to keep our data in we should be all set!

Nextcloud and Docker with Apache Proxy

I decided I wanted to try migrating away from Dropbox, Amazon Drive, and Google Drive to my own server using open source tools. After a bit of research I determined Nextcloud would be the best fit for what I wanted to do right now and some optional features later on. Nextcloud can be installed via packages in the major distributions, but I wanted to use this opportunity to test drive Docker at the same time. One of the reasons I wanted to use a container was so that the installation is mostly isolated from the host install which is good for security purposes but also makes it easier if I want to migrate the whole thing to a different host later on. Now the host I want to use already has a web server, Apache, listening on ports 80 and 443, so we’ll configure it to act as a proxy between the web server in the Nextcloud Docker image and the client. This will also fit well with the SSL certificate the host has.

The first step is getting Docker installed and running. This is pretty easy for most distributions and is covered in detail on the official Docker Community Edition site for Ubuntu, CentOS, and the Gentoo Wiki even has instructions as well.

Once you’ve got Docker up and running. let’s test it out first:

docker run hello-world

This should download the hello-world image and run it.

Now, let’s get to docker. First let me mention that I already have a database (PostgreSQL) that I used so I’ll skip that step here, but if you don’t already have a database available now would be the point to pause and go get that resolved. Since data is not saved between Docker containers, we will need to instruct Docker to create a mount point for the Nextcloud image that will keep our data safe. This can be accomplished with the ‘-v’ flag. We also need to tell Docker what port we want to open up, but in my case I don’t want it using port 80 or 443 so we’ll have to further instruct Docker to forward the port in our ‘-p’ flag.

docker run -d -v nextcloud:/var/www/html -p 8181:80 nextcloud

In the above command I have select port 8181 on the host to be passed to port 80 on the Nextcloud Docker image. Once the Docker container loads completely you should be able to access it via http://your_ip:8181 and see the setup page, but before we do that let’s setup our proxy.

On the host side we will create an Apache vhost with a few lines like this:

<VirtualHost *:80>
ServerName nextcloud.my_domain.com
http://localhost:8181/
Redirect permanent / https://nextcloud.my_domain.com </VirtualHost>

<VirtualHost *:443>
ServerName nextcloud.my_domain.com

<proxy *>
Require host localhost
Require all granted
</proxy>
ProxyPass / http://localhost:8181/
<IfModule mpm_peruser_module>
ServerEnvironment apache apache
</IfModule>
<IfModule mod_headers.c>
Header always set Strict-Transport-Security “max-age=15552000; includeSubDomains”
</IfModule>

SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/my_certificate.pem
SSLCertificateKeyFile /etc/my_certificate-private.pem
SSLCertificateChainFile /etc/my_certificate-full.pem
</VirtualHost>

What this configuration does is force all non-SSL connections to use SSL. Then under the SSL configuration it proxies all connections to port 8181 on localhost where nextcloud is running. Then finally we use our SSL certificate from the host. Don’t forget to setup DNS for your nextcloud domain!

At this point we should be ready to continue with the setup via web. Load up https://nextcloud.my_domain.com in your web browser and follow the on-screen instructions. One of the pages should detect the proxy setup and ask for additional domain(s) to be configured so be sure to add https://nextcloud.my_domain.com to the list in addition to http://host.my_domain.com:8181 (if desired).

One final step that I suggest is setting up a cron job on the host (not inside the Nextcloud Docker image). I have mine set to run ever 15 minutes. In order for this to work we need to install sudo in the container by entering the container:

docker exec -it 16765e565e25 bash

Update apt sources:

apt-get update

Install sudo:

apt-get install sudo

Now finally on the host (NOT container) create a crontab with this line:

*/15 * * * * docker exec -d <docker id> /usr/bin/sudo -u www-data /usr/local/bin/php /var/www/html/cron.php

Be sure to replace <docker id> with the real one which you can find by running ‘docker ps’ on the host.

At this point you should have a fully functional Nextcloud server!