How to self-host Nextcloud and Collabora on Ubuntu Server, both backed by HTTPS provided by Let's Encrypt

Introduction

Duration: 0:20

Banner introducing the tutorial

Nextcloud provides file hosting and several collaboration tools, like contacts, calendars and task boards.

The Collabora Online plugin allows for online collaborative document editing within the Nextcloud.

They’re easy to deploy and manage with Juju. Juju makes it practical to host a personal cloud.

Requirements

To make your way through this tutorial, you will need:

Testing install

Open up a terminal prompt and run the juju version command. If it reports a version, carry on. If not, retry the install steps.

$ juju version
2.7.5

What to do if you get stuck: The best place to ask for help is the Juju Discourse forum.

If you prefer chatting, visit us on IRC or Matrix.

Establishing a Juju controller

Duration: 5:00

We require a Juju controller. You have two options:

  • Use the hosted JAAS controller (recommended for using Amazon AWS, Microsoft Azure and Google Compute Platform)

  • Otherwise use the bootstrap process to create a controller yourself

What is a Juju controller?: Juju uses a software agent called “the controller” to apply changes that you make and to monitor the system’s health. Read more about Juju controllers.

Using the hosted JAAS controller

The Juju team provide a controller that can interact with Juju models hosted on public clouds.

$ juju login jaas

Using JAAS keeps costs down. You’re not responsible for hosting the controller as well as your application(s).

Bootstrap process

To bootstrap Juju onto your own hardware, we need to register your hardware first. We will collect each machine into a “cloud”.

Once the cloud is available, we’ll be able to create a controller into it.

Using your own computer hardware

(Skip this step if you are planning to deploy to public clouds)

If you have your own server hardware, you can make use of the manual cloud to register your computers with Juju.

The juju add-cloud command allows you to complete the registration process. It takes you through an interactive prompt where you will be asked to give a name to your cloud and SSH login details (user@10.10.10.100 in this example)

$ juju add-cloud
Cloud Types
  lxd
  maas
  manual
  openstack
  vsphere

Select cloud type: manual

Enter a name for your manual cloud: home

Enter the controller's hostname or IP address: user@10.10.10.100

Cloud "home" successfully added
You may bootstrap with 'juju bootstrap home'

Create a controller

Use the juju bootstrap command to create the controller. Add the name of the cloud you wish to deploy to as an argument.

$ juju bootstrap home

The juju bootstrap command takes many options. Follow Getting Started with Juju for detailed instructions.

Which clouds does Juju support?: Use the juju clouds command to list the clouds that Juju knows about.

Creating a model

Duration: 0:30

A model is a workspace for our applications. It houses machines, and applications.

Complex models also include other components like networking spaces and persistent storage volumes.

$ juju add-model privcloud
Added 'privcloud' model on aws/us-west-1 with credential '<credential>' for user `<user>`

Adding machines

Duration: 5:00

We now need to add machines to our model. How to do this is subtly different depending on which cloud

Need to add many machines?

Outside of the home or small office environment, your hardware will be more complex. Multi-server we recommend installing MAAS and then configuring a MAAS cloud.

We want to be conservative with our compute resources, so we’ll add a large machine manually, then deploy Nextcloud and the backing database to that single machine.

On a public cloud

Juju can provision machines on our behalf:

juju add-machine --constraints="mem=8G root-disk=200G"
created machine 0
On a manual cloud

We re-register the machine that’s hosting the controller as a machine that’s hosting the model.

$ juju add-machine sssh:user@10.10.10.100
created machine 0

We’ll also add a small xenial (14.04) instance to manage the ssl-termination-proxy charm. This will live as a container within machine 0.

$ juju add-machine lxd:0  --constraints="mem=256M" 
created container 0/lxd/0

Deploy Nextcloud and PostgreSQL

Duration: 2:30

If you would like a “1 click” install, you can use this command deploy everything together. By default, it will use several machines rather than making use of containers on the host:

juju deploy cs:~erik-lonroth/bundle/nextcloud-collabora-tls

$ juju deploy cs:~erik-lonroth/nextcloud --to 0
Located charm "cs:~erik-lonroth/nextcloud-3".
Deploying charm "cs:~erik-lonroth/nextcloud-3".

Nextcloud requires a database. We’ll install PostgreSQL. We allocate 120GB of storage space.

$ juju deploy postgresql --storage pgdata=120G --to 0
Located charm "cs:postgresql-203".
Deploying charm "cs:postgresql-203".

Multi-tenant applications: PostgreSQL and Nextcloud co-located on the same machine. To change this, we can add another unit of Nextcloud, then remove the nextcloud/0 unit. Juju provides us with the ability to start small and scale up as needed.

If you consult the juju status output, you’ll notice an angry red “blocked” message in two places:

$ juju status
Model      Controller  Cloud/Region   Version  SLA          Timestamp
privcloud  jaas        aws/us-west-1  2.6.10    unsupported  15:31:23+13:00

App         Version  Status   Scale  Charm       Store       Rev  OS      Notes
nextcloud            blocked      1  nextcloud   jujucharms    3  ubuntu  
postgresql  10.10    active       1  postgresql  jujucharms  199  ubuntu  

Unit           Workload  Agent      Machine  Public address  Ports     Message
nextcloud/0*   blocked   idle       0        52.53.172.164   80/tcp    Need Mysql or Postgres relation to continue
postgresql/0*  active    executing  0        52.53.172.164   5432/tcp  (start) Live master (10.10)

Machine  State    DNS            Inst id              Series  AZ          Message
0        started  52.53.172.164  i-0d1e5b3a3de5eb4ca  bionic  us-west-1c  running

Now, we need to get the two applications to talk together.

$ juju relate nextcloud postgresql:db

It my take a minute or two for the system to re-configure itself, but juju status will soon update itself to look more like this:

$ juju status
Model      Controller  Cloud/Region   Version  SLA          Timestamp
privcloud  jaas        aws/us-west-1  2.6.10    unsupported  15:35:07+13:00

App         Version  Status  Scale  Charm       Store       Rev  OS      Notes
nextcloud            active      1  nextcloud   jujucharms    3  ubuntu  
postgresql  10.10    active      1  postgresql  jujucharms  199  ubuntu  

Unit           Workload  Agent  Machine  Public address  Ports     Message
nextcloud/0*   active    idle   0        52.53.172.164   80/tcp    Ready
postgresql/0*  active    idle   0        52.53.172.164   5432/tcp  Live master (10.10)

Machine  State    DNS             Inst id              Series  AZ          Message
0        started  52.53.172.164   i-0d1e5b3a3de5eb4ca  bionic  us-west-1c  running

Accessing the Nextcloud login page

Duration: 1:30

Nextcloud is now fully operational. But accessing machine 0’s public IP address (52.53.172.164) on port 80 won’t yet show you a web page. We need to inform Juju to open the firewall.

juju expose nextcloud

If we visit the IP address now, we’re presented with a login screen (and some security warnings).

nexcloud-login

What to use for the login details?

Accessing the intial log in details for Nextcloud

Juju has created an admin account on our behalf using configuration parameters available in the charm.

We can access them via the juju config commands:

$ juju config nextcloud admin-username
admin
$ juju config nextcloud admin-password
mypassword

Entering these values into the form should present you with the Nextcloud application. Take the opportunity to change the admin account’s password and create a non-admin user account.

nextcloud-entry

it is possible to set your own admin password at deployment time via the --config option. It wasn’t done there to keep things simple.

Adding HTTPS

Duration: 5:00

You now need to add a DNS record to a domain for nextcloud. We’ll assume cloud.example.com. The A record needs to point at the IP address of the machine hosting the ssl-termination-proxy/0 unit.

An easy way to fetch the relevant IP address is to use the filtering and formatting options of the juju status command:

juju status ssl-termination-proxy/0 --format=line

Produces

- ssl-termination-proxy/0: 54.215.139.236 (agent:idle, workload:active) 80/tcp, 443/tcp

With that information available, add the equivalent DNS entry:

cloud 	A 	54.215.139.236	3600

Now, we set the config options for the relevant applications, we need to open the proxy to the Internet and add a relation between the ssl-termination-proxy and nextcloud-fqdn.

juju config nextcloud fqdn=cloud.example.com
juju config nextcloud-fqdn fqdns=cloud.example.com
juju expose ssl-termination-proxy 
juju relate ssl-termination-proxy nextcloud-fqdn:ssl-termination

After a minute or so, juju status output will converge to something that looks like this:

$ juju status
Model      Controller  Cloud/Region   Version  SLA          Timestamp
privcloud  jaas        aws/us-west-1  2.6.8    unsupported  16:14:23+13:00

App                    Version   Status  Scale  Charm                  Store       Rev  OS      Notes
nextcloud              16.0.1.1  active      1  nextcloud              jujucharms    3  ubuntu  exposed
nextcloud-fqdn                   active      1  ssl-termination-fqdn   jujucharms    5  ubuntu  
postgresql             10.10     active      1  postgresql             jujucharms  199  ubuntu  
ssl-termination-proxy            active      1  ssl-termination-proxy  jujucharms   15  ubuntu  exposed

Unit                      Workload  Agent  Machine  Public address  Ports           Message
nextcloud/0*              active    idle   0        52.53.172.164   80/tcp          Nextcloud is OK.
postgresql/0*             active    idle   0        52.53.172.164   5432/tcp        Live master (10.10)
ssl-termination-proxy/0*  active    idle   1        54.215.139.236  80/tcp,443/tcp  Ready (cloud.example.com)
  nextcloud-fqdn/0*       active    idle            54.215.139.236                  Ready

Machine  State    DNS             Inst id              Series  AZ          Message
0        started  52.53.172.164   i-0d1e5b3a3de5eb4ca  bionic  us-west-1c  running
1        started  54.215.139.236  i-03d027ce3a8f9fc2e  xenial  us-west-1b  running

If yo you now access the page, you might be surprised at what you encounter:

nextcloud-access

Okay. The security warnings from the browser have gone, but a new one from Nextcloud has popped up. But that’s okay. We can use juju ssh to make the recommended setting change.

Alter Nextcloud trusted_domains setting

We now need to tweak some settings within our Nextcloud instance to allow it to understand HTTPS.

The nextcloud charm that we’ve deployed supports an action that does this, add-trusted-domain. Include the domain and index parameters.

$ juju run-action nextcloud/0 add-trusted-domain --wait domain="localhost" index=1
Action queued with id: <id>

Alter Nextcloud trusted_domains setting manually

If you want to know what’s happening under the hood, you can also perform this step yourself:

Access remote shell securely

Juju provides a helper command that understands how to connect to units directly without needing to refer back to their IP addresses:

juju ssh nextcloud/0

Now, we need to find where the application is stored. We’ll use the find command to look for the file that

sudo find / -name 'config.sample.php' 2>/dev/null
/var/www/nextcloud/config/config.sample.php

Let’s look inside that directory:

ls /var/www/nextcloud/config/
CAN_INSTALL  config.php  config.sample.php

Great. config.php definitely looks like what we want. Let’s make a backup and edit that file.

cd /var/www/nextcloud/config/
sudo cp config.php config.backup.php

Use your favourite editor: to edit the

sudo nano config.php

Edit the ‘trusted_domains’ line so that it includes your domain name:

<?php
$CONFIG = array (
   // ...
  'trusted_domains' => array ('cloud.example.com'),
  // ...
);

Save the file.

Access Nextcloud over HTTPS

Duration: 0:10

Visiting your domain name with your browser should present you with a login page with no security warnings:

nextcloud-secure

Deploying Collabora

Duration: 5:00

This section will be faster, as it is mostly a duplication of the steps taken for Nextcloud.

juju deploy cs:~erik-lonroth/collabora --config nextcloud_domain=cloud.example.com
juju deploy cs:~tengu-team/ssl-termination-fqdn collabora-fqdn --config fqdns=docs.example.com

While that is deploying, add a DNS record for your Collabora. Here is an example:

docs 	A 	54.215.139.236	3600

Now, add the relations. After they’re added, your applications will automatically configure themselves.

juju relate collabora:website collabora-fqdn:website
juju relate collabora-fqdn:ssl-termination ssl-termination-proxy:ssl-termination

Install the Collabora Online plugin for Nextcloud

Duration: 3:00

This step requires you to adjust a setting within Nextcloud’s Administration menu.

User > Apps

Download and enable the Collabora Online plugin

Click the User > Settings

Configure the plugin with the domain name of your plugin

Appendix: All steps as a single script

Juju is asynchronous and declarative. The commands in this tutorial can be executed in any order and will be resolved by Juju. Here they are as a single script that you can customise (be sure to update the configuration values):

juju deploy cs:~erik-lonroth/nextcloud
juju deploy cs:~erik-lonroth/collabora
juju deploy postgresql --storage pgdata=100G
juju deploy cs:~tengu-team/ssl-termination-proxy
juju deploy cs:~tengu-team/ssl-termination-fqdn collabora-fqdn
juju deploy cs:~tengu-team/ssl-termination-fqdn nextcloud-fqdn

# database configuration
juju relate postgresql:db nextcloud:postgres

# nextcloud configuration
juju relate nextcloud:website nextcloud-fqdn:website
juju relate nextcloud-fqdn:ssl-termination ssl-termination-proxy:ssl-termination
juju config nextcloud fqdn=cloud.example.com

# collabora configuration
juju relate collabora:website collabora-fqdn:website
juju relate collabora-fqdn:ssl-termination ssl-termination-proxy:ssl-termination
juju config collabora nextcloud_domain=cloud.example.com
juju config collabora-fqdn fqdns=docs.example.com

# networking
juju expose ssl-termination-proxy

Acknowledgements

Juju community member @erik-lonroth built the nextcloud and collabora charms to enable this.

The Tengu team, led by @merlijn-sebrechts, provided the Let’s Encrypt support.

6 Likes

The nextcloud charm has a juju-action for adding trusted domains @timClicks

Oh cool! That simplifies things greatly.

1 Like

By the way, if you’re wondering why I haven’t said to install the bundle - I intend to. But I also thought that it would be useful to explain what is happening.

1 Like

@erik-lonroth I just tried this on a new model and hit a permissions error. I will see if I can get time over the weekend to submit a fix to the charm.

$ juju run-action nextcloud/0 add-trusted-domain domain="localhost" index=1
Action queued with id: bb724530-7ebb-4727-87c7-7b9c2b740747

$ juju show-action-output --wait 0  bb724530-7ebb-4727-87c7-7b9c2b740747
results:
  result-map:
    message: |-
      Cannot write into "config" directory!
      This can usually be fixed by giving the webserver write access to the config directory
      See https://docs.nextcloud.com/server/16/go.php?to=admin-dir_permissions

      Or, if you prefer to keep config.php file read only, set the option "config_is_read_only" to true in it.
      See https://docs.nextcloud.com/server/16/go.php?to=admin-config
    time-completed: Wed Oct 23 20:03:23 UTC 2019
status: completed
timing:
  completed: 2019-10-23 20:03:24 +0000 UTC
  enqueued: 2019-10-23 20:03:02 +0000 UTC
  started: 2019-10-23 20:03:23 +0000 UTC

1 Like

Hello @timClicks

I’m about to go through this with two communities over the next two months:

https://edgeryders.eu

… and…

OpenHack2020 Australia:
https://m.youtube.com/watch?v=1G7wzXV-YGU

Totally going to use your tutorial!

Cool! This is in my time zone… I will see if I can participate.

1 Like

https://www.openhack2020australia.com/hack4future

I will try to make a youtube vid on this with the help of some people. Would I be able to modify this tutorial @timClicks since the part for example with the trusted_domain is available through an action as I mentioned to you before.

Hi Erik, I’ve updated the tutorial and made it easier to find by making it part of our official tutorials series:

https://jaas.ai/tutorials/deploy-nextcloud-and-collabora-on-ubuntu

2 Likes

That’s amazing. I’m already updating the charm adding support for “storage” in the charm.

I have plans to look into making use of the “nextcloud” snap. https://snapcraft.io/nextcloud

But that would come later.

Those seem like excellent additions. The snap route makes installation trivial. It also manages the services. Your job as charm author is to wire configuration data from relations to the “snap set” command.

I added in support tonight for storage which is now in the edge channel on revision 4.

The snap might have to come later…