首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Coding
V2EX  ›  服务器

基于 Windows Server 2019 混合 Docker for windows 搭建 Nextcloud 简易攻略

  •  
  •   wyxls · 47 天前 · 2990 次点击
    这是一个创建于 47 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于 Windows Server 2019 混合 Docker for windows 搭建 Nextcloud 简易攻略

    环境:

    物理主机系统:Windows server 2019 Datecenter (v1809, 17763.805)
    Docker:Docker for windows 2.1.0.4 (Engine: 19.03.4, Compose: 1.24.1)
    MySQL:MySQL for win64 8.0.18 Community Server
    Nginx:Nginx for windows 1.16.1
    Nextcloud:17.0.0 (hub.docker.com/_/nextcloud, nextcloud:latest, nextcloud:apache, OS:Linux/amd64)
    可选附加:
    Onlyoffice-document-server: https://hub.docker.com/r/onlyoffice/documentserver, tag:latest
    redis: https://hub.docker.com/_/redis, tag:latest
    

    总之除了 Nextcloud,附加的 onlyoffice-document-server 和 redis 之外,其余均为基于 windows 的软件

    Nextcloud 镜像的选择:在官方 Docker 页面中主要版本有默认的 Apache 版和采用容器化 Nginx 的 FPM 版,在我个人实际搭建过程中 FPM 版的 Nginx 和宿主机 windows 之间隔着一层 NAT,配置调试起来显得十分麻烦,故选择运行起来更简单的 Apache 版

    Docker for windows 安装是全自动创建 Docker Host 的 Hyper-V 虚拟机,网络使用 NAT 转发,Host IP 为 10.75.0.1,Container IP 为 10.0.75.0

    MySQL Community 创建好供 Nextcloud 使用的 utf8mb4 编码的数据库(database),并设置好相关的用户名和密码,也可以直接使用默认的 root 账户,记得要修改密码

    NextCloud 和 Nginx 的搭建后续重点讲述

    重点讲述:

    Nextcloud 容器:

    这个其实百度和谷歌上有一大批的教程,只是个人在实际环境运行中出现了各种各样的小细节问题,还有更多的是这些教程大多数都过时了,当然接下来的所有讲述都是仅供参考,毕竟每个人的运行环境都不同

    Compose 文本内包含了 redis 缓存容器和 onlyoffice-document-server 文档服务器容器配置,觉得有用请自取

    我个人将一些比较重要的文件和 log 通过 volume 挂载到物理系统 windows server 的 D 盘中,Nextcloud 则是直接将整个 PHP 程序和数据文件夹 /var/www/html 转移到 D:/Docker/nextcloud 中,方便以后直接使用 windows 管理文档

    nextcloud 容器用的 “wyxls/nextcloud:full” 镜像是我自建的,Nextcloud 的官方镜像默认不带 smbclient 和 crontab,会影响到外部存储挂载 APP 使用 (因为我主要 windows 的 smb 共享),于是我根据官方提供的 Dockerfile 自建了镜像并上传到 docker hub,不需要的话可以改成 nextcloud 官方的 image ( https://hub.docker.com/_/nextcloud)

    Dockerfile example:( https://github.com/nextcloud/docker/blob/master/.examples/dockerfiles/full/apache/Dockerfile)

    version: '3'
    #初始化网络模块,为了让 Nextcloud 和 onlyoffice+redis 协作
    networks:
      nextcloud:
    #services 以下都是容器
    services:
    #redis 容器,暴露 6379 端口供其他容器使用
      redis:
        image: redis
        container_name: redis
        hostname: redis
        restart: always
        networks:
          - nextcloud
        expose:
          - 6379
    #nextcloud 容器,宿主机 10000 端口转发 80 端口访问
      nextcloud:
        image: wyxls/nextcloud:full
        container_name: nextcloud
        restart: always
        depends_on:
          - redis
        environment:
          - UID=1000
          - GID=1000
          - UPLOAD_MAX_SIZE=5G
          - APC_SHM_SIZE=128M
          - OPCACHE_MEM_SIZE=128
          - CRON_PERIOD=15m
          - TZ=Aisa/Shanghai
          - NEXTCLOUD_TABLE_PREFIX=oc_
        volumes:
          - D:/Docker/nextcloud:/var/www/html
        ports:
          - 10000:80
        networks:
          - nextcloud
    #onlyoffice 容器,宿主机 10005 端口转发 443 端口访问,在 nextcloud 的 onlyoffice 设置里必须以 https+宿主端口访问
      onlyoffice:
        container_name: onlyoffice
        image: onlyoffice/documentserver:latest
        stdin_open: true
        tty: true
        restart: always
        depends_on:
          - nextcloud
        volumes:
          - D:/Docker/onlyoffice/document_data:/var/www/onlyoffice/Data
          - D:/Docker/onlyoffice/document_log:/var/log/onlyoffice
          - D:/Docker/onlyoffice/document_fonts:/usr/share/fonts/truetype/custom
          - D:/Docker/onlyoffice/document_forgotten:/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten
        ports:
          - 10005:443
        networks:
          - nextcloud
    

    在 Docker 容器中运行的 Nextcloud 默认以 root 权限运行所有程序,所以访问时会提示设置权限 chmod 0770,但在我个人实践中无论是 chown 还是 chmod 都无法解决这个问题,后来还是强行忽略文件权限检查

    在 /var/www/html/config/config.php 中加入以下一行:

      'check_data_directory_permissions' => false,     #检查数据目录权限
    

    此外别忘了还要添加 Trusted_Domains,不然 Nextcloud 的 Web 端无法访问:

      'trusted_domains' => 
      array (
        0 => 'example.com',
        1 -> 'localhost',
      ),
    
    Nginx:

    由于 Docker for windows 是基于 Hyper-V 虚拟机模拟出的 Linux/amd64 系统,相当于物理 windows——Hyper-V 虚拟机( Docker Host 宿主机)——Docker Container (容器)两层 NAT 网络,所以需要使用 Nginx 当中间人进行反向代理,下面是我个人配置的 conf,仅供参考

    因为我个人的 Windows Server 内网可以直接通过 SMB 访问管理文件,而 Nextcloud 只进行外网访问,所以我只做了 HTTPS 监听+反向代理,有内网 HTTP 访问需求的可以将 SSL 相关部分注释掉

    原本在反向代理 proxy_pass 段有 connect, read, send 等 timeout 限制,但后来发现添加后网页访问和 windows 客户端同步变得异常缓慢,而且频繁报错,故删除

    server {
        listen      10002 ssl;                         #Nginx 监听端口
        server_name example.com localhost 192.168.x.x; #域名, IP, 本地地址都可以填写
        root        D:/nextcloud;                      #nextcloud 目录
        index       index.php;
    
        ssl_certificate       D:/SSL-Certificates/fullchain.cer;
        ssl_certificate_key   D:/SSL-Certificates/private.key;
        ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;
    
        #以下部分为隐藏 header, 为了解决 nextcloud 自检问题
        proxy_hide_header Strict-Transport-Security;
        proxy_hide_header X-Content-Type-Options;
        proxy_hide_header X-Robots-Tag;
        proxy_hide_header X-Frame-Options;
        proxy_hide_header X-Download-Options;
        proxy_hide_header X-Permitted-Cross-Domain-Policies;
        proxy_hide_header Referrer-Policy;
        proxy_hide_header X-XSS-Protection;
    
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options nosniff;
        add_header X-Robots-Tag "none";
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Download-Options "noopen";
        add_header X-Permitted-Cross-Domain-Policies "none";
        add_header Referrer-Policy "no-referrer";
        add_header X-XSS-Protection "1; mode=block";
    
        client_max_body_size 10G;
        fastcgi_buffers 64 4K;
        fastcgi_hide_header X-Powered-By;
        
        location / {
            proxy_pass http://localhost:10000/;                            #反向代理地址
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
    	location = /.well-known/carddav {                                  #解决自检 carddav 未正常配置解析提示问题 
            return 301 $scheme://$http_host/remote.php/dav;
        }
    
    	location = /.well-known/caldav {                                   #解决自检 carddav 未正常配置解析提示问题
            return 301 $scheme://$http_host/remote.php/dav;
        }
    
        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;
        }
    
    }
    

    在初步搭好 Nextcloud 后实际使用中经常出现访问超时,原因是 Nextcloud 在反向代理中可能会无法侦测正确的协议,需要强行覆写( Nextcloud 默认 latest 镜像用 Apache 作为 Web server 监听 HTTP 80 端口)

      'overwriteprotocol' => 'https',
    

    额外部分:

    Onlyoffice-document-server:

    Nextcloud 官方提供连接 onlyoffice 服务的 APP,与 onlyoffice 对接后能实现 Nextcloud 内通过 Web 访问直接打开并编辑 office 相关文档 (pptx, xlsx, docs 等),通过 Docker 可以一键配置

    version: '3'
    services:
      onlyoffice:
        container_name: onlyoffice
        image: onlyoffice/documentserver:latest
        stdin_open: true
        tty: true
        restart: always
        depends_on:
          - nextcloud
        volumes:
          - D:/Docker/onlyoffice/document_data:/var/www/onlyoffice/Data
          - D:/Docker/onlyoffice/document_log:/var/log/onlyoffice
          - D:/Docker/onlyoffice/document_fonts:/usr/share/fonts/truetype/custom
          - D:/Docker/onlyoffice/document_forgotten:/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten
        ports:
          - 10005:443
        networks:
          - nextcloud
    

    证书安装:在 /var/www/onlyoffice/Data 中建立"certs"文件夹并将 SSL 证书及私钥以"onlyoffice.crt"和"onlyoffice.key"保存,或者直接在 yml 中 environment 环境参数添加,在 Docker-Settings-Shared Drives 设置共享后可以直接使用 windows 物理路径指定,比如:D:\SSL-certificates\onlyoffice.crt

    environment:
     - SSL_CERTIFICATE_PATH=证书路径
     - SSL_KEY_PATH=私钥路径
    

    通过访问 https://example.com:10005 可以查看 Document Server 运行状况,显示 Document Server is running 表示成功

    最后在 Nextcloud 内设置 Document Editing Service address 为 https://example.com:10005,如果页面下方出现 settings 一类选项则表示已成功连接

    Redis:

    Nextcloud 官方推荐使用 Redis 缓存 Nextcloud,我自己也不太懂原理,但官方既然推荐了就一起部署上啦

    version: '3'
    services:
      redis:
        image: redis
        container_name: redis
        hostname: redis
        restart: always
        networks:
          - nextcloud
        expose:
          - 6379
    

    记得要在 Nextcloud 对应的 config/config.php 中添加相关内容

      'memcache.local' => '\OC\Memcache\APCu',         #redis
      'memcache.distributed' => '\OC\Memcache\Redis',  #redis
      'memcache.locking' => '\OC\Memcache\Redis',      #redis
      'redis' => array(                                #redis
         'host' => 'redis',                            #如果 redis 部署在物理机上填 localhost,这里由于 redis 和 nextcloud 在同一网络 nextcloud 内,所以可用 redis 代替
         'port' => 6379,
         ),
    

    结语:

    onlyoffice 目前我个人测试只能在 Docker 内部 Nextcloud 使用,详细原因猜测是 onlyoffice 内置的 Nginx 没正确配置监听或允许外部网络域名访问(反正我软路由的另一个 Nextcloud 对接时显示 Connetion refused )

    我凭借着记忆将大致的搭建过程写了出来,难免会有所纰漏,烦请各位朋友查漏指正,有什么问题可以回复交流

    此外如果对过程中任何一部分有修正改进的建议,请务必告诉我,我对 Nginx、PHP、MySQL 参数调优真的是一窍不通

    牢骚话:

    有人可能会问为什么不干脆用 Linux 物理系统来搭,没辙啊,老爸只会用 windows,老妈想着吃饭时间连上去看 iqiyi 的电视剧,家里其他人又想摆一台公用的共享 NAS,我自己对 centOS 又不是特别熟悉,最后翻了一大堆的论坛帖子、网站文章自己摸索,目前也就只能这样先用着了

    其实最关键是没钱买群晖,而且家里人的要求比较杂,群晖不能很好地满足,于是这份攻略就诞生了

    曾经想过 ESXi 6.7 组建 FreeNAS + centOS + Docker (Nextcloud)+ Windows 7 的大虚拟机,把路由 LEDE 也虚拟化,从此就可以把那台软路由也扔掉,但后来发现搞不定 N 卡直通后给 Windows,重启虚拟机就带着 ESXi 一起死机的问题。据谷歌搜索说是因为 ESXi 6.7 在显卡第一次直通给虚拟机后关机时没能正常 reset 显卡状态,导致第二次虚拟机启动时显卡处于正在使用状态而带着宿主机一起 Boom,折腾了两天还是解决不了,随后我就放弃并滚回去用 windows 了

    总之……暂时告一段落

    15 回复  |  直到 2019-11-22 09:20:37 +08:00
        1
    wyxls   47 天前
    自查漏打一个细节问题,windows 系统下的 MySQL 8 默认密码认证插件为 caching_sha2_password,在上面所给的 MySQL for win64 + Nextcloud Container 环境下,给 Nextcloud 创建数据库用户的时候要留意主机名为 host.docker.internal,密码认证插件改为 mysql_native_password
        2
    wyxls   47 天前
    在实际使用过程中发现 Nextcloud 和 MySQL 对接的效率有点低,上网查了一下参数调优,胡乱一气都给调大了,想着 E3 1230 v3+32G ECC RAM 跑个 Nextcloud 效率应该不会太低吧

    ```
    #
    # 性能优化
    #
    # 允许最大连接数
    max_connections = 500
    # 响应的连接数,一般为最大连接数的 85%
    max_used_connections= 425
    # 索引块( index blocks )缓存的大小
    key_buffer_size = 128M
    # 允许服务器接受的数据包大小
    max_allowed_packet = 32M
    # 块数据插入缓存大小
    bulk_insert_buffer_size = 32M
    # 线程分配内存大小
    thread_stack = 256K
    # 线程缓存数量
    thread_cache_size = 16
    # 打开表格数量缓存
    table_open_cache = 1024
    ```

    大佬们如果有更好的优化参数请告诉我,秋梨膏
        3
    wq2016   47 天前
    我一个树莓派 3B+,跑无压力,同步盘使用。。。
        4
    wyxls   47 天前
    @wq2016 我这个问题出在大量的小文件同步,大概是 1 万 5 千多个 word、excel,用 windows 端的客户端同步的时候“检查远程变更”的效率很慢,不知道应该优化哪里才好
        5
    wq2016   47 天前
        6
    wq2016   47 天前
    @wyxls 我可能文件比你更多吧,我有 50G,都是工作文档,图片等等,excel
        7
    wyxls   47 天前
    @wq2016 我看了日志和 I/O 数据,感觉瓶颈是在 MySQL 那,我也翻到了一些用树莓派做 Nextcloud,他们大多都加大了 innodb cache 相关的参数。事实上我犯了个很弱智的错误,我初步搭建测试的时候 MySQL 的数据库放在了 5400 转的 HDD 里,过会我把数据库丢到 SSD 里再看看运行效率

    #默认 128M
    innodb_buffer_pool_size = 512M
    #默认 1
    innodb_buffer_pool_instance = 1
    #默认 2
    innodb_flush_log_at_trx_commit = 2
    #默认 16M
    innodb_log_buffer_size = 32M
    #默认 90
    innodb_max_dirty_pages_pct = 90
        8
    wq2016   47 天前
    @wyxls 我树莓派买的 256G 内存卡在跑
        9
    wyxls   47 天前
    upstream timed out (10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond) while reading response header from upstream

    运行过程中 nginx 的 log 总是有上述 error,因为在外部网络通过域名访问 Nginx 监听反向代理使用 localhost 作为 host name 时所有网络请求都会走一遍本地 DNS 解析或走 hosts,而 Win10 和 Server 2019 默认开启 IPv6 地址,解析的时候总是会尝试一遍 IPv6 访问,也就是[::1]

    解决方法是将 Proxy_pass 直接改成 127.0.0.1

    根据相关解释,在 hosts 里加入 127.0.0.1 localhost 应该也是可行的
        10
    wyxls   47 天前
    我个人是实在不知道为什么 Nextcloud Windows 客户端远程同步文件夹效率超级低下,甚至各种 Gateway time-out

    除了 Nextcloud 的数据保留外,将其余所有文件转移到 SSD 后,将 Docker for windows 的 CPU 数拉到 4,内存拉到 4G 后,2G 的大量小文件总算能正常同步了

    docker stats 里内存占用仅有 25%左右,但进到 Nextcloud 容器内 top 看到空闲内存仅剩 200MB,不太懂
        11
    ddup   46 天前 via Android
    我的树莓派 nextcloud 同步时老是系统卡死,是真的卡死不会活过来,在 nginx 里面限制了下并发数,看看后续效果。
        12
    wyxls   46 天前
    @ddup 我这 x86 的性能倒是不用考虑什么限制,但倒是不知道问题究竟出在哪里

    Nextcloud 的容器启动初期同步效率一点问题都没有,但在运行一段时间后就各种超时 504 gateway timeout,Web 访问也是跟着卡

    除了 windows 客户端同步之外就一点问题都没有
        13
    GSGUA   40 天前
    请问下是怎么将数据放到 windows 文件夹中的?
        14
    wyxls   40 天前
    @GSGUA 在 compose 中用 volume 将 windows 文件夹路径挂载到 container 里,记得 Docker 客户端需要将对应磁盘共享给 Docker Host
        15
    EvineDeng   21 天前 via Android
    我尝试使用 Windows Server 2019 自带的 Linux 子系统搭建 Nextcloud,同样遇到 0770 权限的问题,同样也是 chown chmod 都无法解决。是不是也可以照搬您这条忽略权限的代码?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   891 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 28ms · UTC 21:58 · PVG 05:58 · LAX 13:58 · JFK 16:58
    ♥ Do have faith in what you're doing.