20 DECEMBER 2021: UNLISTED AT ERIK’S REQUEST.
|Summary||Learn how to deploy Nextcloud and Collabora Online on Ubuntu server, all backed by HTTPS using Let’s Encrypt|
|Author||Tim McNamara firstname.lastname@example.org|
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.
To make your way through this tutorial, you will need:
- Juju installed (see Installing Juju)
- a domain name that you control
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
Establishing a Juju controller
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. It hosts the Juju controller for you such that you are only responsible for hosting your application(s).
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.
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 (
email@example.com 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: firstname.lastname@example.org Cloud "home" successfully added You may bootstrap with 'juju bootstrap home'
Create a controller
juju bootstrap command to create the controller. Add the name of the cloud you wish to deploy to as an argument.
$ juju bootstrap home
juju bootstrap command takes many options. Follow Getting Started with Juju for detailed instructions.
Which clouds does Juju support?:
juju clouds command to list the clouds that Juju knows about.
Creating a model
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>`
We now need to add machines to our model. How to do this is subtly different depending on the type of cloud that we are using.
Need to add many machines?
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:email@example.com 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
If you would like a “1-click” install, you can use this command to 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’ll allocate 120 GB of storage space.
$ juju deploy postgresql --storage pgdata=120G --to 0 Located charm "cs:postgresql-203". Deploying charm "cs:postgresql-203".
PostgreSQL and Nextcloud are 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 126.96.36.199 80/tcp Need Mysql or Postgres relation to continue postgresql/0* active executing 0 188.8.131.52 5432/tcp (start) Live master (10.10) Machine State DNS Inst id Series AZ Message 0 started 184.108.40.206 i-0d1e5b3a3de5eb4ca bionic us-west-1c running
To fix this, we need to get the two applications to talk together.
$ juju relate nextcloud postgresql:db
It may 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 220.127.116.11 80/tcp Ready postgresql/0* active idle 0 18.104.22.168 5432/tcp Live master (10.10) Machine State DNS Inst id Series AZ Message 0 started 22.214.171.124 i-0d1e5b3a3de5eb4ca bionic us-west-1c running
Accessing the Nextcloud login page
Nextcloud is now fully operational. But accessing machine 0’s public IP address (126.96.36.199) 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).
But what are the login details we should type in?
Accessing the initial 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 this opportunity to change the admin account’s password and create a non-admin user account.
It is possible to set your own admin password at deployment time via the
--config option. The only reason we didn’t do it at that point was in order to keep things simple.
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 to the IP address of the machine hosting the
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
- ssl-termination-proxy/0: 188.8.131.52 (agent:idle, workload:active) 80/tcp, 443/tcp
With this information in hand, we can add the equivalent DNS entry:
cloud A 184.108.40.206 3600
Now, to 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 220.127.116.11 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 18.104.22.168 80/tcp Nextcloud is OK. postgresql/0* active idle 0 22.214.171.124 5432/tcp Live master (10.10) ssl-termination-proxy/0* active idle 1 126.96.36.199 80/tcp,443/tcp Ready (cloud.example.com) nextcloud-fqdn/0* active idle 188.8.131.52 Ready Machine State DNS Inst id Series AZ Message 0 started 184.108.40.206 i-0d1e5b3a3de5eb4ca bionic us-west-1c running 1 started 220.127.116.11 i-03d027ce3a8f9fc2e xenial us-west-1b running
If you now access the page, you might be surprised at what you encounter:
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 the 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. Make sure to include the
$ juju run-action nextcloud/0 add-trusted-domain --wait domain="localhost" index=1 Action queued with id: <id>
Alter the Nextcloud trusted_domains setting manually
If you want to know what’s happening under the hood, you can also perform this step yourself:
Access the 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 will look for it using the
sudo find / -name 'config.sample.php' 2>/dev/null
Let’s look inside that directory:
CAN_INSTALL config.php config.sample.php
config.php definitely looks like what we want. Let’s first make a backup.
cd /var/www/nextcloud/config/ sudo cp config.php config.backup.php
Now we can use our favourite editor to edit that file.
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
Visiting your domain name with your browser should present you with a login page with no security warnings:
The steps in this section should go faster, as they mostly duplicate the steps we already took for Nextcloud. Essentially we begin by deploying:
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 18.104.22.168 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
This step requires you to adjust a setting within Nextcloud’s Administration menu.
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
Juju community member @erik-lonroth built the
collabora charms to enable this.
The Tengu team, led by @merlijn-sebrechts, provided the Let’s Encrypt support.