NextCloud and OnlyOffice via Docker

From WikiMLT

Here is a short step-by-step man­u­al: How to set­up On­ly­Of­fice Dock­er con­tain­er and proxy it by Apache2 for NextCloud us­age.

In­stall Dock­er

Ac­cord­ing to the Dock­er and Dock­er-com­pose in­stal­la­tion, read the guide Dock­er Ba­sic Set­up. The rest part of this sec­tion is dep­re­cat­ed, but is leaved here as his­tor­i­cal note :)

#Re­move me: Dep­re­cat­ed Sec­tion
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable"
sudo apt install docker-ce
docker --version
sudo systemctl start docker
sudo systemctl enable docker
Al­low Dock­er us­age by your $USER with­out us­ing su­do.
sudo groupadd docker
sudo usermod -aG docker $USER
su - $USER
id -nG
Prune un­used Dock­er con­tain­ers and im­ages pe­ri­od­i­cal­ly.
sudo crontab -l | grep -i 'docker'
0 2 * * 7 /usr/bin/docker container prune
In my case the fol­low­ing was the most im­por­taint step to get On­ly­Of­fice con­tain­er works cor­rect­ly.
sudo sed 's/^#DOCKER_OPTS/DOCKER_OPTS/' /etc/default/docker -i
sudo systemctl restart docker

Set­up the On­ly­Of­fice Dock­er Con­tain­er

Cre­ate a di­rec­to­ry where the con­fig­u­ra­tion file docker-compose.yaml and the per­sis­tent vol­umes will live.

mkdir /home/docker/onlyoffice
cd /home/docker/onlyoffice

Pull the Dock­er im­ages and run the con­tain­er for a first time

sudo docker run -i -t -d -p 8081:80 --restart=always \
-v $PWD/DocumentServer/logs:/var/log/onlyoffice  \
-v $PWD/DocumentServer/data:/var/www/onlyoffice/Data  \
-v $PWD/DocumentServer/lib:/var/lib/onlyoffice \
-v $PWD/DocumentServer/db:/var/lib/postgresql \
--hostname docs --name onlyoffice-docs \
onlyoffice/documentserver:latest

Test whether it works. At this point the On­ly­Of­fice doc­u­ment serv­er must be ac­ces­si­ble the brows­er, prob­a­bly you maybe need to wait about 10 sec­onds be­fore it be­come ac­ces­si­ble. Note the host port 8081 must be open (for you) with­in the host's fire­wall.

#De­tails
http://<host-ip>:8081/welcome/

En­able the in­te­grat­ed test ex­am­ples.

docker exec onlyoffice-docs supervisorctl start ds:example
docker exec onlyoffice-docs sed 's,autostart=false,autostart=true,' -i /etc/supervisor/conf.d/ds-example.conf

Now you can ac­cess the ex­am­ples at the fol­low­ing ad­dress.

http://<host-ip>:8081/example/

Ex­port the con­fig­u­ra­tion files. For some rea­son the con­fig­u­ra­tion files can­not be ex­port­ed via the vol­ume op­tion as this is done above for some oth­er di­rec­to­ries. So, if we need that, we need first to copy them man­u­al­ly.

#De­tails
sudo mkdir DocumentServer/etc
sudo docker cp onlyoffice-docs:/etc/onlyoffice DocumentServer/etc
sudo docker cp onlyoffice-docs:/etc/supervisor DocumentServer/etc

Now we can stop and prune the con­tain­er.

docker stop onlyoffice-docs
docker container prune
Now cre­ate new con­tain­er and at­tach the di­rec­to­ries with the con­fig­u­ra­tion files as vol­umes.
sudo docker run -i -t -d -p 8081:80 --restart=always \
-v "$PWD/DocumentServer/logs:/var/log/onlyoffice" \
-v "$PWD/DocumentServer/data:/var/www/onlyoffice/Data" \
-v "$PWD/DocumentServer/lib:/var/lib/onlyoffice" \
-v "$PWD/DocumentServer/db:/var/lib/postgresql" \
-v "$PWD/DocumentServer/etc/onlyoffice:/etc/onlyoffice" \
-v "$PWD/DocumentServer/etc/supervisor:/etc/supervisor" \
--hostname docs --name onlyoffice-docs \
onlyoffice/documentserver:latest

Fi­nal­ly stop and prune the con­tain­er, be­cause in the next sec­tion we will cre­ate a Dock­er-com­pose con­fig­u­ra­tion file.

docker stop onlyoffice-docs
docker container prune

Dock­er-com­pose

Cre­ate the docker-compose.yaml file. Tweak the val­ue of the host port 8081, and the time zone TZ if it is need­ed.

nano docker-compose.yaml
# https://hub.docker.com/r/onlyoffice/documentserver/
# https://github.com/ONLYOFFICE/onlyoffice-owncloud/issues/108

version: "3"
services:
  onlyoffice-docs:
    container_name: onlyoffice-docs
    image: onlyoffice/documentserver:latest
    hostname: docs
    #network_mode: host
    ports:
      - "8081:80/tcp"
    environment:
      TZ: 'Europe/Sofia'
    # Volumes store your data between container upgrades
    volumes:
      - './config/docs/log:/var/log/onlyoffice'
      - './config/docs/data:/var/www/onlyoffice/Data'
      - './config//etc/supervisor/conf.d:/etc/supervisor/conf.d'
      - './config/etc/onlyoffice/documentserver/supervisor:/etc/onlyoffice/documentserver/supervisor'
    restart: unless-stopped
    
    
    
# https://hub.docker.com/r/onlyoffice/documentserver/
# https://github.com/ONLYOFFICE/onlyoffice-owncloud/issues/108

version: "3"
services:
  onlyoffice-docs:
    container_name: onlyoffice-docs
    #image: onlyoffice/documentserver:latest
    image: onlyoffice/documentserver:7.2
    hostname: docs
    #network_mode: host
    ports:
      - "8081:80/tcp"
    environment:
      TZ: 'Europe/Sofia'
    # Volumes store your data between container upgrades
    volumes:
      - './config/logs:/var/log/onlyoffice'
      - './config/mysql:/var/lib/mysql'
      - './config/data:/var/www/onlyoffice/Data'
      - './config/data:/var/www/onlyoffice/DocumentServerData'
      - './config/etc/supervisor:/etc/supervisor'
      - './config/etc/onlyoffice:/etc/onlyoffice'
    restart: unless-stopped

Down­load the Dock­er im­ages and run the con­tain­er in de­tached (per­sis­tent) mode.

docker-compose up -d

Open the On­ly­Of­fice doc­u­ment serv­er via the brows­er. Note the host port 8081 must be open (for you) with­in the host's fire­wall.

http://<host-ip>:8081/welcome/

The rest part of this sec­tion is dep­re­cat­ed, but is leaved here as his­tor­i­cal note :)

#Re­move me: Dep­re­cat­ed Sec­tion
Get a list of all avail­able ver­sions of On­ly­Of­fice im­ages (ref­er­ence).
wget -q https://registry.hub.docker.com/v1/repositories/onlyoffice/documentserver/tags -O - | jq -r '.[].name'
Down­lad the lat­est On­ly­Of­fice im­age and run it at port 81 of 127.0.0.1 lo­cal­host.
# docker pull onlyoffice/documentserver
docker run -i -t -d -p 81:80 --restart=always onlyoffice/documentserver:latest
  • Note the op­tion –restart=always means the con­tain­er will run au­to­mat­i­cal­ly when Dock­er is started/​​​restarted.
  • Dock­er will pull the im­age au­to­mat­i­cal­ly when it is not avail­able lo­cal­ly.

Apache2 Proxy Vir­tu­al Host

Test Whether the ce­ses­sary Apache2 mod­ules are en­abled.

sudo apache2ctl -M | grep -E 'auth[nz]_core|unixd|proxy|headers|setenvif'
 unixd_module (static)          # Required
 authn_core_module (shared)     # Required
 authz_core_module (shared)     # Required
 headers_module (shared)        # Required
 proxy_module (shared)          # Required
 proxy_fcgi_module (shared)
 proxy_http_module (shared)     # Required
 proxy_http2_module (shared)
 proxy_wstunnel_module (shared) # Required
 setenvif_module (shared)       # Required

Set­up a new vir­tu­al host as fol­low and restart Apache2. Note in this sce­nar­i­ou you need a valid SSL/TLS certivi­cate.

sudo nano /etc/apache2/sites-enabled/docs.example.com.conf
<VirtualHost *:80>
    ServerName docs.example.com
    ServerAdmin admin@example.com
    Redirect permanent "/" "https://docs.example.com/"
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
    ServerName docs.example.com
    ServerAdmin admin@example.com

    ErrorLog ${APACHE_LOG_DIR}/docs.example.com.error.log
    CustomLog ${APACHE_LOG_DIR}/docs.example.com.access.log combined

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem

    <IfModule pagespeed_module>
        ModPagespeed off
    </IfModule>
    
    <IfModule security2_module>
      # SecRuleEngine Off
    </IfModule>
    
    # ProxyPreserveHost On
    # ProxyRequests Off

    SetEnvIf Host "^(.*)$" THE_HOST=$1
    Header edit Set-Cookie ^(.*)$ "$1; HttpOnly; Secure"
    RequestHeader setifempty X-Forwarded-Proto https
    RequestHeader setifempty X-Forwarded-Host %{THE_HOST}e
    ProxyAddHeaders Off

    ProxyPassMatch (.*)(\/websocket)$ "ws://localhost:81/$1$2"
    ProxyPass / "http://localhost:81/"
    ProxyPassReverse / "http://localhost:81/"

</VirtualHost>
</IfModule>

Ref­er­ences