使用docker-compose部署Nextcloud和Onlyoffice组合包(包含nginx+ssl+postgres+redis)

3,095 阅读5分钟

使用docker-compose部署Nextcloud和Onlyoffice组合包 可快速免费建立个人网盘。

Nextcloud是一个私人网盘,使用PHP语言编写,是owncloud的一个分支,可以共享和协作处理文档、发送和接收电子邮件、管理您的日历以及进行视频聊天而不会泄露数据,上传下载可以达到硬盘满速,还具有简单、易用,高效,易扩展、快速部署等特点,不止网页可以访问,还同时拥有配套的客户端(windows,mac,安卓,ios)。作为完全内部部署的解决方案,Nextcloud Hub 提供在线协作的好处,而没有合规性和安全风险

ONLYOFFICE安全的办公室和生产力应用(社区版,手机端(手机useragent)不能编辑)

Nextcloud 插件 因为和谐原因,一般我们选用下载后安装模式,而不是内部安装。

开始搭建

  • 安装环境:

    ubuntu server Xenial 16.04 (LTS)

    Docker version 20.10.7, build f0df350

    docker-compose version 1.29.2, build 5becea4c

  • docker国内镜像加速:

    # 创建或修改 /etc/docker/daemon.json 文件
    $ sudo vim /etc/docker/daemon.json
    
    {
    "registry-mirrors": [
        "https://registry.docker-cn.com",
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn"
        ]
    }
    
    # 加载重启docker
    $ sudo systemctl daemon-reload
    $ sudo systemctl restart docker
    
    # 查看是否成功(查看最底下,Registry Mirrors)
    $ docker info
    
    
  • 安装portainer(方便管理docker):

      docker run -d -p 9898:9000 \
          --restart=always \
          -v /var/run/docker.sock:/var/run/docker.sock \
          --name prtainer \
          portainer/portainer
    
  • 下载需要的镜像:

      # nginx
      docker pull nginx
      # postgres
      docker pull postgres:12
      # onlyoffice
      docker pull onlyoffice/documentserver:latest
      # nextcloud
      docker pull nextcloud:fpm
      # redis
      docker pull redis:alpine
    
  • 网站签名证书

    • 自签名证书(或者用现成的也可以)
      # 生成证书:
      # 创建私钥
      openssl genrsa -out onlyoffice.key 2048
      # 创建CSR
      openssl req -new -key onlyoffice.key -out onlyoffice.csr
      # 用私枂和CSR签发证书
      openssl x509 -req -days 365 -in onlyoffice.csr -signkey onlyoffice.key -out onlyoffice.crt
      # 用dhparam加密服务器密钥
      openssl dhparam -out dhparam.pem 2048
    
    • key和crt证书文件转pem格式
      openssl x509 -in SSLcertificate.crt  -out fullchain.pem
      openssl rsa -in SSLprivatekey.key -out privkey.pem
    
  • 在ubuntu根目录新建一个文件夹 mydata

    • 其他位置,以及文不同的文件夹名都可以,只要记得修改脚本中的对应路径就可以了

    • 在mydata目录下新建一个文件夹 config

      • 用以存放程序初始化时的账号密码等信息

      • 网盘数据库名称:postgres_db.txt

      • 网盘数据库用户:postgres_user.txt

      • 网盘数据库密码:postgres_password.txt

      • 网盘管理员账号:nextcloud_admin_user.txt

      • 网盘管理员密码:nextcloud_admin_password.txt

    • 在mydata目录下新建一个文件夹 nextcloud

      • 用以存放程序初始化时信息,以及各个容器映射的数据

      • 在nextcloud目录下新建一个certs文件夹用以存放网站证书

        • privkey.pem
        • fullchain.pem
      • 在nextcloud目录下新建一个nginx文件夹用以存放nginx配置

        • 新建 nginx.conf 文件
              # nginx.conf
          
              user  www-data;
              worker_processes  1;
          
              error_log  /var/log/nginx/error.log warn;
              pid        /var/run/nginx.pid;
          
              events {
                  worker_connections  1024;
              }
          
              http {
          
                  upstream backend {
                      server app-server:9000;
                  }
          
          
                  include       /etc/nginx/mime.types;
                  default_type  application/octet-stream;
          
                  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                  '$status $body_bytes_sent "$http_referer" '
                                  '"$http_user_agent" "$http_x_forwarded_for"';
          
                  access_log  /var/log/nginx/access.log  main;
          
                  sendfile        on;
                  #tcp_nopush     on;
          
                  keepalive_timeout  65;
          
                  map $http_host $this_host {
                      "" $host;
                      default $http_host;
                  }
          
                  map $http_x_forwarded_proto $the_scheme {
                      default $http_x_forwarded_proto;
                      "" $scheme;
                  }
          
                  map $http_x_forwarded_host $the_host {
                      default $http_x_forwarded_host;
                      "" $this_host;
                  }
          
                  server {
                      listen 80;
          
                      include /etc/nginx/common.conf;
                  }
              }
          
        • 新建 common.conf 文件
          # common.conf
          
          # Add headers to serve security related headers
          add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
          add_header X-Content-Type-Options nosniff;
          add_header X-XSS-Protection "1; mode=block";
          add_header X-Robots-Tag none;
          add_header X-Download-Options noopen;
          add_header X-Permitted-Cross-Domain-Policies none;
          
          root /var/www/html;
          client_max_body_size 10G; # 0=unlimited - set max upload size
          fastcgi_buffers 64 4K;
          
          gzip off;
          
          index index.php;
          error_page 403 /core/templates/403.php;
          error_page 404 /core/templates/404.php;
          
          rewrite ^/.well-known/carddav /remote.php/dav/ permanent;
          rewrite ^/.well-known/caldav /remote.php/dav/ permanent;
          
          location = /robots.txt {
              allow all;
              log_not_found off;
              access_log off;
          }
          
          location ~ ^/(build|tests|config|lib|3rdparty|templates|data)/ {
              deny all;
          }
          
          location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
              deny all;
          }
          
          location / {
              rewrite ^/remote/(.*) /remote.php last;
              rewrite ^(/core/doc/[^\/]+/)$ $1/index.html;
              try_files $uri $uri/ =404;
          }
          
          location ~* ^/ds-vpath/ {
              rewrite /ds-vpath/(.*) /$1  break;
              proxy_pass http://onlyoffice-document-server;
              proxy_redirect     off;
          
              client_max_body_size 100m;
          
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
          
              proxy_set_header Host $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Host $the_host/ds-vpath;
              proxy_set_header X-Forwarded-Proto $the_scheme;
          }
          
          location ~ \.php(?:$|/) {
              fastcgi_split_path_info ^(.+\.php)(/.+)$;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
              fastcgi_param HTTPS off;
              fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
              fastcgi_pass backend;
              fastcgi_intercept_errors on;
          }
          
          # Adding the cache control header for js and css files
          # Make sure it is BELOW the location ~ \.php(?:$|/) { block
          location ~* \.(?:css|js)$ {
              add_header Cache-Control "public, max-age=7200";
              # Add headers to serve security related headers
              add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
              add_header X-Content-Type-Options nosniff;
              add_header X-Frame-Options "SAMEORIGIN";
              add_header X-XSS-Protection "1; mode=block";
              add_header X-Robots-Tag none;
              add_header X-Download-Options noopen;
              add_header X-Permitted-Cross-Domain-Policies none;
              # Optional: Don't log access to assets
              access_log off;
          }
          
          # Optional: Don't log access to other assets
          location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|swf)$ {
              access_log off;
          }
          
          
        • 新建 nginx-ssl.conf 文件
          # nginx-ssl.conf 文件
          
              user  www-data;
              worker_processes  1;
          
              error_log  /var/log/nginx/error.log warn;
              pid        /var/run/nginx.pid;
          
              events {
                  worker_connections  1024;
              }
          
              http {
          
                  upstream backend {
                      server app-server:9000;
                  }
          
          
                  include       /etc/nginx/mime.types;
                  default_type  application/octet-stream;
          
                  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                  '$status $body_bytes_sent "$http_referer" '
                                  '"$http_user_agent" "$http_x_forwarded_for"';
          
                  access_log  /var/log/nginx/access.log  main;
          
                  sendfile        on;
                  #tcp_nopush     on;
          
                  keepalive_timeout  65;
          
                  map $http_host $this_host {
                      "" $host;
                      default $http_host;
                  }
          
                  map $http_x_forwarded_proto $the_scheme {
                      default $http_x_forwarded_proto;
                      "" $scheme;
                  }
          
                  map $http_x_forwarded_host $the_host {
                      default $http_x_forwarded_host;
                      "" $this_host;
                  }
          
                  server {
                      listen 80;
          
                      location / {
                          return 301 https://$host$request_uri;
                      }
                  }
          
                  server {
                      listen 80;
                      server_name nginx-server;
          
                      include /etc/nginx/common.conf;
                  }
          
                  server {
                      listen 443 ssl;
          
                      ssl_certificate     /etc/nginx/certs/fullchain.pem;
                      ssl_certificate_key /etc/nginx/certs/privkey.pem;
                      ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
                      ssl_ciphers         HIGH:!aNULL:!MD5;
          
                      include /etc/nginx/common.conf;
                  }
              }
          
          
      • 在nextcloud目录下新建一个ssl.yml文件

            version: '3.9'
            services:
            onlyoffice-document-server:
                environment:
                - USE_UNAUTHORIZED_STORAGE=true
            nginx:
                volumes:
                - ./certs:/etc/nginx/certs:ro
                - ./nginx/nginx-ssl.conf:/etc/nginx/nginx.conf:ro
        
      • 在nextcloud目录下新建一个docker-compose.yml 文件

            version: '3.9'
            services:
            db:
                container_name: db-server
                image: postgres:12
                restart: always
                volumes:
                - ./db:/var/lib/postgresql/data
                environment:
                - POSTGRES_DB_FILE=/run/secrets/postgres_db
                - POSTGRES_USER_FILE=/run/secrets/postgres_user
                - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
                secrets:
                - postgres_db
                - postgres_password
                - postgres_user
        
            cache:
                container_name: cache-server
                image: redis:alpine
                restart: always
                expose:
                - 6379
                restart: always
        
            app:
                container_name: app-server
                image: nextcloud:fpm
                restart: always
                expose:
                - '80'
                - '9000'
                volumes:
                - ./app_data:/var/www/html
                environment:
                - REDIS_HOST=cache
                - REDIS_HOST_PORT=6379
                - POSTGRES_HOST=db
                - POSTGRES_DB_FILE=/run/secrets/postgres_db
                - POSTGRES_USER_FILE=/run/secrets/postgres_user
                - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
                - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/nextcloud_admin_password
                - NEXTCLOUD_ADMIN_USER_FILE=/run/secrets/nextcloud_admin_user
                depends_on:
                - db
                - cache
                secrets:
                - nextcloud_admin_password
                - nextcloud_admin_user
                - postgres_db
                - postgres_password
                - postgres_user
        
            onlyoffice-document-server:
                container_name: onlyoffice-document-server
                image: onlyoffice/documentserver:latest
                restart: always
                expose:
                - '80'
                - '443'
                volumes:
                - ./document_data:/var/www/onlyoffice/Data
                - ./document_log:/var/log/onlyoffice
                environment:
                - REDIS_SERVER_HOST=cache
                - REDIS_SERVER_PORT=6379
                depends_on:
                - cache
        
            nginx:
                container_name: nginx-server
                image: nginx
                restart: always
                ports:
                - 80:80
                - 443:443
                volumes:
                - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
                - ./nginx/common.conf:/etc/nginx/common.conf:ro
                - ./app_data:/var/www/html
        
            secrets:
            nextcloud_admin_password:
                file: /mydata/config/nextcloud_admin_password.txt
            nextcloud_admin_user:
                file: /mydata/config/nextcloud_admin_user.txt
            postgres_db:
                file: /mydata/config/postgres_db.txt
            postgres_password:
                file: /mydata/config/postgres_password.txt
            postgres_user:
                file: /mydata/config/postgres_user.txt    
        
      • 在nextcloud目录下新建一个set_configuration.sh 文件

        #!/bin/bash
        
        set -x
        
        docker exec -u www-data app-server php occ --no-warnings config:system:get trusted_domains >> trusted_domain.tmp
        
        if ! grep -q "nginx-server" trusted_domain.tmp; then
            TRUSTED_INDEX=$(cat trusted_domain.tmp | wc -l);
            docker exec -u www-data app-server php occ --no-warnings config:system:set trusted_domains $TRUSTED_INDEX --value="nginx-server"
        fi
        
        rm trusted_domain.tmp
        
        docker exec -u www-data app-server php occ --no-warnings app:install onlyoffice
        
        docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice DocumentServerUrl --value="/ds-vpath/"
        docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice DocumentServerInternalUrl --value="http://onlyoffice-document-server/"
        docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice StorageUrl --value="http://nginx-server/"
        
        docker exec -u www-data app-server php occ --no-warnings config:system:set allow_local_remote_servers  --value=true
        
  • 准备工作完成,开干(敲命令)

        # 定位到程序目录
        cd /mydata/nextcloud
    
        # 启动程序
        docker-compose -f docker-compose.yml -f ssl.yml up -d
    
        # 运行脚本前先看下是不是程序能跑了,能跑了 再运行脚本,脚本主要是用来串联,nextcloud和onlyoffice
    
        bash set_configuration.sh
    
        # 修改下程序的配置,用来应对域名访问问题,以及https 没有自动跳转的问题
        ./nextcloud/app_data/config/config.php
    
        # 修改为(新增局域网域名,和外网域名)
        'trusted_domains' => 
        array (
            0 => 'localhost',
            1 => 'nginx-server',
            2 => '192.168.x.x',
            3 => 'xxx.xxx.com',  
        ),
        
        # 新增
        'overwriteprotocol' => 'https',
    
        # 保存config.php
    
        # 继续去敲命令
        # 让上传下载满速,不然只能10~20m/s的速度
        docker exec --user www-data app-server php occ config:app:set files max_chunk_size --value 0
    
  • 收尾(检查下脚本的优化任务是否正常执行)

    • 检查是否选择cron

      • 管理员登录进 nextcloud(账号密码在/mydata/config/文件夹中)
      • 设置->基本设置->后台任务(选择cron)
    • 检查ubuntu中是否已开定时任务刷新

      • 查看/修改 定时任务
          crontab -e
      
      • 检查是否存在
          */5 * * * * docker exec --user www-data app-server php /var/www/html/cron.php 
      
      • 如果没有就新增,新增后重启任务
          service cron restart
      
    • 安装/配置/优化部分已经完成

  • 安装插件

    • 自带的插件安装平台,因为和谐原因,下载安装会有问题,建议别尝试,很容易进入维护模式,如果不小心进入了维护模式,也别急,config.php 文件中设置为'auth.bruteforce.protection.enabled' => false, 然后再刷下就好了
    • 去官网下载插件(也许可能需要科学访问)
    • 这里就演示一个,其他的方法相同
    • 下载files_mindmap-0.0.24.tar.gz(在线思维导图)
    • 把压缩包上传到/mydata/nextcloud_apps
    • 解压缩到插件文件夹/mydata/nextcloud/app_data/apps
          tar zxvf  /mydata/nextcloud_apps/files_mindmap-0.0.24.tar.gz -C /mydata/nextcloud/app_data/apps
      
    • 用管理员登录nextcloud 开启插件
    • 应用->已禁用的应用->Mind Map ->启用
    • 刷新网站,就可以去文件中新建思维导图了
  • 到此攻略完毕,office 等也可以在线使用

  • 2023-04-23 更新

    # 7.2版本的onlyoffice 有了密钥
    # 所以流程稍微有所变化
    # 1.安装好onlyOffice插件
    # 2.再跑下上面的脚本 
    bash set_configuration.sh
    # 再获取onlyOffice的密钥
    sudo docker exec [容器id] /var/www/onlyoffice/documentserver/npm/json -f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.session.string'
    # 填入nextcloud onlyOffice 插件中的密码中
    # 即可正常使用 nextcloud下的onlyOffice插件