A self hosted cloud is something which is interesting for a lot of people nowadays. Whether it be that they don’t like to share their data with a big company or for learning effects just to name a few reasons.

In this article we take a look at SeaFile which is a open source cloud software solution. To get a more modern touch, we will also integrate OnlyOffice into SeaFile. This will allow us to do collaboration office document editing, including docx, pptx and xlsx files (Microsoft Office). Don’t be afraid because of the length of this article. If you’re already more familiar with techniques like SeaFile, Docker and OnlyOffice you can easily skip to the chapters where it start to be interesting for you.

Why SeaFile and not NextCloud?

I’ve decided to go with SeaFile instead of NextCloud about a year ago. The simple reason was speed! SeaFile is amazingly fast in synchronization. Even if you have thousands of little files, they all will be synced fast.

Another big reason to go with SeaFile is delta synchronization. Delta synchronization basically means that SeaFile is able to determine which part of your file has beed changed and is then only uploading the changed part of this file. This mechanism comes hand in hand with the overall synchronization speed, too. SeaFile does also offer end-to-end encryption. This means you can encrypt your files locally and upload them to the server. This makes the files unreadable for third parties.

If you want to extend your Cloud with things like contact and calendar synchronization, then NextCloud might be the better choice for you as there is no option to integrate such things in SeaFile. SeaFile is a pure cloud solution for files, but it is doing this one key feature almost perfect.

Requirements

First of all, I assume that you have already Docker installed on your server system. If not, check out the manual from Docker here: official Docker installation instructions. Your (server) system should have at least 4GB of RAM and 5 GB of free hard disk space in order to install the needed container files. In addition to these 5 GB you need the desired amount of free hard disk space for your files to be stored.

If you don’t have a server or system at home which you can use, you can try a hosted server at one of the many providers out there. I can recommend Netcup as a provider. You can find their offers here: netcup VPS. You can also use one of the following codes at the checkout. These codes are 5€ vouchers for new customers at netcup:

  • 36nc15574364944
  • 36nc15574364943
  • 36nc15574364942
  • 36nc15574364941
  • 36nc15574364940

Hint: These vouchers are part of a affiliate system which means a get a small portion as a reward.

Create a Docker network

The first step we do is to create a Docker network interface. We need a extra interface in order to assign static private IP addresses to the containers. Why we need static IP addresses anyway? This will be explained later on in this how to.

The following command creates a new Docker network interface which will be named “cloud” with a maximum of 253 usable IP addresses:

user@server:~$ sudo docker network create --subnet=192.168.20.0/24 cloud

The IP addresses within this network are going from 192.168.20.1 to 192.168.20.254. The first address is being used by the Docker host itself (in this example 192.168.20.1). We could cut down the usable addresses even more but for easiness, let’s stick with this solution right now.

Setup the SeaFile Docker container

Now that we have created a dedicated Docker network we can start to create the SeaFile Docker container. In order to store the database as well as the client files on the Docker host, we have to create a folder which we then mount in the container. In this example I’ve decided to store all the SeaFile related files on /srv/seafile on the host system. So we have to create this directory first:

user@server:~$ sudo mkdir /srv/seafile

As next we can finally create the Docker container. The following command creates a SeaFile Docker container with the latest version available detached (-d switch). The rest of the parameters are explained below:

user@server:~$ sudo docker run -d --name seafile --net cloud --ip 192.168.20.2 -e SEAFILE_SERVER_LETSENCRYPT=true -e SEAFILE_SERVER_HOSTNAME=cloud.myserver.com -e SEAFILE_ADMIN_EMAIL=me@mymail.com -e SEAFILE_ADMIN_PASSWORD='MyPW' -v /srv/seafile:/shared -p 80:80 -p 443:443 seafileltd/seafile:latest
The parameters in detail
  • –name: The name of the container. In this example the container will be called seafile.
  • –net: The network were the container will be attached to. We use the previously created cloud network here.
  • –ip: The fixed IP address within the cloud network.
  • -e SEAFILE_SERVER_LETSENCRYPT: This is a parameter which will be bypassed to the containers setup script (which runs the first time when you create a new container). It tells the container that SSL encryption (HTTPS) will be enabled and we want to get a free certificate from Let’s Encrypt. Keep in mind that the DNS resolution must work in order to get a valid Let’s Encrypt certificate! This certificate will be valid 90 days. To extend it, simply recreate the container (look at the section Extend Let’s Encrypt certificate below to find out more).
  • -e SEAFILE_SERVER_HOSTNAME: Also a parameter which is bypassed to the setup script. Sets the actual wanted hostname within the SeaFile Docker container.
  • -e SEAFILE_ADMIN_EMAIL: Another setup parameter. Sets the the mail address of the SeaFile administrator. This will also be the login for you when the container is up and running.
  • -e SEAFILE_ADMIN_PASSWORD: The password of the SeaFile administrator.
  • -v /srv/seafile:/shared: We mount the previously created directory /srv/seafile on the host system in /shared within the Docker container. If we wouldn’t mount /shared, all files would be gone after restarting or recreating the SeaFile container.
  • -p 80:80 and -p 443:443: We make the SeaFile container accessible from the world wide web over Port 443 and 80 which are the standard ports for HTTP and HTTPS. However, all unencrypted HTTP traffic will be automatically redirect to the encrypted way over Port 443 (HTTPS).
  • seafileltd/seafile:latest: This downloads the latest version of the SeaFile server from the official Docker Hub. Docker Hub is basically the package manager of Docker.

Don’t forget to adjust the parameters according to your needs. After a few minutes, your SeaFile installation will be ready to use. You can access it with your public domain or IP address, for e.g. https://cloud.myserver.com.

Setup the OnlyOffice Docker container

Now that SeaFile is running and accessible, we can make OnlyOffice ready for usage, too. As already stated, OnlyOffice is a editor for most of the Microsoft Office document formats including docx, pptx and xlsx. It’s open source and free to use. Before we start, we will create a directory where OnlyOffice can store it’s cache and other database related files. We will later mount that directory within the OnlyOffice Docker container just like we did with SeaFile:

user@server:~$ sudo mkdir /srv/onlyoffice
Install certbot and obtain a Let’s encrypt certificate

We’ve already secured SeaFile with the help of a Let’s encrypt certificate. Thus it’s just consequent to secure OnlyOffice with Let’s Encrypt as well. To do so we need a little tool which is called certbot. It does all the work for us. If you’re running a Ubuntu server version 18.04 or higher, you can easily install it like this:

user@server:~$ sudo apt install certbot

If you’re a Debian user, you have to use Backports in Debian 9 in order to install certbot. To enable backports in Debian 9, create a new file under the directory /etc/apt/sources.list.d/ named backports.list with the following content:

deb http://deb.debian.org/debian stretch-backports main contrib non-free

Save and close the file. Now we can install certbot as well:

user@server:~$ sudo apt update && sudo apt install -t stretch-backports certbot

Now that we have certbot installed, we can get another certificate. Warning: Don’t use the same domain name which you already used in SeaFile here! Otherwise your SeaFile certificate will be invalidated. The easiest way is to use another subdomain like office.myserver.com:

user@server:~$ certbot certonly --standalone -d office.myserver.com

Just like with SeaFile, ensure that the subdomain you’re using is pointing to the public IP address of your server. Otherwise you won’t get a certificate and certbot will return an error. If the process was successful, the certificate will be valid 90 days and you can find it under /etc/letsencrypt/live/office.myserver.com/cert.pem.

These files have to be copied so that the OnlyOffice container is later able to read them. We also have to extended the certificate with the Let’s Encryt chain. Otherwise SeaFile will not be able to validate the certificate later on which results in errors when opening documents with OnlyOffice:

user@server:~$ sudo cp /etc/letsencrypt/live/office.myserver.com/cert.pem /mnt/onlyoffice/data/certs/onlyoffice.crt
user@server:~$ sudo cp /etc/letsencrypt/live/office.myserver.com/privkey.pem /mnt/onlyoffice/data/certs/onlyoffice.key
user@server:~$ wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
user@server:~$ sudo sh -c "cat lets-encrypt-x3-cross-signed.pem.txt >> /mnt/onlyoffice/data/certs/onlyoffice.crt"
user@server:~$ rm lets-encrypt-x3-cross-signed.pem.txt
Setup OnlyOffice

We’re now finally able to start OnlyOffice. For this use the following command (the parameters are explained below again):

user@server:~$ sudo docker run -i -t -d -p 8443:443 --name onlyoffice --net cloud --ip 192.168.20.3 --add-host cloud.myserver.com:192.168.20.2 -v /srv/onlyoffice/logs:/var/log/onlyoffice -v /srv/onlyoffice/data:/var/www/onlyoffice/Data onlyoffice/documentserver:latest
The parameters in detail
  • -p 8443:443: We make OnlyOffice accessible over port 8443 from connections over the world wide web. You don’t have to use the port 8443 but a higher, more uncommon port is recommended. It’s something like a additional “security factor”. Higher, more unusual port numbers are more likely not be considered by bots.
  • –net and –ip: Again we use the dedicated cloud Docker network and set a fixed IP address.
  • –add-host: This is a key parameter here. We are using OnlyOffice and SeaFile on a single host system. This means that OnlyOffice has to be able to contact SeaFile over port 9000. By default, that’s not possible. As a workaround (which is also more secure than allow SeaFile to communicate over port 9000 with the world wide web) we use this parameter to add an entry to the /etc/hosts file on the OnlyOffice container. This entry is pointing cloud.myserver.com to the internal Docker IP address.
  • -v: Same as with the creation of the SeaFile container. Files like logs will be stored there. This also contains the certificates we’ve created the step before.
  • onlyoffice/documentserver:latest: Like with the SeaFile container creation, we use the latest OnlyOffice documentserver version available at the Docker Hub.

After a few minutes, the OnlyOffice instance should be ready to use. You can check this if you visit the IP address or the domain name of your instance / server. For e.g. https://office.myserver.com:8443. If you see Document Server is running, you’re good to go.

Get SeaFile and OnlyOffice to work together

Now that SeaFile and OnlyOffice are running we have to link them in order to get them working together. To do so, we have to tell SeaFile how our OnlyOffice instance can be reached. So open the file /srv/seafile/seafile/conf/seahub_settings.py on your docker host and add the following lines at the end of this file:

ENABLE_ONLYOFFICE = True
VERIFY_ONLYOFFICE_CERTIFICATE = False
ONLYOFFICE_APIJS_URL = 'https://office.myserver.com:8443/web-apps/apps/api/documents/api.js'
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods')
ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')

You have to edit the ONLYOFFICE_APIJS_URL to the actual URL of your OnlyOffice instance. Save and close the file. Even we force SeaFile to not verify the OnlyOffice certificate (parameter VERIFY_ONLYOFFICE_CERTIFICATE = False) it does check the certificate anyways. Thus we have added the complete Let’s Encrypt chain a few steps before.

That’s already it. Restart the two containers and you should be able to create / modify documents in SeaFile:

user@docker:~$ sudo docker stop onlyoffice
user@docker:~$ sudo docker stop seafile
user@docker:~$ sudo docker start onlyoffice
user@docker:~$ sudo docker start seafile
Lack of security token support in SeaFile

Security is really important these days. While SeaFile only works if you logged yourself in, OnlyOffice has implemented another approach. The so called “security token”. A security token is used by the cloud software solution (like NextCloud or Seafile) to authenticate against the OnlyOffice instance.

While NextCloud does support this security token mechanism, sadly SeaFile doesn’t. In addition to this you can’t simply use a firewall to block all traffic from outside to your OnlyOffice instance because the client also have to able to communicate with it. Because of this I recommended (as a little bit of blurring) the usage a more uncommon port. I know that this doesn’t have something to do with making something “secure”, however it’s at least something for now. Implementing security token support is on the road map of the SeaFile developers.

For clarification, not using security tokens doesn’t mean everyone can access your files. It just means that everyone who is able to find out the actual address of your OnlyOffice instance can use your instance for editing documents as well.

Updating the containers

Updating the SeaFile as well as the OnlyOffice container is really simple. To do so, stop the container, delete it and recreate it. The already explained latest tag at the end of the image name makes sure that you always pull the latest stable version available. So for example to update Onlyoffice:

user@docker:~$ sudo docker stop onlyoffice
user@docker:~$ sudo docker rm onlyoffice
user@docker:~$ sudo docker run -i -t -d -p 8443:443 --name onlyoffice --net cloud --ip 192.168.20.3 --add-host cloud.myserver.com:192.168.20.2 -v /srv/onlyoffice/logs:/var/log/onlyoffice -v /srv/onlyoffice/data:/var/www/onlyoffice/Data onlyoffice/documentserver:latest

Updating SeaFile does look similar:

user@docker:~$ sudo docker stop seafile
user@docker:~$ sudo docker rm seafile
user@docker:~$ sudo docker run -d --name seafile --net cloud --ip 192.168.20.2 -e SEAFILE_SERVER_LETSENCRYPT=true -e SEAFILE_SERVER_HOSTNAME=cloud.myserver.com -e SEAFILE_ADMIN_EMAIL=me@mymail.com -e SEAFILE_ADMIN_PASSWORD='MyPW' -v /srv/seafile:/shared -p 80:80 -p 443:443 seafileltd/seafile:latest

Please keep in mind that you have to modify the docker create command again so that it fits to your initially create command. In order to keep track if there are any updates available, you could write a Cronjob which does the steps above automatically (something I really wouldn’t recommend due to possibly update failures). Or you subscribe to the developers newsletter so that you get notice when a new version is released. Sadly the Docker Hub doesn’t have a functionality in sending mails when an image is being updated (as of May 2019).

Extending Let’s Encrypt certificates

Extending the validity of Let’s Encrypt certificates for SeaFile is really simple. Just recreate the container like you would update the container. SeaFile checks the certificate automatically at the recreation process and extends the validity of the certificate.

For the manually created Let’s Encrypt certificate for OnlyOffice we have to stop the SeaFile container (because this container is using the port 443 and 80 which we need for certbot). Than we simply repeat the commands like the first time we got the certificate. This includes the copy commands as well as adding the Let’s Encrypt chain, too. While renewing the certificate, certbot may asks you if you want to keep the actual certificate or if you want to replace it. This message only pops up if you’re actual certificate isn’t already expired. You can surpass this message with the –force-renew parameter:

user@docker:~$ sudo certbot certonly --force-renew --standalone -d office.myserver.com

You can wrap these steps in a Cronjob of course as well. This would allow you to extend the certificate without even touching your system.

A few words about firewalling

If you’re using a firewall (which I highly recommend) make sure that port 80 and 443 (HTTP / HTTPS) are accessible from the world wide web. Also make sure that the port you’ve set for the OnlyOffice instance is accessible from outside (in this article this port was 8443). The client has to be able to communiate with OnlyOffice, not just the SeaFile server.

SeaFile with OnlyOffice: A great couple

As you can see, thanks to Docker making and maintaining your own, self-hosted cloud is as easy as it never was. However, if you think that it is still to difficult for you to manage such a solution and thus you want to stick to a centralized hosted solution like Dropbox, Google Drive or OneDrive, consider at least to encrypt the files you store at their servers. For your own privacy and security. Solution likes Boxcryptor (free with the basic version) or Cryptomator (open source and free to use) are making it very easy to encrypt your files at cloud providers.

Further links