collabora office http://tech.oeru.org/ en Installing NextCloud and Collabora Office Online with Docker on Ubuntu 16.04 http://tech.oeru.org/installing-nextcloud-and-collabora-office-online-docker-ubuntu-1604 <span class="field field--name-title field--type-string field--label-hidden">Installing NextCloud and Collabora Office Online with Docker on Ubuntu 16.04</span> <div class="field field-node--field-blog-tags field-name-field-blog-tags field-type-entity-reference field-label-above"> <h3 class="field__label">Blog tags</h3> <div class="field__items"> <div class="field__item field__item--ubuntu-linux"> <span class="field__item-wrapper"><a href="/taxonomy/term/12" hreflang="en">ubuntu linux</a></span> </div> <div class="field__item field__item--mariadb"> <span class="field__item-wrapper"><a href="/taxonomy/term/48" hreflang="en">mariadb</a></span> </div> <div class="field__item field__item--docker"> <span class="field__item-wrapper"><a href="/taxonomy/term/16" hreflang="en">docker</a></span> </div> <div class="field__item field__item--docker-compose"> <span class="field__item-wrapper"><a href="/taxonomy/term/49" hreflang="en">docker-compose</a></span> </div> <div class="field__item field__item--php"> <span class="field__item-wrapper"><a href="/taxonomy/term/40" hreflang="en">php</a></span> </div> <div class="field__item field__item--collabora-office"> <span class="field__item-wrapper"><a href="/taxonomy/term/50" hreflang="en">collabora office</a></span> </div> <div class="field__item field__item--nextcloud"> <span class="field__item-wrapper"><a href="/taxonomy/term/51" hreflang="en">nextcloud</a></span> </div> <div class="field__item field__item--lets-encrypt"> <span class="field__item-wrapper"><a href="/taxonomy/term/17" hreflang="en">let&#039;s encrypt</a></span> </div> <div class="field__item field__item--redis"> <span class="field__item-wrapper"><a href="/taxonomy/term/21" hreflang="en">redis</a></span> </div> <div class="field__item field__item--productivity"> <span class="field__item-wrapper"><a href="/taxonomy/term/52" hreflang="en">productivity</a></span> </div> <div class="field__item field__item--nginx"> <span class="field__item-wrapper"><a href="/taxonomy/term/30" hreflang="en">nginx</a></span> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="View user profile." href="/user/1" class="username">dave</a></span> <span class="field field--name-created field--type-created field--label-hidden">Mon 29/01/2018 - 17:29</span> <div class="field field-node--field-image field-name-field-image field-type-image field-label-hidden has-multiple"> <figure class="field-type-image__figure image-count-1"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/Files%20-%20OERu%20NextCloud.png?itok=xQHlcyml" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;The NextCloud web interface for browsing your files&quot;}" role="button" title="The NextCloud web interface for browsing your files" data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;The NextCloud web interface for browsing your files&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/Files%20-%20OERu%20NextCloud.png?itok=6v2Kuyct" width="220" height="164" alt="The NextCloud web interface for browsing your files" loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-2"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/NextCloud-AppStore.png?itok=DPeCx5Rd" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;The central AppStore (note, almost all apps have no cost and are open source). You get a similar view within your own NextCloud instance.&quot;}" role="button" title="The central AppStore (note, almost all apps have no cost and are open source). You get a similar view within your own NextCloud instance." data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;The central AppStore (note, almost all apps have no cost and are open source). You get a similar view within your own NextCloud instance.&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/NextCloud-AppStore.png?itok=WqCJJdGj" width="220" height="175" alt="The central AppStore (note, almost all apps have no cost and are open source). You get a similar view within your own NextCloud instance." loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-3"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/NextCloud-Calendar.png?itok=-j0Dq2rG" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;The NextCloud shared calendar plugin works with all major calendaring applications alongside your existing digital calendars.&quot;}" role="button" title="The NextCloud shared calendar plugin works with all major calendaring applications alongside your existing digital calendars." data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;The NextCloud shared calendar plugin works with all major calendaring applications alongside your existing digital calendars.&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/NextCloud-Calendar.png?itok=bP23WxDf" width="220" height="175" alt="The NextCloud shared calendar plugin works with all major calendaring applications alongside your existing digital calendars." loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-4"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/Nextcloud-CollaboraSpreadsheet.png?itok=Ovp0KryQ" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;An example of a fairly complex spreadsheet in the Collabora spreadsheet interface.&quot;}" role="button" title="An example of a fairly complex spreadsheet in the Collabora spreadsheet interface." data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;An example of a fairly complex spreadsheet in the Collabora spreadsheet interface.&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/Nextcloud-CollaboraSpreadsheet.png?itok=CNhDR2y-" width="220" height="157" alt="An example of a fairly complex spreadsheet in the Collabora spreadsheet interface." loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-5"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/Nextcloud-CollaboraWordprocessor.png?itok=IOyfA_M4" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;A fairly complex document, with variables, shown in the Collabora wordprocessor interface.&quot;}" role="button" title="A fairly complex document, with variables, shown in the Collabora wordprocessor interface." data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;A fairly complex document, with variables, shown in the Collabora wordprocessor interface.&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/Nextcloud-CollaboraWordprocessor.png?itok=HPawBI-o" width="220" height="157" alt="A fairly complex document, with variables, shown in the Collabora wordprocessor interface." loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-6"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-01/DavInFilemanager.png?itok=rCbwaUUY" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;This is what your NextCloud would look like in your desktop filemanager (this is the Nemo filemanager on a Linux desktop)&quot;}" role="button" title="This is what your NextCloud would look like in your desktop filemanager (this is the Nemo filemanager on a Linux desktop)" data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;This is what your NextCloud would look like in your desktop filemanager (this is the Nemo filemanager on a Linux desktop)&quot;}"><img src="/sites/default/files/styles/medium/public/2018-01/DavInFilemanager.png?itok=g2dNm33H" width="220" height="122" alt="This is what your NextCloud would look like in your desktop filemanager (this is the Nemo filemanager on a Linux desktop)" loading="lazy" class="image-style-medium" /> </a> </div> </figure> <figure class="field-type-image__figure image-count-7"> <div class="field-type-image__item"> <a href="http://tech.oeru.org/sites/default/files/styles/max_1300x1300/public/2018-02/CollaboraAdminConsole.png?itok=1tNI9ZdJ" aria-controls="colorbox" aria-label="{&quot;alt&quot;:&quot;Collabora Office admin console&quot;}" role="button" title="Collabora Office admin console" data-colorbox-gallery="gallery-field_image-9s1vCmuTUlQ" class="colorbox" data-cbox-img-attrs="{&quot;alt&quot;:&quot;Collabora Office admin console&quot;}"><img src="/sites/default/files/styles/medium/public/2018-02/CollaboraAdminConsole.png?itok=iijjMrBK" width="220" height="149" alt="Collabora Office admin console" loading="lazy" class="image-style-medium" /> </a> </div> </figure> </div> <div class="clearfix text-formatted field field-node--body field-name-body field-type-text-with-summary field-label-hidden"> <div class="field__items"> <div class="field__item"><p><strong>Update 2021-11-08</strong>: this post is now getting a bit long-in-the-tooth, and I need to update it to use up-to-date components. It might still be useful to folks, but use it with caution. Also, please note, we're using NextCloud with <a href="https://onlyoffice.com">OnlyOffice</a> (the open source community edition) these days. <strong>Update 2023-06-14</strong>: Here's a <a href="/node/56">new tutorial for Ubuntu 22.04</a>!</p> <p>Dropbox is the best known of the end-user "cloud storage" services for documents, backups, and synchronising data among multiple devices, although now Google's Drive and Microsoft's OneDrive are functionally similar and are being heavily promoted and tied into all sorts of services.</p> <p>Similarly the collaborative editing of documents, spreadsheets, and presentations in the browser, pioneered by Etherpad, but then adopted in a big way by Google Docs (and more recently, Microsoft Office 365), has revolutionised collective note taking, document preparation, and ease of access to these powerful tools by the mainstream of computer users. Only a browser is required, and no other software needs to be installed.</p> <p>But what about people who don't want to entrust all of their data to foreign corporations, holding their data in foreign jurisdiction, in formats that may or may not be retrievable in the event that the supplier fails or changes "strategic direction"? And many of these services involve "mining" their data to extract useful information that vendors sell to others to <em>help them advertise to us in a more targeted way. </em>Yeah, that's creepy.</p> <p>More-over, often if you want to <em>share</em> your data with others, <em>they</em> have to log into the same service, and accept the service's terms and conditions (usually substantially constraining the user's normal rights and freedoms, although who<em> actually</em> reads those, eh?!) in order to do so... so ones use of those services has a magnifying effect on the loss of privacy and control.</p> <p>Some people sensibly prefer to manage their own, or institution-specific, solutions on the infrastructure of their choosing, in a way that doesn't tie anyone into paying ever increasing amounts for data storage as the volumes increase perpetually, month on month.</p> <p>Some of us simply prefer to have control of our own destiny, without a dependence on, for example, file or data storage formats and practices that are completely opaque to them. Our data reflects our creativity energy, and it seems much more comfortable for many of us to be in charge of our own fates rather than entrusting it to a third party who simply sees us a profit centre.</p> <p>Thankfully, the open source world has created an array of possible equivalent systems, and this post describes how you, too, can set up your own equivalent to Dropbox + Google Docs using entirely open source software on any commodity virtual machine hosting system you want to use by adopting NextCloud and Collabora Office.</p> <h2>NextCloud</h2> <p><a href="https://nextcloud.com">NextCloud</a> is <a href="https://nextcloud.com/files/">functionally similar</a> to Dropbox, however, with its active development community and plug-in architecture, it can provide quite a lot more as well, like shared calendaring, email, video conferencing, contact syncing, image/sound/video galleries, <a href="https://nextcloud.com/files/">among many other services</a>.</p> <p>If you prefer not to organise and run your own server, you can purchase a supported server via their website for a cost similar to Dropbox (although, realise that NextCloud is relatively small by comparison and doesn't have the massive economies of scale enjoyed by the bigger players).</p> <p>For those with an interest in history: NextCloud is a fork created by the founder of OwnCloud, after he decided that the company which formed around his OwnCloud project was moving in a direction that was philosophical unpalatable for him. The beauty of open source is that developers can follow their consciences without requiring anyone's permission. The resulting "forks" in code bases and communities then thrive or die based on the strengths of the communities they can build and sustain. This fork is remarkably similar to that which occurred in the OpenOffice community which resulted in the founding of LibreOffice. LibreOffice has thrived and OpenOffice has faded into irrelevance. More on that below.</p> <p>For those with a technological interest, NextCloud is a mature PHP application (but with a modern architecture, including a command line interface, occ) which stores its data in an RDBMS like MySQL, MariaDB, PostgreSQL, or (usually for development purposes) the lightweight SQLite database. Here are <a href="https://docs.nextcloud.com/server/12/admin_manual/installation/index.html">details for would-be administrators</a>.</p> <h2>Collabora Office</h2> <p>Given how much companies like Google and Microsoft invest on Docs and Office 365 respectively, how is it possible for an open source community to create a credible competitor? Turns out it's not as hard as you might think if they leverage the power of open source.</p> <p>A small software company with headquarters in the UK (although their team appears to be from all over), Collabora Office, has taken on the ambitious mission of creating a "collaborative web interface" allowing users to collaborate using <a href="https://libreoffice.org">LibreOffice</a>, one of the most powerful and widely used office package available anywhere. We're currently at Collabora Office 3.0, and the front end is quite nice and functional, but still pretty simple - that can be a good thing for many users. Collabora is progressively re-imagining the user interface of LibreOffice as a collaborative web interface. This isn't easy, but it's <em>much</em> easier than it otherwise would be because the difficult job of creating the heavy-lifting application back-end is already done - LibreOffice is a mature widely used application (albeit with a desktop interface, not a web-based collaborative interface). So we can expect progress will be rapid, and large sets of new capabilities will be "unlocked" as they progress their efforts.</p> <h2>NextCloud and Collabora - better together!</h2> <p>The beauty of the open source software model is that we can connect NextCloud and Collabora office - completely separate and unrelated communities - thanks to a new integration standard, WOPI (Web-application Open Platform Interface) they form a well integrated component model - with the <em>major </em>added benefit of being able to swap in a better file management platform, or a better collaborative productivity package if one or the other emerges, without having to start from scratch.</p> <h2>Setting up your own NextCloud Collabora Server</h2> <p>If you're game to run your own (and, in my experience, it's a surprisingly well behaved system) here's how you do it.</p> <p>In preparation, you'll want to have the following ready:</p> <ul><li>a Linux virtual machine or "VM" (I recommend running the current Ubuntu LTS version, or current Debian) with a user with Sudo privileges...,</li> <li>your domain name for the NextCloud instance, pointing to the IP address of your VM,</li> <li>your domain name for the Collabora instance, also pointing to the IP of your VM, and</li> <li>credentials for an email address capable of sending from a remote server (usually termed an "authenticating SMTP email account")</li> </ul><h3>Secure access with SSH</h3> <p>First things first, make sure you're logged into your host (probably via SSH) as a user who has "sudo" capabilities! You need to log into the host from your local machine. We recommend setting up <a href="https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server">key-based authentication</a>.</p> <h3>Firewall with UFW</h3> <p>No computer system is ever full secure - there're always exploits waiting to be found, so security is a process of maintaining vigilance. Part of that is reducing exposure - minimising your "attack surface". Use a firewall - "<a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-16-04" title="Uncomplicated FireWall">ufw</a>" is installed on Ubuntu by default. Make sure you've got exceptions for SSH (without them, you could lock yourself out of your machine! Doh!).</p> <p>Run the following commands to allow your Docker containers to talk to other services on your host.</p> <p><code>sudo ufw allow in on docker0<br /> sudo ufw allow from 172.0.0.0/8 to any</code></p> <p>Specifically for Docker's benefit, you need to tweak the default Forwarding rule (I use "vim" as my editor. If you don't know how to/want to use it, replace <strong>vim</strong> with <strong>nano</strong> everywhere you see it in the following - nano's easier to use for simple edits like this):</p> <p><code>sudo vim /etc/default/ufw</code></p> <p>and copy the line <code>DEFAULT_FORWARD_POLICY="DROP"</code> tweak it to look like this (commenting out the default, but leaving it there for future reference!):</p> <p><code>#DEFAULT_FORWARD_POLICY="DROP"<br /> DEFAULT_FORWARD_POLICY="ACCEPT"</code></p> <p>You also have to edit <code>/etc/ufw/sysctl.conf</code> and remove the "#" at the start of the following lines, so they look like this:</p> <p><code>sudo vim /etc/ufw/sysctl.conf</code></p> <p><code># Uncomment this to allow this host to route packets between interfaces<br /> net/ipv4/ip_forward=1<br /> net/ipv6/conf/default/forwarding=1<br /> net/ipv6/conf/all/forwarding=1</code></p> <p>and finally restart the network stack and ufw on your server<code> </code></p> <p><code>sudo service networking restart<br /> sudo service ufw restart</code></p> <h3>Installing the Nginx webserver</h3> <p>In the configuration I'm describing here, you'll need a webserver running on the server - it'll be acting as a "proxy" for the Docker-based Nginx instance described below. I like the efficiency of Nginx and clarity of Nginx configurations over those of Apache and other open source web servers. Here's how you install it.</p> <p><code>sudo apt-get install nginx-full</code></p> <p>To allow nginx to be visible via ports 80 and 443, run</p> <p><code>sudo ufw allow "Nginx Full"</code></p> <p><strong>Note</strong>: make sure your hosting service is not blocking these ports at some outer layer (depending on who's providing that hosting service you may have to set up port forwarding).</p> <h3>Installing MariaDB</h3> <p>MariaDB is effectively a drop-in alternative to MySQL and we prefer it because it's not controlled by Oracle and has a more active developer community. On Ubuntu, MariaDB pretends to be MySQL for compatibility purposes, so don't be weirded out by the interchangeable names below. Install the server and the client like this.</p> <p><code>sudo apt-get install mariadb-server-10.0 mariadb-client-10.0</code></p> <p>You need to set a root (admin) user password - you might want to create a /root/.my.cnf file containing the following (replacing YOURPASSWORD) to let you access MariaDB without a password from the commandline<code>:</code></p> <p><code>[client]<br /> user=root<br /> password=YOURPASSWORD</code></p> <p>You should now be able to type "mysql" at the command prompt</p> <p>Tweak the configuration so that it's listening on</p> <p><code>sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf </code></p> <p>and copy the bind-address line and adjust so it looks like this - we want MariaDB to be listening on all interfaces, not just localhost (127.0.0.1)...</p> <p><code># Instead of skip-networking the default is now to listen only on<br /> # localhost which is more compatible and is not less secure.<br /> #bind-address           = 127.0.0.1<br /> bind-address            = 0.0.0.0</code></p> <p>Then restart MariaDB:</p> <p><code>sudo service mysql restart</code></p> <p>It should now be listening on port 3306 on all interfaces, i.e. 0.0.0.0.</p> <p>Now set up the database which will hold NextCloud's data. Log into the MySQL client on the host (if you've created a .my.cnf file in your home directory as describe above, you won't need to enter your username and password):</p> <p><code>mysql -u root -p</code></p> <p>Enter your root password when prompted. It's also a good idea to gin up a password for your "nextcloud" database user. I usually use pwgen (<code>sudo apt-get install pwgen</code>) - for example running this command will give you a single 12 character password without special characters (just numbers and letters):</p> <p><code>pwgen -s 12 1<br /> T7KR2osrMkyC</code></p> <p>At the prompt (which will look something like MariaDB [(none)]&gt;) enter the following lines (putting your password in place of [passwd]):</p> <p><code>CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;<br /> CREATE USER "nextcloud"@"%" IDENTIFIED BY "[passwd]";<br /> GRANT ALL ON nextcloud.* to "nextcloud"@"%";<br /> FLUSH PRIVILEGES;</code></p> <p>Then enter \q to exit.</p> <h2>NextCloud and Collabora Office with Docker</h2> <p>We make use of the NextCloud community's <a href="https://hub.docker.com/_/nextcloud/" title="Documentation for the reference NextCloud Docker container.">stable Docker container</a> which they keep up to date. Similarly, the Collabora community has created a <a href="https://hub.docker.com/collabora/code">reference Docker container</a>.</p> <p>The over all architecture consists of five Docker containers (note, done properly, you aim to ensure that each container runs only one service!):</p> <ol><li>the main NextCloud container (running the PHP-FPM service)</li> <li>an identical container to the PHP one which runs the cron service (which does periodic administrative tasks relevant to NextCloud)</li> <li>the self-contained Collabora Office container (running PHP with an Apache web server instance and a full instance of LibreOffice running in headless server mode (never fear, no servers were harmed in the building of this server!) - yes this server doesn't really adhere to the "one-service per container" convention, but I'm ok with that. It's just a convention after all.)</li> <li>a Redis container (which provides performance improving caching for NextCloud), and</li> <li>an Nginx webserver container which makes it easier to manage the configuration and paths of the NextCloud and Collabora servers via WOPI. It means that on the hosting server, we only need to run a proxying web server, which is easy.</li> </ol><p>The way I prefer to implement this set of containers is to use <a href="https://docs.docker.com/compose/">Docker Compose</a> (after first setting up <a href="https://docs.docker.com/install/linux/docker-ce/ubuntu/">Docker support</a> on your server - I'll assume you've followed the complete instructions including <a href="https://docs.docker.com/install/linux/linux-postinstall/">setting up Docker for your non-root user</a>). I suggest using the latest <a href="https://docs.docker.com/compose/install/#install-compose">installation instructions</a> provided by the Docker community. To be honest, I usually use the alternative instructions, <a href="https://docs.docker.com/compose/install/#install-using-pip">employing the "pip" approach</a>. You can upgrade an existing install by issuing (on your Linux VM's command line):</p> <p><code>sudo pip install -U docker-compose </code></p> <p>To set up your server, I recommend setting up a place for your Docker containers (replace "me" with your non-root username on the server) and the associated persistent data (your Docker containers should hold <em>no</em> important data - you should be able to delete and recreate them entirely without losing any important data or configuration):</p> <p><code>sudo mkdir /home/data</code><br /><code>sudo mkdir /home/data/nextcloud</code><br /><code>sudo mkdir /home/data/nextcloud/apps<br /> sudo mkdir /home/data/nextcloud/config<br /> sudo mkdir /home/data/nextcloud/data<br /> sudo mkdir /home/data/nextcloud/redis<br /> sudo mkdir /home/data/nextcloud/resources<br /> sudo mkdir /home/docker<br /> sudo mkdir /home/docker/nextcloud-collabora<br /> sudo chown -R me:me /home/docker<br /> cd /home/docker/nextcloud-collabora</code></p> <p>Here's an example of the required docker-compose.yml file (you can create this via a text editor like "nano" which should be pre-installed on any VM these days, or use my preferred, but less intuitive, editor, vim via <code>vim docker-compose.yml</code> in the /home/docker/nextcloud-collabora directory):</p> <p><code>version: '2'<br /> networks:<br />   back:<br />     driver: bridge<br /> services:<br />   web:<br />     image: nginx<br />     ports:<br />       - 127.0.0.1:8082:80<br />     volumes:<br />       - ./nginx.conf:/etc/nginx/nginx.conf:ro<br />     links:<br />       - app<br />     volumes_from:<br />       - app<br />     environment:<br />       - VIRTUAL_HOST<br />     networks:<br />     - back<br />     restart: unless-stopped      <br />   app:<br />     image: nextcloud:12-fpm<br />     links:<br />       - redis<br />     volumes:<br />       - /home/data/nextcloud/apps:/var/www/html/apps<br />       - /home/data/nextcloud/config:/var/www/html/config<br />       - /home/data/nextcloud/resources:/var/www/html/resources<br />       - /home/data/nextcloud/data:/var/www/html/data<br />     networks:<br />     - back<br />     restart: unless-stopped      <br />   cron:<br />     image: nextcloud:12-fpm<br />     volumes_from:<br />       - app<br />     user: www-data<br />     entrypoint: |<br />       bash -c 'bash -s &lt;&lt;EOF<br />       trap "break;exit" SIGHUP SIGINT SIGTERM<br />       while /bin/true; do<br />         /usr/local/bin/php /var/www/html/cron.php<br />         sleep 900<br />       done<br />       EOF'<br />     networks:<br />       - back<br />     restart: unless-stopped      <br />   redis:<br />     image: redis:alpine<br />     volumes:<br />       - /home/data/nextcloud/redis:/data<br />     networks:<br />       - back<br />     restart: unless-stopped<br />   collab:<br />     image: collabora/code<br />     environment:</code><br /><code>      # put the domain name you select for your NextCloud instance<br />       # here! Escape any . in your domain name by preceding them with \\<br />       domain: your\\.domain\\.tld<br />       username: admin</code><br /><code>      # put your own strong password in here!<br />       password: some-good-password<br />     cap_add:<br />       - MKNOD<br />     networks:<br />       - back<br />     volumes_from:<br />       - app<br />     ports:<br />       - 127.0.0.1:9980:9980<br />     links:<br />       - app<br />     restart: unless-stopped</code></p> <p>You'll need to substitute the domain name you pick for your NextCloud instance - Collabora's container requires that you specify it so that it doesn't accept connections from other (potentially nefarious) containers elsewhere on the Internet!</p> <p>Also note, the "ports" specified above, 8082 for <code>nginx</code> and 9980 for <code>collab</code> are arbitrary - I picked these to ensure they don't conflict with ports being used by other containers on my server - you can use these if you want, or use <code>sudo netstat -punta</code> to see what ports are currently claimed by other services on your server (if there are any) and pick ones that don't clash! If it scroll past too fast, you can pipe it into less to allow you to scroll and search: <code>sudo netstat -punta | less</code> - hit "q" to exit or "/" to initiate a text search.</p> <p>You will also need to provide the "nginx.conf" file referenced in the nginx section of the file. Do that by using your editor, e.g. <code>vim nginx.conf</code>, and enter this content:</p> <p><code>user www-data;</code></p> <p><code>events {<br />   worker_connections 768;<br /> }</code></p> <p><code>http {<br />   upstream backend {</code><br /><code>      # if you don't call your NextCloud server "app" in your<br />       # docker-compose.yml, you'll need to change app below to </code><br /><code>      # whatever you end up calling it.<br />       server app:9000;<br />   }<br />   include /etc/nginx/mime.types;<br />   default_type application/octet-stream;</code></p> <p><code>  server {<br />     listen 80;<br />     <br />     # Add headers to serve security related headers<br />     add_header X-Content-Type-Options nosniff;<br />     add_header X-Frame-Options "SAMEORIGIN";<br />     add_header X-XSS-Protection "1; mode=block";<br />     add_header X-Robots-Tag none;<br />     add_header X-Download-Options noopen;<br />     add_header X-Permitted-Cross-Domain-Policies none;</code></p> <p><code>    root /var/www/html;</code></p> <p><code>    location = /robots.txt {<br />       allow all;<br />       log_not_found off;<br />       access_log off;<br />     }</code></p> <p><code>    location = /.well-known/carddav {<br />       return 301 $scheme://$host/remote.php/dav;<br />     }<br />     location = /.well-known/caldav {<br />       return 301 $scheme://$host/remote.php/dav;<br />     }</code></p> <p><code>    client_max_body_size 1G;<br />     fastcgi_buffers 64 4K;</code></p> <p><code>    gzip off;</code></p> <p><code>    index index.php;<br />     error_page 403 /core/templates/403.php;<br />     error_page 404 /core/templates/404.php;<br />  <br />     location / {<br />         rewrite ^ /index.php$uri;<br />     }</code></p> <p><code>    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {<br />         deny all;<br />     }<br />     location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {<br />         deny all;<br />     }</code></p> <p><code>    location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+|core/templates/40[34])\.php(?:$|/) {<br />         include fastcgi_params;<br />         fastcgi_split_path_info ^(.+\.php)(/.*)$;<br />         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;<br />         fastcgi_param PATH_INFO $fastcgi_path_info;<br />         fastcgi_param HTTPS on;<br />         #Avoid sending the security headers twice<br />         fastcgi_param modHeadersAvailable true;<br />         fastcgi_param front_controller_active true;<br />         fastcgi_pass backend;<br />         fastcgi_intercept_errors on;<br />         fastcgi_request_buffering off;<br />     }</code></p> <p><code>    location ~ ^/(?:updater|ocs-provider)(?:$|/) {<br />         try_files $uri/ =404;<br />         index index.php;<br />     }</code></p> <p><code>    # Adding the cache control header for js and css files<br />     # Make sure it is BELOW the PHP block<br />     location ~* \.(?:css|js)$ {<br />         try_files $uri /index.php$uri$is_args$args;<br />         add_header Cache-Control "public, max-age=7200";<br />         # Add headers to serve security related headers (It is intended to<br />         # have those duplicated to the ones above)<br />         # Before enabling Strict-Transport-Security headers please read into<br />         # this topic first.<br />         # add_header Strict-Transport-Security "max-age=15768000;<br />         #  includeSubDomains; preload;";<br />         add_header X-Content-Type-Options nosniff;<br />         add_header X-Frame-Options "SAMEORIGIN";<br />         add_header X-XSS-Protection "1; mode=block";<br />         add_header X-Robots-Tag none;<br />         add_header X-Download-Options noopen;<br />         add_header X-Permitted-Cross-Domain-Policies none;<br />         # Optional: Don't log access to assets<br />         access_log off;<br />     }</code></p> <p><code>    location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ {<br />         try_files $uri /index.php$uri$is_args$args;<br />         # Optional: Don't log access to other assets<br />         access_log off;<br />     }<br />   }<br /> }</code></p> <p>That should be all the configuration you need to make the Docker containers go.</p> <h2>Configuring Nginx to proxy NextCloud and Collabora</h2> <p>The next step is configuring the local nginx proxy servers for NextCloud and Collabora using the nginx instance you installed earlier. That's what responds to the domain name you choose for this service. In our case, the name is <a href="https://docs.oeru.org">https://docs.oeru.org</a> - you can have a look at it to see what you should be seeing when you first start things up! We use <a href="https://letsencrypt.org" title="This is an incredible free and open source service, that is single-handedly making the web a much safer place.">Let's Encrypt</a> to provide secure hosting - <a href="/protecting-your-users-lets-encrypt-ssl-certs">here're my Let's Encrypt instructions</a> on setting it up. The key thing to realise is that your "certificates" need to exist for Nginx to restart with the new configurations below - use the "commenting out the intervening lines" trick mentioned in my instructions to bootstrap the creation of your secure certificates!</p> <p>To configure the proxies, you need to create two configuration files in your /etc/nginx/sites-available/ directory.</p> <h3>NextCloud Proxy Configuration</h3> <p>Create a file with a meaningful name for your NextCloud Proxy, perhaps based on the domain name you've chosen (our file for docs.oeru.org is called "docs") using the same editing approach as the last few (although this is in a different directory) for example <code>sudo vim /etc/nginx/sites-available/docs</code> with the following contents, replacing "nextcloud.domain" with your selected domain name (and the port number 8082 if you've opted to change to a different one!):</p> <p><code>server {<br />     listen 80;<br />     server_name nextcloud.domain;</code></p> <p><code>    include /etc/nginx/includes/letsencrypt.conf;</code></p> <p><code>    # redirect all HTTP traffic to HTTPS.<br />     location / {<br />         return  302 https://nextcloud.domain$request_uri;<br />     }<br /> }</code></p> <p><code># This configuration assumes that there's an nginx container talking to the mautic PHP-fpm container,<br /> # and this is a reverse proxy for that Mautic instance.<br /> server {<br />     listen 443 ssl;<br />     server_name nextcloud.domain;</code></p> <p><code>    ssl_certificate /etc/letsencrypt/live/nextcloud.domain/fullchain.pem;<br />     ssl_certificate_key /etc/letsencrypt/live/nextcloud.domain/privkey.pem;<br />     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;<br />     # to create this, see https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html<br />     ssl_dhparam /etc/ssl/certs/dhparam.pem;<br />     keepalive_timeout 20s;</code></p> <p><code>    include /etc/nginx/includes/letsencrypt.conf;<br />    <br />     location ^~ / {<br />         proxy_pass http://localhost:8082;<br />         proxy_set_header Upgrade $http_upgrade;<br />         proxy_set_header Connection "Upgrade";<br />         proxy_set_header Host $http_host;<br />         proxy_read_timeout 36000s;<br />     }<br />     client_max_body_size 1G;<br />     fastcgi_buffers 64 4K;</code></p> <p><code>    add_header X-Frame-Options "SAMEORIGIN";<br />     add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";<br /> }</code></p> <h3>Collab Proxy Configuration</h3> <p>Now create a collabora proxy configuration.</p> <p>Note: This will probably never by used by any user directly (there is a resource analysis service on the collabora system that might be of interest) - instead it'll be referenced by the NextCloud instance transparently to your users. </p> <p>In our case, we chose the domain collab.oeru.org and the file is called "collab", created via <code>sudo vim /etc/nginx/sites-available/collab</code> and containing (replace collab.domain with the one you've selected - similarly replace the port number 9980 with whatever you've selected if you've opted for a different one!):</p> <p><code>server {<br />     listen 80;<br />     server_name collab.domain;</code></p> <p><code>    # for let's encrypt renewals!<br />     include /etc/nginx/includes/letsencrypt.conf;</code></p> <p><code>    # redirect all HTTP traffic to HTTPS.<br />     location / {<br />         return  302 https://collab.domain$request_uri;<br />     }<br /> }</code></p> <p><code>server {<br />     listen 443 ssl;<br />     server_name collab.domain;</code></p> <p><code>    ssl_certificate /etc/letsencrypt/live/collab.domain/fullchain.pem;<br />     ssl_certificate_key /etc/letsencrypt/live/collab.domain/privkey.pem;<br />     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;<br />     # to create this, see https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html<br />     ssl_dhparam /etc/ssl/certs/dhparam.pem;<br />     keepalive_timeout 20s;</code></p> <p><code>    # for let's encrypt renewals!<br />     include /etc/nginx/includes/letsencrypt.conf;</code></p> <p><code>    proxy_http_version 1.1;<br />     proxy_buffering off;</code></p> <p><code>    # static files<br />     location ^~ /loleaflet {<br />         proxy_pass https://localhost:9980;<br />         proxy_set_header Host $http_host;<br />     }</code></p> <p><code>    # WOPI discovery URL<br />     location ^~ /hosting/discovery {<br />         proxy_pass https://localhost:9980;<br />         proxy_set_header Host $http_host;<br />     }</code><br /><br /><code>    # download, presentation and image upload<br />     location ^~ /lool {<br />         proxy_pass https://localhost:9980;<br />         proxy_set_header Upgrade $http_upgrade;<br />         proxy_set_header Conection "upgrade";<br />         proxy_set_header Host $http_host;<br />     }<br /> }</code></p> <p>Once those are created, you have to make sure that they're "enabled" (replacing with your file names, of course):</p> <p><code>sudo cd /etc/nginx/sites-enabled<br /> sudo ln -sf ../sites-available/docs .<br /> sudo ln -sf ../sites-available/collab .</code></p> <p>To confirm that there aren't any typos or issues that might make nginx unhappy, run</p> <p><code>sudo nginx -t</code></p> <p>If all's well, get nginx to reread its configuration with the new files:</p> <p><code>sudo service nginx reload</code></p> <h2>Firing it all up!</h2> <p>Phew - congratulations on getting here! We've reached the moment of truth where we need to see if this whole thing will work!</p> <p>We need to make sure we're back in the Docker directory we set up:</p> <p><code>cd /home/docker/nextcloud-collabora</code></p> <p>and then we need to try running our docker-compose script to "pull" in the pre-built Docker containers we've specified in our docker-compose.yml file:</p> <p><code>docker-compose pull</code></p> <p>All going well, after a few minutes (longer or shorter depending on the speed of your server's connection) you should have download the Nginx, Redis, NextCloud and Collabora-CODE Docker images. Then you can run:</p> <p><code>docker-compose up -d &amp;&amp; docker-compose logs -f</code></p> <p>This will attempt to start up the containers (bringing them "up" in daemon mode, thus the -d) and then show you a stream of log messages from the containers, preceded by the container name. This should help you debug any problems that occur during the process (ideally, none).</p> <p>Once you see log messages streaming past, and no obvious "container exited" or other error messages (which will usually contain the word "error" a lot), you should be able to point your browser at your selected domain name and bring it up in your browser!</p> <h3>Setting up the database</h3> <p>On doing so, if all is well, you should be directed through the database set up process for your NextCloud instance. Your details should be:</p> <p>database IP: 172.17.0.1 - this is the default IP of the Docker host server.<br /> database name: nextcloud<br /> database user: nextcloud<br /> database password: (the one you came up with above)</p> <h3>Setting the Admin user</h3> <p>Once that's set and working, NextCloud will install all the relevant database tables and initial data. You'll be asked to set up an <em>admin user</em> account, which can be "admin" (you could make it something different to help stymie nefarious probes that assume you've got a user called "admin" - but don't forget what you've called it!) and some strong password you create (you can use the pwgen utility you used earlier) - I'd recommend recording it somewhere. I would <em>not</em> recommend making your own account, in your name, the main admin account. I recommend creating a second account, <em>with administrator privileges</em> for yourself, but leave the admin account purely for administrative activities.</p> <h3>Configuring Outgoing Email</h3> <p>To allow your NextCloud instance to send outgoing email, so that your site can alert you to security updates that need to be applied, or so that users can request a replacement password if they've forgot theirs, you'll need an <em>authenticating SMTP account</em> somewhere. Most of you already have one. You'll probably want to set up a dedicated email address for this server somewhere, perhaps something like "<a href="mailto:nextcloud@your.domain">nextcloud@your.domain</a>" or similar, with a username (often just the email address) and a password. You'll need the following details:</p> <p>SMTP server : an IP address or a domain name<br /> SMTP username: a username or an email address<br /> SMTP password: a strong password already configured for the username on that server<br /> SMTP login security: whether login is via TLS, SSL, or unsecure (!!), and<br /> SMTP login method: plain, encrypted, "login" or some other value.</p> <p>You should be able to test your email settings to make sure the details you've entered are valid. If you need to adjust these settings later, you can go to the admin menu (top right of the web browser interface) and go to Admin-&gt;Additional Settings  - should have a path of <a href="https://your.domain/settings/admin/additional">https://your.domain/settings/admin/additional</a></p> <h3>Configuring Collabora Office Integration</h3> <p>Once you're logged in as your own user, looking at your own default folders, you can start having a look around. You should have an "admin" menu (assuming you've created your user with Administrator privileges) at the top right of the web interface. If you go to Apps, you can use the search box to search for "Collabora" or go to the "Office &amp; text" App category. You'll need to "enable" the Collabora Online "official" app, at which point it will download the latest version of the connector app and install it (it should appear in your /home/data/nextcloud/apps directory)</p> <p>Once you've done that, go to your top right menu again, selecting Admin, and you should see "Collabora Online" as an option in the left column (which starts with "Basic settings"). Selecting that, you'll need to enter  "<a href="https://collab.domain">https://collab.domain</a>" (replacing with your domain, of course). I don't have any of the other options ticked.</p> <p>If it works, you should have the ability to go back to the home of your NextCloud install, which should show you your top-level folders. If you click the "+" next to the home icon (top left of the folder pane) you should now have the option to create (in addition to "Upload file", "New folder", "New text file") a "New Document", "New Spreadsheet", and "New Presentation". Clicking those should give you the Collabora Office interface for the designated content type.</p> <p>Similarly, you can use the "Upload file" to upload a document in a format that is supported by Collabora Office, once uploaded clicking on the filename should open it for editing in the appropriate Collabora Office interface.</p> <p>It is saved as it is change, you shouldn't need to save it explicitly.</p> <h2>Upgrading it</h2> <p>So, as you're no doubt aware, both NextCloud and Collabora Office are always being improved and updated. I certainly encourage you to keep your installation up-to-date.</p> <p>While you'll periodically see that NextCloud apps have available updates (these can be upgraded through the browser interface) updates to the NextCloud and Collabora Office systems themselves need to be undertaken by upgrading the containers. Luckily it's easy to do (although I strongly urge you to ensure you have a very recent backup of both database and uploaded files - they're the files in /home/data/nextcloud/data:</p> <p>Updating the container should be as easy as either doing another</p> <p><code>docker pull oeru/mautic</code></p> <p>and then shutting down Docker container via a</p> <p><code>docker-compose stop</code></p> <p>removing the old containers (this won't remove any data you want to save if you followed the directions above! But remember to do it in the right directory!) via</p> <p><code>docker-compose rm -v</code></p> <p>and then restarting it via</p> <p><code>docker-compose up -d</code></p> <p>Use <code>docker-compose logs -f</code> to watch the logs - you'll likely see debugging information in the unlikely event that something goes wrong in the upgrade process.</p> <h2>Backing it up</h2> <p>To back up your instance on your server, you need two things: a file system backup of your /home/data/nextcloud directory, and database dumps of your database.</p> <p>There're lots of ways to back up your files (I personally use a bash script that I wrote in a past role, which uses <a href="http://www.nongnu.org/rdiff-backup/">rdiff-backup</a> to create versioned backups either locally or on a remote server, although there're <a href="https://www.howtoforge.com/linux_rdiff_backup">other documented approaches</a> - leave a comment below if you'd like to learn more about my approach!).</p> <p>Backing up your database is as easy installing automysqlbackups:</p> <p><code>sudo apt install automysqlbackups</code></p> <p>You'll find daily versioned dumps of your MariaDB database(s) in /var/lib/automysqlbackups. To run an ad hoc backup (which will replace the previous backup from that day, if there is one) just run</p> <p><code>sudo automysqlbackups</code></p> <h2>Collabora Admin Console</h2> <p>Once you've got everything set up, you can access the admin console of the Collabora Office instance at the collab.domain you specified above - it'll have the path <code>https://collab.domain/loleaflet/dist/admin/admin.html</code> (of course replacing collab.domain with your domain) which gives you useful info about the system resources being used, number of documents being edited and by whom, and some other interesting details. I've included a screen shot.</p> <p>When prompted for login details, use the collab username - "admin" if you used the default I provided, and the password you set in your docker-compose.yml file above.</p> </div> </div> </div> <section class="field field-node--field-blog-comments field-name-field-blog-comments field-type-comment field-label-above comment-wrapper"> <a name="comments"></a> <h2 class="comment-field__title">Blog comments</h2> <article data-comment-user-id="0" id="comment-820" class="comment js-comment by-anonymous has-title clearfix"> <div class="comment__container"> <h3 class="comment__title"> <a href="/comment/820#comment-820" class="permalink" rel="bookmark" hreflang="en">All I get after all of that…</a> <span class="comment__new marker marker--success hidden" data-comment-timestamp="1636139893"></span> </h3> <div class="comment__meta"> <div class="comment__submitted"> <span class="comment__author"><span>Tim (not verified)</span></span> <span class="comment__pubdate">Sat 06/11/2021 - 04:21</span> </div> </div> <div class="comment__content"> <div class="clearfix text-formatted field field-comment--comment-body field-name-comment-body field-type-text-long field-label-hidden"> <div class="field__items"> <div class="field__item"><p>All I get after all of that is &quot;OK&quot;</p> </div> </div> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=820&amp;1=default&amp;2=en&amp;3=" token="9x_0sEHuh-dJwj9sa5I_pygyooUxR3CerM32QzLc50E"></drupal-render-placeholder> </div> </div> </article> <article data-comment-user-id="1" id="comment-821" class="comment js-comment by-node-author has-title clearfix"> <div class="comment__container"> <h3 class="comment__title"> <a href="/comment/821#comment-821" class="permalink" rel="bookmark" hreflang="en">Sorry Tim, after all what?</a> <span class="comment__new marker marker--success hidden" data-comment-timestamp="1636155192"></span> </h3> <div class="comment__meta"> <div class="comment__submitted"> <span class="comment__author"><a title="View user profile." href="/user/1" class="username">dave</a></span> <span class="comment__pubdate">Sat 06/11/2021 - 08:18</span> </div> </div> <div class="comment__content"> <div class="clearfix text-formatted field field-comment--comment-body field-name-comment-body field-type-text-long field-label-hidden"> <div class="field__items"> <div class="field__item"><p>Sorry Tim, after all what? I'd love to provide assistance, but need you to be a bit more specific.</p></div> </div> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=821&amp;1=default&amp;2=en&amp;3=" token="RxxscuNlrNd_TL-Wh6nh4yeQjDHOY5TxdqhEDyLKN6E"></drupal-render-placeholder> </div> </div> </article> <div class="comment-form-wrapper"> <h2 class="comment-form__title">Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=17&amp;2=field_blog_comments&amp;3=comment" token="aF_f2aYW3SGRfmrsffb5fOJlN5wEXJibvMUiQKm2VjE"></drupal-render-placeholder> </div> </section> Mon, 29 Jan 2018 04:29:13 +0000 dave 17 at http://tech.oeru.org