Collaborate on documents in real time - OnlyOffice for OwnCloud

Docker collaboration tools to improve your workflow and efficiency
Photo by Scott Graham / Unsplash

A while back I created a walkthrough to set up your own selfhosted OwnCloud instance for file storage and sharing. For those of you who have multiple users and need some real-time collaboration, I have the answer for you:

This is a separate container which we will spin up and connect to OwnCloud via the integration app and OwnCloud Admin Settings.


Prerequisites:

  1. Docker and docker-compose installed on your machine
  2. sudo privileges to be able to run docker commands as root, or you've added your user to the docker group to bypass that
  3. The ability to SSH / use CLI/terminal on your machine, or use Portainer to spin up your stacks
  4. Some sort of access and relevant permissions to manage and create new directories
  5. A working OwnCloud instance, ability to modify the docker-compose.yml (if you haven't set it up yet, you can follow this guide) and admin access
  6. A working reverse proxy setup with SSL certificate generation (check out my SWAG article for some info on how to do that if you haven't already)

Prepping your system for OnlyOffice

  • Navigate to your OwnCloud volume on your host system, where you should have a few folders such as core, db, files and redis (your setup may vary)
  • Create a new folder here called onlyoffice and go into it
  • Inside your onlyoffice folder, create three more called cache, data and logs
  • Locate and open the docker-compose.yml for your OwnCloud services
💡
If you've followed my OwnCloud guide then thedocker-compose.yml will be in your owncloud folder, however if you're using Portainer or you set it up in a different way then you'll need to edit the stack (Portainer) or find it where you left
  • Somewhere in the services block of your compose file, you will need to add the following:
#ownCloud
  onlyoffice:
    image: onlyoffice/documentserver
    container_name: onlyoffice
    ports:
      - '10080:80' #change before the `:` if necessary to avoid port clashes
      - '10443:443' #change before the `:` if necessary to avoid port clashes
    restart: unless-stopped
    environment:
      - LETS_ENCRYPT_DOMAIN=example.com #change to your domain without http or https
      - LETS_ENCRYPT_EMAIL=anyemail@willdo.com #change to any email
      - JWT_SECRET=yoursecretstring #change to a long-ish secret of your own
    volumes:
      - ./onlyoffice/data:/var/www/onlyoffice/Data
      - ./onlyoffice/logs:/var/log/onlyoffice
      - ./onlyoffice/cache:/var/lib/onlyoffice
    # uncomment below if you only want onlyoffice to start when owncloud has started
    #depends_on:
      #- owncloud
    networks:
      - proxy #change if necessary to your reverse proxy network, or to make sure that your reverse proxy and onlyoffice instance are on the same network
make sure to read the #commented out lines and change what's necessary to match your setup
  • If your owncloud instance is only accessible locally and therefore doesn't have a specified proxy network yet, you will also need to add that network into the compose file. The whole thing might look something like this:
#########NETWORKS#########
networks:
  owncloud:
    external: true
  proxy:
    external: true
#########NETWORKS#########
services:
  owncloud:
    image: owncloud/server:latest
    container_name: owncloud
    restart: unless-stopped
    ports:
      - 8080:8080 #change before the ':' if necessary
    depends_on:
      - oc-db #makes sure the database is up before running owncloud
      - oc-redis #same as above
    environment:
      - OWNCLOUD_DOMAIN=123.456.789.9:8080 #change to your host IP and port above
      - OWNCLOUD_TRUSTED_DOMAINS=123.456.789.9,owncloud.yourdomain.com #change to match the IP ONLY above (do not include the port) and add the domain you will use to access it externally. If you don't plan to access it externally, delete the domain and the comma
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloudDB
      - OWNCLOUD_DB_USERNAME=#choose a username (1)
      - OWNCLOUD_DB_PASSWORD=#enter a strong password (1)
      - OWNCLOUD_DB_HOST=oc-db
      - OWNCLOUD_ADMIN_USERNAME=#choose a username (2)
      - OWNCLOUD_ADMIN_PASSWORD=#choose a strong password (2)
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=oc-redis
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - ./files:/mnt/data
    networks:
      - owncloud

  oc-db:
    image: mariadb:10.5
    container_name: owncloud_db
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=#choose a strong password
      - MYSQL_USER=#the same as username (1) above
      - MYSQL_PASSWORD=#the same as password (1) above
      - MYSQL_DATABASE=owncloudDB
    command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=${MYSQLROOTPWD}"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - ./db:/var/lib/mysql
    networks:
      - owncloud

  oc-redis:
    image: redis:6
    container_name: owncloud_redis
    restart: unless-stopped
    command: ["--databases", "1"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - ./redis:/data
    networks:
      - owncloud

#ownCloud
  onlyoffice:
    image: onlyoffice/documentserver
    container_name: onlyoffice
    ports:
      - '10080:80' #change before the `:` if necessary to avoid port clashes
      - '10443:443' #change before the `:` if necessary to avoid port clashes
    restart: unless-stopped
    environment:
      - LETS_ENCRYPT_DOMAIN=example.com #change to your domain without http or https
      - LETS_ENCRYPT_EMAIL=anyemail@willdo.com #change to any email
      - JWT_SECRET=yoursecretstring #change to a long-ish secret of your own
    volumes:
      - ./onlyoffice/data:/var/www/onlyoffice/Data
      - ./onlyoffice/logs:/var/log/onlyoffice
      - ./onlyoffice/cache:/var/lib/onlyoffice
    # uncomment below if you only want onlyoffice to start when owncloud has started
    #depends_on:
      #- owncloud
    networks:
      - proxy #change if necessary to your reverse proxy network, or to make sure that your reverse proxy and onlyoffice instance are on the same network
we don't need our onlyoffice container to be on the same network as our owncloud container as we will be accessing it via the domain name we will set up in the next step

Setting up your reverse proxy for OnlyOffice

Now is a good time to get this out of the way with whichever tools you use for this. Again if you need a guide because you've not done this before, please check out my SWAG article.

  • On your nameserver, create your A or CNAME record for onlyoffice.yourdomain.com
  • In your reverse proxy, do the necessary steps so that onlyoffice.yourdomain.com resolves to your onlyoffice container (for instance with swag, set up a proxy-conf so that onlyoffice points to onlyoffice on port 80). An example nginx proxy conf is below, yours may differ if you have a different setup:
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name onlyoffice.*;
    include /config/nginx/ssl.conf;
    client_max_body_size 0;

	#enable for ldap auth, fill in ldap details in ldap.conf
    #include /config/nginx/ldap.conf;

    # enable for Authelia
    #include /config/nginx/authelia-server.conf;

    location / {
        #enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        #enable the next two lines for ldap auth
        #auth_request /auth;
        #error_page 401 =200 /ldaplogin;

        # enable for Authelia
        #include /config/nginx/authelia-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app onlyoffice;
        set $upstream_port 80;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

Once that's been setup, we're ready to spin up the container.


Creating the container and integrating with OwnCloud

  • In SSH or Portainer, recreate your OwnCloud stack, and you should notice that onlyoffice is now also created
  • Check the logs for a few minutes to make sure no errors are thrown
  • Once you're satisfied it's all up and running, open owncloud in your browser and log in with the administrator account
  • Click the menu button top left and then Market in the drop down options
  • Select Tools from the categories on the left, then find and click ONLYOFFICE
  • Scroll down and click INSTALL (mine says UNINSTALL because mine's already installed and I didn't bother to uninstall it for this tuto, big whoop wanna fight about it?)
  • When it's installed, click your user button top left, then select settings
  • On the left, click Additional
  • Locate the ONLYOFFICE block on the page, and identify the ONLYOFFICE Docs address and Secret key fields
  • In the former, put in the full address of your reverse proxied onlyoffice instance, such as https://onlyoffice.yourdomain.com
  • In the latter, input the JWT_SECRET which you set in the onlyoffice block in the docker-compose.yml
  • Hit save

Using OnlyOffice

That's pretty much it. You should now be able to create or import any spreadsheet or word-style file and edit it, with others, in real time. OnlyOffice will open automatically when you click a file inside OwnCloud which is supported An example is below:


Self-hosting OwnCloud: private & shareable file storage
One of the simplest self-hosted tools available, replete with 2FA security, multiple users, group admins, and external file-sharing
Swag, Authelia and Reverse Proxies
A step-by-step walkthrough to self-host your Reverse Proxy with SWAG, and providing SSO and 2FA security using Authelia, all in docker