has_many :codes

Setting up Seafile file sharing and sync with an s3 backend and Collabora Office integration

Published  

For a while I've used a self hosted instance of Nextcloud to sync data between my computers and occasionally share files with others. Nextcloud is super popular: not only can it be cheaper than something like Dropbox - because you can have as many users as you want with your Nextcloud instance being limited only by the storage available and the specs of your server, you are also in control of your data, which is nice (although this also means you need to take care of security, backups and maintenance in general). You can even extend Nextcloud's functionality by installing "apps" from a marketplace that add all sorts of features.

I really like Nextcloud as a concept but not as implementation.  Somehow I have always felt like it's a unpolished product with huge potential. It tries to do too much, and the developers seem to spend most of their time adding half baked features rather than getting the core functionality right. And by core functionality I mainly mean syncing and sharing of data. This has always been a sore point with Nextcloud: it's terribly slow, doesn't handle conflicts well, and seems somewhat unreliable overall. For some people all the other features Nextcloud has to offer may be important, but I only need proper file syncing and basic collaboration features. I don't care about the rest.

For this reason I have been looking for an alternative which I would still be able to self host like Nextcloud, but with a faster and more robust syncing functionality. In most comparisons "Nextcloud vs others" Seafile is often mentioned as a faster and more reliable syncing solution than Nextcloud, so I decided to give it a try and so far I am very impressed! It's indeed much faster than Nextcloud, and I can see what people mean when they say it's more reliable too, because conflicts happen less frequently and usually are sorted out automatically.

This is especially important for me because among the data I share between computers are my code repositories - I like being able to quickly switch from my Mac mini to the MacBook or viceversa, and continue my work without having to push something that I may have not finished yet to Github just to be able to pull from another computer. Nextcloud is just plain terrible at handling git repositories; changing branch often means that many changes occur in many files in a very short amount of time, and Nextcloud just doesn't work well with this and lots of conflicts all the time are typical.

Seafile, on the other hand, is a lot faster and performs syncing of many files in bulk, reducing the amount and frequency of conflicts.  My understanding is that Seafile performs "delta" uploads, meaning that when a file changes it only uploads the parts of the file that have changed, which also contributes to the better speed. One downside with Seafile is that it stores the data in chunks similar to what Git does, so the files cannot be read directly. For some people this may be a deal breaker, I honestly don't care because I consume the data on my computers via syncing, not on the server.

So, if you also are looking for a reliable and fast syncing solution that you can self host and you don't care about anything else, this post may be for you. I will show you how to easily set up Seafile with Docker with two particular requirements in mind: 

  1. we are going to use an s3 compatible storage to store the actual data; by default, Seafile stores the data on the local disk, but depending on the amount of data you want to store in it you may need a server with a lot of storage. An alternative, which I prefer, is to store the data in object storage so I don't need to worry about how much storage I need to have available. I use iDrive e2 for this because it's compatible with the s3 API - so it works with Seafile out of the box, it's super fast (the fastest I have found so far) and incredibly cheap. There is an offer at the moment where 1 whole terabyte of storage costs just $4 for the first year, which is awesome. After that it's only $40/TB/year, which is still the cheapest I have found so far. The pricing is amazing, considering the speed and reliability of the service (I have used it for several months already to store all sorts of data in it, and it has been rock solid)
  2. we don't care about all the bells and whistles that Nextcloud has to offer, but we want at least the basic collaboration features for office documents, like being able to edit documents online in the browser when we can't use our own devices, being able to occasionally collaborate on a document with other people in realtime, and being able to share documents with other people who can preview or download those documents without edit permissions. As we'll see in a bit, we'll use Collabora Online for this. Collabora is an online version of an office suite based on the popular LibreOffice. 

Some caveats with the solution I am offering here:

  1. in order to be able o use s3 with Seafile, we need to use the Pro version, which is free only up to 3 users and then it's a paid product. This is quite different from Nextcloud, which is completely free for an unlimited number of users. I only have exactly 3 users so I don't care, but even if I had more users I would still choose it because it's very cheap anyway - like just $8 per month for up to 9 users, with various pricing tiers beyond that - and because of all the problems I had with Nextcloud.
  2. Collabora Online is not the only office suite we can hook with Seafile. There's also OnlyOffice. OnlyOffice has some advantages like better compatibility with Microsoft Office formats, and the fact that it's lighter on resources on the server, because most of the processing actually happens in the browser, on the client. Collabora has a more limited compatibility with Microsoft formats, so you may occasionally lose some formatting when converting documents from a format to another, and uses more CPU and memory on the server because it's actually an instance of LibreOffice running on the server, behind the scenes. So if you have more than a few users, you'll need a bigger server with Collabora compared to with OnlyOffice. Another advantage with OnlyOffice is that it automatically previews documents in read only mode when they are shared with other people; with Collabora you need an extra component for previews (also based on LibreOffice). However, I had all sort of pains trying to get OnlyOffice working 100% correctly with Seafile, like for example opening a document in the browser does not see a new version of the document uploaded via the desktop client and edited with a desktop office app, so that made it almost unusable for me. Unfortunately the official documentation and Google didn't help much. I was able to get up and running with Collabora more easily so I am using that instead. A benefit of Collabora is that it is more feature rich than OnlyOffice in general. OnlyOffice has some nice desktop apps which you can use instead of the browser and which can also connect to your Seafile or Nextcloud instance to collaborate with other people, so that's nice. With Collabora instead I need to use LibreOffice or similar on my Macs and I can't connect it to my Seafile instance, but it's not a big deal. When I need to collaborate with others (which happens rarely) I just use the browser version which allows that.


Setting up Seafile with Docker Compose

The easiest way to set this up is, as usual these days, with Docker. 

  • Create a docker-compose.yml file somewhere, and paste the following in it:
version: "3.3"

services:
  mariadb:
    image: mariadb:10.5
    container_name: mariadb
    restart: unless-stopped
    ports:
      - "127.0.0.1:3306:3306"
    env_file:
      - ./mariadb.env
    volumes:
      - ./mariadb:/var/lib/mysql

  memcached:
    image: memcached
    container_name: memcached
    restart: unless-stopped

  seafile:
    image: docker.seadrive.org/seafileltd/seafile-pro-mc:latest
    container_name: seafile
    restart: unless-stopped
    ports:
      - 127.0.0.1:8080:80
    depends_on:
      - mariadb
      - memcached
    env_file:
      - ./seafile.env
    volumes:
      - ./seafile:/shared
      
  collabora:
    image: collabora/code
    container_name: collabora
    restart: unless-stopped
    env_file:
      - ./collabora.env
      
  seafile-office-preview:
    image: seafileltd/office-preview:latest
    container_name: seafile-office-preview
    command: bash start.sh
    volumes:
      - ./office-preview:/shared
      - ./office-previewer-settings.py:/opt/office_convertor/settings.py

  • Create the file mariadb.env
MARIADB_ROOT_PASSWORD=<some password for the database root user>

  • Create the file seafile.env
DB_HOST="mariadb"
DB_ROOT_PASSWD=<mariadb root password>
SEAFILE_ADMIN_EMAIL=<your seafile admin user's email address>
SEAFILE_ADMIN_PASSWORD=<your seafile admin user's password>
SEAFILE_SERVER_LETSENCRYPT="false"
SEAFILE_SERVER_HOSTNAME="cloud.yourdomain.com"
EMAIL_USE_TLS=True
TIME_ZONE=Europe/Helsinki # or whichever works for you

  • Create the file office-previewer-settings.py
import os

# Make sure the SECRET_KEY is the same as value in seahub_settings.py
SECRET_KEY = "..."

WORKERS = 10                   # worker number
OUTPUT_DIR = '/shared/output'  # output folder in container
PORT = 8089                    # port in container

  • Create the file collabora.env
domain=<your seafile domain>

  • run `docker compose up -d` to start these containers
  • configure your web server (like Nginx or Apache) to proxy all requests for the domain you'll use with Seafile, to 127.0.0.1:8080 (in my case I use Nginx Proxy Manager so my config is slightly different, but I am keeping it basic and generic here for simplicity)
  • Seafile, using the MySQL root user in the env file will create 3 databases named ccnet_db, seafile_db and seahub_db which it needs for its components to work.
  • access Seafile via browser at the relevant domain with your admin user and make sure Seafile works.

Switching to the s3 backend

Right now Seafile is storing the user files on the file system. In order to switch to s3, 

  • create 3 buckets with your s3 compatible storage of choice named something like unique-prefix-seafile-commit-objects, unique-prefix-seafile-fs-objects, and unique-prefix-seafile-block-objects, Replace unique-prefix with something unique since bucket names must be unique usually with s3 compatible services.
  • Edit seafile/seafile/conf/seafile.conf and append the following
[commit_object_backend]
name = s3
bucket = unique-prefix-seafile-commit-objects
key_id = <s3 access key>
key = <s3 secret key>
host = <s3 endpoint hostname>
aws_region = <s3 region>
use_v4_signature = false
path_style_request = true
use_https = true
memcached_options = --SERVER=memcached --POOL-MIN=10 --POOL-MAX=100 --RETRY-TIMEOUT=3600

[fs_object_backend]
name = s3
bucket = unique-prefix-seafile-fs-objects
key_id = <s3 access key>
key = <s3 secret key>
host = <s3 endpoint hostname>
aws_region = <s3 region>
use_v4_signature = false
path_style_request = true
use_https = true
memcached_options = --SERVER=memcached --POOL-MIN=10 --POOL-MAX=100 --RETRY-TIMEOUT=3600

[block_backend]
name = s3
bucket = unique-prefix-seafile-block-objects
key_id = <s3 access key>
key = <s3 secret key>
host = <s3 endpoint hostname>
aws_region = <s3 region>
use_v4_signature = false
path_style_request = true
use_https = true
memcached_options = --SERVER=memcached --POOL-MIN=10 --POOL-MAX=100 --RETRY-TIMEOUT=3600

  • Recreate the Seafile container
docker stop seafile
docker rm seafile
docker compose up -d

If everything went well, you should still be able to log in, and create a new library (basically on repository of files). This new library will start storing data in the buckets, which you can verify with the control panel of your s3 service of choice or with an s3 client.

Assuming you did everything correctly so far, you should be able to set up the Seafile desktop and mobile clients (which you can find on the official website) and start syncing your data. The core functionality is done.

Editing office documents collaboratively with Collabora Online

The next step is setting up Collabora Online, so that we can edit documents in the browser (by accessing them from the Seafile web GUI).

  • Edit seafile/seafile/conf/seahub_settings.py and
    • take a note of the SECRET_KEY, as you'll need it in a moment
    • append the following
# From 6.1.0 CE version on, Seafile support viewing/editing **doc**, **ppt**, **xls** files via LibreOffice
# Add this setting to view/edit **doc**, **ppt**, **xls** files
OFFICE_SERVER_TYPE = 'CollaboraOffice'

# Enable LibreOffice Online
ENABLE_OFFICE_WEB_APP = True

# Url of LibreOffice Online's discovery page
# The discovery page tells Seafile how to interact with LibreOffice Online when view file online
# You should change `https://collabora-online.seafile.com/hosting/discovery` to your actual LibreOffice Online server address
OFFICE_WEB_APP_BASE_URL = 'https://office.your-domain.com/hosting/discovery'

# Expiration of WOPI access token
# WOPI access token is a string used by Seafile to determine the file's
# identity and permissions when use LibreOffice Online view it online
# And for security reason, this token should expire after a set time period
WOPI_ACCESS_TOKEN_EXPIRATION = 30 * 60   # seconds

# List of file formats that you want to view through LibreOffice Online
# You can change this value according to your preferences
# And of course you should make sure your LibreOffice Online supports to preview
# the files with the specified extensions
OFFICE_WEB_APP_FILE_EXTENSION = ('odp', 'ods', 'odt', 'xls', 'xlsb', 'xlsm', 'xlsx','ppsx', 'ppt', 'pptm', 'pptx', 'doc', 'docm', 'docx')

# Enable edit files through LibreOffice Online
ENABLE_OFFICE_WEB_APP_EDIT = True

# types of files should be editable through LibreOffice Online
OFFICE_WEB_APP_EDIT_FILE_EXTENSION = ('odp', 'ods', 'odt', 'xls', 'xlsb', 'xlsm', 'xlsx','ppsx', 'ppt', 'pptm', 'pptx', 'doc', 'docm', 'docx')

# document previews
OFFICE_CONVERTOR_ROOT = 'http://seafile-office-preview:8089'

  • Recreate the Seafile container
docker stop seafile
docker rm seafile
docker compose up -d

Now if you click on an office document in the Seafile web GUI, a new tab will be open with Collabora in edit mode for your file. This allows you to edit the file directly in the browser and even collaborate on it with other people, in realtime.

Previewing shared office documents

To be able to let other people to preview documents you share with them:

  • Edit office-previewer-settings.py and set SECRET_KEY to the value you copied from seafile/seafile/conf/seahub_settings.py
  • Recreate the preview container
docker stop seafile-office-preview
docker rm seafile-office-preview
docker compose up -d

Now if you share a document with someone with a public link generated with Seafile (either from the web GUI or with a Seafile client), they will be able to open the link in the browser and see a read only preview of the document.

Wrapping up

That's it! You should now have a fully working Seafile setup backed by s3 for the storage and with full edit/preview/collaboration features for office documents. I wrote this post to hopefully save others some time, since it took me a while to figure out some bits on my own due to the lacking documentation and other resources I could find with Google. Let me know in the comments if you run into any issues and I'll try to help if I can.

© Vito Botta