更新1:在调试中发现发现 Windows Docker 和 MySQL for Windows 之间的互访有严重的问题,目前改用Docker容器构建MariaDB数据库,所有功能一切正常。修改一些过于啰嗦的描述。运行环境有改动。 #### 环境: ```plaintext 物理主机系统: Windows server 2019 Datecenter (v1809, 17763.805) Docker: Docker for windows 2.2.0.4 build 43472(Engine: 19.03.8, Compose: 1.25.4) Mariadb: Docker (mariadb:latest) Nginx: Docker (nginx:latest) Nextcloud: 18.0.2 (hub.docker.com/_/nextcloud, nextcloud:latest, nextcloud:apache, OS:Linux/amd64) 可选附加: Onlyoffice-document-server:Docker (onlyoffice/documentserver:latest) redis:Docker (redis:latest) ``` #### 前置工作 ##### Nextcloud镜像的选择 在官方Docker页面中主要版本有默认的Apache版和采用容器化Nginx的FPM版,在我个人实际搭建过程中FPM版的Nginx和宿主机windows之间隔着一层NAT,配置调试起来显得十分麻烦,故选择运行起来更简单的Apache版 ##### 容器间互访 将每个容器的网络加入同一外部Host网络就可以实现容器间通过service name互访 ```yaml networks: default: external: name: shared ``` ##### Docker for windows 安装是全自动创建Docker Host的Hyper-V虚拟机 ###### 创建共用网络 (关键) `docker network create shared` 这是后续MariaDB+NextCloud+Nginx互访工作的关键步骤 ##### MariaDB ###### MariaDB.yml ```yaml version: "3" services: mariadb: image: mariadb:latest container_name: mariadb command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb-flush-method=fsync environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=password # 必须, root账户的密码 - MYSQL_LOG_CONSOLE=true volumes: # 挂载数据存储路径,建议外置数据 - /C/Docker/mariadb:/var/lib/mysql # 挂载外置MariaDB配置文件 - /C/Docker/mariadb-conf/my.cnf:/etc/my.cnf restart: unless-stopped networks: - default # 一起搭建方便通过Web操作数据库 phpmyadmin: image: phpmyadmin/phpmyadmin:4.9.4 container_name: phpmyadmin environment: - TZ=Asia/Shanghai # 允许访问不同数据库 - PMA_ARBITRARY=1 # 默认访问上面的mariadb - PMA_HOST=mariadb restart: unless-stopped expose: - '80' ports: # 映射端口 - 8080:80 networks: - default networks: default: external: name: shared ``` ###### 部署数据库 通过docker exec -it mariadb bash进入容器内部使用命令操作数据库 ```shell #登入数据库 mysql -u root -p ``` 创建环境 ```sql # 创建数据库nextcloud create database nextcloud; # 创建用户nextcloud create user nextclouduser@% identified by 'password'; # 给nextcloud用户赋予数据库nextcloud所有权限 grant all privileges on nextcloud.* to nextcloud@% identified by 'password'; # 重载刷新权限 flush privileges; ``` #### 主体搭建部署 ##### NextCloud ###### NextCloud.yml ```yaml version: '3' services: redis: image: redis container_name: nextcloud-redis restart: unless-stopped networks: - default expose: - '6379' nextcloud: image: nextcloud container_name: nextcloud restart: unless-stopped depends_on: - redis environment: - TZ=Asia/Shanghai volumes: - /C/Docker/nextcloud:/var/www/html # NextCloud主程序存储路径 - /D/Docker/nextcloud/data:/var/www/html/data # NextCloud数据存储路径 expose: - '80' # 暴露80端口供Nginx反向代理用 ports: - 8080:80 # 转发8080端口至80端口 networks: - default networks: default: external: name: shared ``` 主程序挂载到外部是方便在Windows上修改程序配置以及保持程序与数据操作权限统一,但这样在NextCloud程序更新效率和运行效率上会打一点折扣,还会破坏镜像自身内置默认的以www-data运行的crontab,需要外部Windows配置计划任务运行cron.php 如果主程序路径选择volume挂载到Windows系统路径,那么在Docker容器中运行的Nextcloud默认以root用户权限运行,所以在访问时会提示设置权限chmod 0770,无论是chown还是chmod都无法解决,可通过强行忽略文件权限检查解决 ###### 忽略数据目录权限检查 在/var/www/html/config/config.php中加入以下内容 ```php #检查数据目录权限 'check_data_directory_permissions' => false, ``` ###### 添加可信任访问域名 在/var/www/html/config/config.php添加Trusted_Domains,不然Nextcloud的Web端无法访问 ```php 'trusted_domains' => array ( 0 => 'example.com', 1 -> 'localhost', ), ``` NextCloud初步搭建完成,通过 http://localhost:80 或 http://localhost:8080 访问NextCloud的Web界面进行初始化操作 ```plaintext 数据库用户名: nextcloud 数据库用户密码: password 数据库名: nextcloud 数据库Host: mariadb ``` ##### Nginx (HTTPS访问) ###### Nginx.yml ```yaml version: "3" services: nginx: image: nginx:latest container_name: nginx volumes: - /C/Docker/nginx/nginx.conf:/etc/nginx/nginx.conf # 外置Nginx配置文件 - /C/Docker/nginx/conf:/etc/nginx/conf.d # 外置Nginx配置文件 restart: unless-stopped ports: - 8081:443 # 转发10006端口至Nginx监听的443端口 networks: - default networks: default: external: name: shared ``` ###### NextCloud.conf ```nginx server { #Nginx监听端口 listen 443 ssl; #域名, IP, 本地地址都可以填写 server_name nc.example.com; # SSL证书路径 ssl_certificate /etc/ssl/cert.cer; # SSL私钥路径 ssl_certificate_key /etc/ssl/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 X-Content-Type-Options; proxy_hide_header X-Download-Options; proxy_hide_header X-Frame-Options; proxy_hide_header X-Permitted-Cross-Domain-Policies; proxy_hide_header X-Robots-Tag; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always; add_header Referrer-Policy "no-referrer"; add_header X-Content-Type-Options nosniff; add_header X-Download-Options "noopen"; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Permitted-Cross-Domain-Policies "none"; add_header X-Robots-Tag "none"; add_header X-XSS-Protection "1; mode=block"; client_max_body_size 10G; fastcgi_buffers 64 4K; fastcgi_hide_header X-Powered-By; # 反向代理, 通过service name访问 location / { proxy_pass http://nextcloud:80/; 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; proxy_buffer_size 64k; proxy_buffers 8 64k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location = /.well-known/host-meta { return 301 $scheme://$http_hostpublic.php?service=host-meta; } location = /.well-known/host-meta.json { return 301 $scheme://$http_host/public.php?service=host-meta-json; } #解决自检carddav未正常配置解析提示问题 location = /.well-known/carddav { return 301 $scheme://$http_host/remote.php/dav; } #解决自检carddav未正常配置解析提示问题 location = /.well-known/caldav { return 301 $scheme://$http_host/remote.php/dav; } #解决自检webfinger未正常配置解析提示问题 location = /.well-known/webfinger{ return 301 $scheme://$http_host/index.php/.well-known/webfinger; } #解决自检nodeinfo未正常配置解析提示问题 location = /.well-known/nodeinfo{ return 301 $scheme://$http_host/index.php/.well-known/nodeinfo; } 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:latest用Apache作为网页服务器监听HTTP 80端口,在Nginx反代中可能无法侦测正确的协议,需要添加参数强行覆写 在NextCloud程序目录的config/config.php中添加以下内容 ```php 'overwriteprotocol' => 'https', ``` 至此,NextCloud在公网可通过 https://example.com:8081/ 访问 #### 可选部分 ##### Onlyoffice-document-server Nextcloud官方提供连接onlyoffice服务的应用,与onlyoffice对接后能实现在NextCloud内直接Web访问打开并编辑office文档 (pptx, xlsx, docs等),通过Docker可以一键配置 ```yaml version: '3' services: onlyoffice-document-server: container_name: onlyoffice-document-server image: onlyoffice/documentserver:latest stdin_open: true restart: unless-stopped environment: - TZ=Asia/Shanghai # 启用HTTPS HSTS - ONLYOFFICE_HTTPS_HSTS_ENABLED=true # SSL证书路径 - SSL_CERTIFICATE_PATH=/var/www/onlyoffice/Data/certs/cert.cer # SSL私钥路径 - SSL_KEY_PATH=/var/www/onlyoffice/Data/certs/private.key - REDIS_SERVER_HOST=onlyoffice-redis - REDIS_SERVER_PORT=6379 deploy: resources: limits: cpus: '0.50' memory: 2048M volumes: # 外置log - /D/Docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice # 外置data - /D/Docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data # 挂载SSL证书和私钥路径 - /C/SSL-Certificates:/var/www/onlyoffice/Data/certs # 外置lib - /D/Docker/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice ports: - 8082:443 depends_on: - onlyoffice-redis networks: - default onlyoffice-redis: container_name: onlyoffice-redis image: redis:latest restart: unless-stopped networks: - default expose: - '6379' networks: default: external: name: shared ``` ###### 证书安装 1. 在/var/www/onlyoffice/Data中建立 "certs" 文件夹,将SSL证书 (cert.cer) 和私钥 (private.key)放入 2. 修改environment环境参数挂载路径中的文件名称 ```yaml environment: - SSL_CERTIFICATE_PATH=证书路径 - SSL_KEY_PATH=私钥路径 ``` 通过访问https://example.com:8082/ ,可以查看Document Server运行状况,显示 "Document Server is running" 表示成功 最后在Nextcloud的Onlyoffice连接应用中设置Document Editing Service address为https://example.com:8082/ 页面下方出现settings一系列选项则表示已成功连接 ##### Redis Nextcloud官方推荐使用Redis缓存Nextcloud,在上述NextCloud部分已经默认一同部署 ##### 邮件提醒 NextCloud可以使用现有的邮箱服务、用户发送提醒邮件,在网页界面—设置—基本设置—电子邮件服务器中配置 #### 结语 主要优点: - 提供了丰富的扩展可供安装 - 文件完整地存储在服务器上,方便直接复制备份 主要缺点: - 基于PHP,运行效率有折扣 Loading... <div class="tip share">请注意,本文编写于 2457 天前,最后修改于 1490 天前,其中某些信息可能已经过时。</div> 更新1:在调试中发现发现 Windows Docker 和 MySQL for Windows 之间的互访有严重的问题,目前改用Docker容器构建MariaDB数据库,所有功能一切正常。修改一些过于啰嗦的描述。运行环境有改动。 #### 环境: ```plaintext 物理主机系统: Windows server 2019 Datecenter (v1809, 17763.805) Docker: Docker for windows 2.2.0.4 build 43472(Engine: 19.03.8, Compose: 1.25.4) Mariadb: Docker (mariadb:latest) Nginx: Docker (nginx:latest) Nextcloud: 18.0.2 (hub.docker.com/_/nextcloud, nextcloud:latest, nextcloud:apache, OS:Linux/amd64) 可选附加: Onlyoffice-document-server:Docker (onlyoffice/documentserver:latest) redis:Docker (redis:latest) ``` #### 前置工作 ##### Nextcloud镜像的选择 在官方Docker页面中主要版本有默认的Apache版和采用容器化Nginx的FPM版,在我个人实际搭建过程中FPM版的Nginx和宿主机windows之间隔着一层NAT,配置调试起来显得十分麻烦,故选择运行起来更简单的Apache版 ##### 容器间互访 将每个容器的网络加入同一外部Host网络就可以实现容器间通过service name互访 ```yaml networks: default: external: name: shared ``` ##### Docker for windows 安装是全自动创建Docker Host的Hyper-V虚拟机 ###### 创建共用网络 (关键) `docker network create shared` 这是后续MariaDB+NextCloud+Nginx互访工作的关键步骤 ##### MariaDB ###### MariaDB.yml ```yaml version: "3" services: mariadb: image: mariadb:latest container_name: mariadb command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --innodb-flush-method=fsync environment: - TZ=Asia/Shanghai - MYSQL_ROOT_PASSWORD=password # 必须, root账户的密码 - MYSQL_LOG_CONSOLE=true volumes: # 挂载数据存储路径,建议外置数据 - /C/Docker/mariadb:/var/lib/mysql # 挂载外置MariaDB配置文件 - /C/Docker/mariadb-conf/my.cnf:/etc/my.cnf restart: unless-stopped networks: - default # 一起搭建方便通过Web操作数据库 phpmyadmin: image: phpmyadmin/phpmyadmin:4.9.4 container_name: phpmyadmin environment: - TZ=Asia/Shanghai # 允许访问不同数据库 - PMA_ARBITRARY=1 # 默认访问上面的mariadb - PMA_HOST=mariadb restart: unless-stopped expose: - '80' ports: # 映射端口 - 8080:80 networks: - default networks: default: external: name: shared ``` ###### 部署数据库 通过docker exec -it mariadb bash进入容器内部使用命令操作数据库 ```shell #登入数据库 mysql -u root -p ``` 创建环境 ```sql # 创建数据库nextcloud create database nextcloud; # 创建用户nextcloud create user nextclouduser@% identified by 'password'; # 给nextcloud用户赋予数据库nextcloud所有权限 grant all privileges on nextcloud.* to nextcloud@% identified by 'password'; # 重载刷新权限 flush privileges; ``` #### 主体搭建部署 ##### NextCloud ###### NextCloud.yml ```yaml version: '3' services: redis: image: redis container_name: nextcloud-redis restart: unless-stopped networks: - default expose: - '6379' nextcloud: image: nextcloud container_name: nextcloud restart: unless-stopped depends_on: - redis environment: - TZ=Asia/Shanghai volumes: - /C/Docker/nextcloud:/var/www/html # NextCloud主程序存储路径 - /D/Docker/nextcloud/data:/var/www/html/data # NextCloud数据存储路径 expose: - '80' # 暴露80端口供Nginx反向代理用 ports: - 8080:80 # 转发8080端口至80端口 networks: - default networks: default: external: name: shared ``` 主程序挂载到外部是方便在Windows上修改程序配置以及保持程序与数据操作权限统一,但这样在NextCloud程序更新效率和运行效率上会打一点折扣,还会破坏镜像自身内置默认的以www-data运行的crontab,需要外部Windows配置计划任务运行cron.php 如果主程序路径选择volume挂载到Windows系统路径,那么在Docker容器中运行的Nextcloud默认以root用户权限运行,所以在访问时会提示设置权限chmod 0770,无论是chown还是chmod都无法解决,可通过强行忽略文件权限检查解决 ###### 忽略数据目录权限检查 在/var/www/html/config/config.php中加入以下内容 ```php #检查数据目录权限 'check_data_directory_permissions' => false, ``` ###### 添加可信任访问域名 在/var/www/html/config/config.php添加Trusted_Domains,不然Nextcloud的Web端无法访问 ```php 'trusted_domains' => array ( 0 => 'example.com', 1 -> 'localhost', ), ``` NextCloud初步搭建完成,通过 http://localhost:80 或 http://localhost:8080 访问NextCloud的Web界面进行初始化操作 ```plaintext 数据库用户名: nextcloud 数据库用户密码: password 数据库名: nextcloud 数据库Host: mariadb ``` ##### Nginx (HTTPS访问) ###### Nginx.yml ```yaml version: "3" services: nginx: image: nginx:latest container_name: nginx volumes: - /C/Docker/nginx/nginx.conf:/etc/nginx/nginx.conf # 外置Nginx配置文件 - /C/Docker/nginx/conf:/etc/nginx/conf.d # 外置Nginx配置文件 restart: unless-stopped ports: - 8081:443 # 转发10006端口至Nginx监听的443端口 networks: - default networks: default: external: name: shared ``` ###### NextCloud.conf ```nginx server { #Nginx监听端口 listen 443 ssl; #域名, IP, 本地地址都可以填写 server_name nc.example.com; # SSL证书路径 ssl_certificate /etc/ssl/cert.cer; # SSL私钥路径 ssl_certificate_key /etc/ssl/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 X-Content-Type-Options; proxy_hide_header X-Download-Options; proxy_hide_header X-Frame-Options; proxy_hide_header X-Permitted-Cross-Domain-Policies; proxy_hide_header X-Robots-Tag; add_header Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" always; add_header Referrer-Policy "no-referrer"; add_header X-Content-Type-Options nosniff; add_header X-Download-Options "noopen"; add_header X-Frame-Options "SAMEORIGIN"; add_header X-Permitted-Cross-Domain-Policies "none"; add_header X-Robots-Tag "none"; add_header X-XSS-Protection "1; mode=block"; client_max_body_size 10G; fastcgi_buffers 64 4K; fastcgi_hide_header X-Powered-By; # 反向代理, 通过service name访问 location / { proxy_pass http://nextcloud:80/; 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; proxy_buffer_size 64k; proxy_buffers 8 64k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } location = /.well-known/host-meta { return 301 $scheme://$http_hostpublic.php?service=host-meta; } location = /.well-known/host-meta.json { return 301 $scheme://$http_host/public.php?service=host-meta-json; } #解决自检carddav未正常配置解析提示问题 location = /.well-known/carddav { return 301 $scheme://$http_host/remote.php/dav; } #解决自检carddav未正常配置解析提示问题 location = /.well-known/caldav { return 301 $scheme://$http_host/remote.php/dav; } #解决自检webfinger未正常配置解析提示问题 location = /.well-known/webfinger{ return 301 $scheme://$http_host/index.php/.well-known/webfinger; } #解决自检nodeinfo未正常配置解析提示问题 location = /.well-known/nodeinfo{ return 301 $scheme://$http_host/index.php/.well-known/nodeinfo; } 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:latest用Apache作为网页服务器监听HTTP 80端口,在Nginx反代中可能无法侦测正确的协议,需要添加参数强行覆写 在NextCloud程序目录的config/config.php中添加以下内容 ```php 'overwriteprotocol' => 'https', ``` 至此,NextCloud在公网可通过 https://example.com:8081/ 访问 #### 可选部分 ##### Onlyoffice-document-server Nextcloud官方提供连接onlyoffice服务的应用,与onlyoffice对接后能实现在NextCloud内直接Web访问打开并编辑office文档 (pptx, xlsx, docs等),通过Docker可以一键配置 ```yaml version: '3' services: onlyoffice-document-server: container_name: onlyoffice-document-server image: onlyoffice/documentserver:latest stdin_open: true restart: unless-stopped environment: - TZ=Asia/Shanghai # 启用HTTPS HSTS - ONLYOFFICE_HTTPS_HSTS_ENABLED=true # SSL证书路径 - SSL_CERTIFICATE_PATH=/var/www/onlyoffice/Data/certs/cert.cer # SSL私钥路径 - SSL_KEY_PATH=/var/www/onlyoffice/Data/certs/private.key - REDIS_SERVER_HOST=onlyoffice-redis - REDIS_SERVER_PORT=6379 deploy: resources: limits: cpus: '0.50' memory: 2048M volumes: # 外置log - /D/Docker/onlyoffice/DocumentServer/logs:/var/log/onlyoffice # 外置data - /D/Docker/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data # 挂载SSL证书和私钥路径 - /C/SSL-Certificates:/var/www/onlyoffice/Data/certs # 外置lib - /D/Docker/onlyoffice/DocumentServer/lib:/var/lib/onlyoffice ports: - 8082:443 depends_on: - onlyoffice-redis networks: - default onlyoffice-redis: container_name: onlyoffice-redis image: redis:latest restart: unless-stopped networks: - default expose: - '6379' networks: default: external: name: shared ``` ###### 证书安装 1. 在/var/www/onlyoffice/Data中建立 "certs" 文件夹,将SSL证书 (cert.cer) 和私钥 (private.key)放入 2. 修改environment环境参数挂载路径中的文件名称 ```yaml environment: - SSL_CERTIFICATE_PATH=证书路径 - SSL_KEY_PATH=私钥路径 ``` 通过访问https://example.com:8082/ ,可以查看Document Server运行状况,显示 "Document Server is running" 表示成功 最后在Nextcloud的Onlyoffice连接应用中设置Document Editing Service address为https://example.com:8082/ 页面下方出现settings一系列选项则表示已成功连接 ##### Redis Nextcloud官方推荐使用Redis缓存Nextcloud,在上述NextCloud部分已经默认一同部署 ##### 邮件提醒 NextCloud可以使用现有的邮箱服务、用户发送提醒邮件,在网页界面—设置—基本设置—电子邮件服务器中配置 <img src="/usr/uploads/images/搭建NextCloud-WinServer-2019-Docker-for-Windows/NextCloud邮件SMTP配置.png" style="zoom:100%;" /> #### 结语 主要优点: - 提供了丰富的扩展可供安装 - 文件完整地存储在服务器上,方便直接复制备份 主要缺点: - 基于PHP,运行效率有折扣 最后修改:2022 年 10 月 12 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏