书签

你还没有保存任何书签. 要将某篇文章加入书签, 请点击

  • Docker 搭建私有云 Nextcloud

  • 前言

    本文是 Docker 系列的第二篇,对之前发布的 Nextcloud 搭建教程进行了修改和完善并重新发布。

    本文要实现的目标是快速搭建一个配置好 SSL 证书的 Nextcloud 服务器,不占用主机443端口,非常适合建站的朋友在主站之外使用诸如cloud.domain.com的子域名为自己搭建云存储服务,用于小范围的快速文件分享或者个人文件存储。

    网络上有很多 Nextcloud 搭建方法,本文完全采用 Nextcloud 官方提供的 docker-compose 方式,搭建完成后使用 nginx 配置端口转发及 SSL 证书。

    搭建完成体验地址:点击访问
    用户名 guest 密码 Guest12345


    搭建方法

    Docker Hub上有很多 Nextcloud 的镜像,经过试用,最终选择了官方镜像。

    Nextcloud 的官方 Github 页面有着详细的使用说明,并提供了多样化的选择,可以查看这个页面并根据自己的需求选择使用。

    官方 Github 页面上提供的 docker-compose 文件很完善,基本无须任何修改,我们就可以在我们的服务器上搭建起 Nextcloud 服务。本文中使用的是insecure/mariadb-cron-redis/fpm/目录下的docker-compose文件,地址在这里

    选择 insecure, 是因为自动配置SSL容易出错,并且如果不把容器 443 端口直接映射到主机443 端口,仍然需要其他 Web 服务器进行端口转发,而进行转发的 Web 服务器同样需要配置 SSL。

    具体步骤如下:

    将官方提供的 docker-compose 文件下载到服务器

    由于 git 无法通过 git clone 下载单个文件夹,我们通过 wget 结合文件原始地址逐一下载,具体方式是——在本地新建对应的文件夹,进入文件夹后,wget+ 对应文件夹中文件链接,具体步骤如下:

    mkdir -p ~/docker/docker-compose/nextcloud
    cd ~/docker/docker-compose/nextcloud
    
    mkdir web
    cd web
    wget https://raw.githubusercontent.com/nextcloud/docker/master/.examples/docker-compose/insecure/mariadb-cron-redis/fpm/web/Dockerfile
    wget https://raw.githubusercontent.com/nextcloud/docker/master/.examples/docker-compose/insecure/mariadb-cron-redis/fpm/web/nginx.conf
    
    cd ..
    wget https://raw.githubusercontent.com/nextcloud/docker/master/.examples/docker-compose/insecure/mariadb-cron-redis/fpm/db.env
    wget https://raw.githubusercontent.com/nextcloud/docker/master/.examples/docker-compose/insecure/mariadb-cron-redis/fpm/docker-compose.yml
    

    其中具体文件的下载地址,可以通过在 Github 该文件页面,点击 Raw 之后获得

    使用 docker-compose BUILD 镜像并运行

    完成上面的操作后,我们就已经将整个官方提供的 docker-compose 示例复制到了我们的服务器上,我们只需将配置文件中的内容补全,之后 BUILD 后运行即可,要修改的地方共有两处:
    docker-nextcloud-build1.png
    docker-nextcloud-build2.png

    因为下面的操作我们需要使用 docker-compose,如果提示未安装,请先进行安装:

    sudo apt-get update
    sudo apt-get install docker-compose
    

    之后BUILD镜像并运行:

    docker-compose build --pull
    docker-compose up -d
    

    这里需要注意,可能会提示 version 错误,根据使用的 Docker 版本不同,可能需要将 docker-compose.yml 第一行的 version: '3' 改为 version: '2',关于 version 的使用可以参考官方文档

    docker-nextcloud-build3ch.png

    所有容器正常运行,此时访问http://服务器IP:8080就可以进入Nextcloud界面,此时创建一个用户就可以进入Nextcloud文件管理界面。

    docker-nextcloud-success1.png
    docker-nextcloud-success2.png

    通过 Portainer 中的 Logs 可以看到容器运行正常,数据库连接正常,我们已经可以正常上传下载分享文件,但关键的工作还未完成,主要包括:

    • 申请 SSL 证书
    • 修改 nginx 配置文件实现端口转发及 HTTPS 访问

    申请 SSL 证书

    HTTPS 取代 HTTP 是大势所趋,随着 Let's Encrypt 等免费 SSL 证书的出现,越来越多的网站开始为自己加上一把小锁,安全之外还多一份美观,既然免费,我们怎么有理由拒绝,本部分将使用 Cerbot 来申请 Let's Encrypt 提供的免费通配符证书。

    获取 Certbot 客户端

    使用 wget 获取 Cerbot客户端:

    wget https://dl.eff.org/certbot-auto
    

    增加可执行权限:

    chmod a+x certbot-auto
    

    申请证书

    之后执行以下命令即可开始申请免费SSL证书:

    
    ./certbot-auto certonly -d "*.betas.me" --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
    

    注意将betas.me替换成你的域名。

    docker-nextcloud-ssl1.png

    根据提示填写即可,最后一步需要到你的域名管理页面添加一个TXT类的解析,Host名名是_acme-challege,值为下面一行所提供的:

    docker-nextcloud-ssl2.png

    去你的域名管理页面添加即可,添加后请稍等片刻待DNS生效即可,经测试一般几分钟就可以,之后点击回车确认即可,如果正确添加了 TXT 解析值,就会提示 SSL 证书申请成功。

    可以看到 SSL 证书保存在 /etc/letsencrypt/live下,但要注意的是live下保存的实际上是软连接,原文件位置是在/etc/letsencrypt/archive文件夹下,如果我们直接绑定/etc/letsencrypt/live到容器,容器将会因无法找到链接文件而报错,所以我直接将/etc/letsencrypt目录绑定到容器。

    替代选择:通过网页手动申请 SSL 证书

    如果你运行 Certbot 出错或者其他原因无法申请成功,可以前往 Freessl 进行申请,可以选择 TrustAsia 提供的一年免费的单域名证书或者 Let's Encrypt 提供的三个月通配符证书。

    docker-nextcloud-freessl.png

    证书申请完成后,因所有证书文件均为纯文本内容,可通过在服务器新建对应文件后,复制文件内容的形式将证书复制至服务器,也可以通过 FTP 方式复制至服务器。


    配置 SSL

    在部署 Nextcloud 服务时,已经包含了一个 nginx 容器,完全可以通过将该 nginx 的配置文件绑定主机文件并进行修改来实现HTTPS访问,但这种情况下,一般需要将容器内的443端口直接映射到主机443端口,否则访问时必须以https://域名:端口号的形式,还是需要主机内其他Web服务器进行端口转发。

    所以,我推荐不通过 Nextcloud 中的 nginx 配置 HTTPS,而是直接通过在主机内再运行一个 nginx(当然你也可以选择其他Web服务器),并直接在该 nginx 内进行 HTTPS 配置以及端口转发。

    配置 Nextcloud 容器外 nginx 端口转发

    大部分读者在架设 Nextcloud 之前 已经部署过其他服务,一般也已经安装了 nginx 等 Web 服务器,443端口已经处于被占用状态,所以通过上一部分的做法时不得不通过增加端口号来访问,最后还是需要在容器外增加端口转发,所以我建议直接使用本部分的方法。

    Nextcloud 容器外既可以是非 Docker 环境的 nginx 也可以是 Docker 环境中的另一个 nginx ,这里我们同样采用容器,我们要实现的目标是将 http://服务器IP:8080 转发到https://cloud.betas.me。

    如果你已经搭建过 nginx 服务,请直接参考修改 nginx 配置文件即可。

    如果你还未搭建 nginx 服务,可以通过 Docker 创建一个新的 nginx 容器,请注意以下目录绑定根据实际情况修改:

    请参考本博客的这篇文章

    docker run -d --name nginx \
    -v /root/docker/nginx:/etc/nginx \
    -v /root/wwwroot:/usr/share/nginx/html \
    -v /etc/letsencrypt:/etc/letsencrypt \
    -p 80:80 \
    -p 443:443 \
    nginx
    

    之后我们在 /root/docker/nginx/conf.d 目录下新建一个cloud.域名.conf 文件,内容如下:

    server {
           listen 443 ssl http2;
           server_name cloud.betas.me;
           ssl_certificate /etc/letsencrypt/live/betas.me/fullchain.pem;
           ssl_certificate_key /etc/letsencrypt/live/betas.me/privkey.pem;
           ssl_trusted_certificate  /etc/letsencrypt/live/betas.me/chain.pem;
           ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
           ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
                    ssl_prefer_server_ciphers on;
                    ssl_session_cache shared:SSL:10m;
                    ssl_session_timeout 30m;
           add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    
        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://服务器IP:8080;
        }
    }
    
    

    之后重启 nginx 容器,即可实现通过https://cloud.betas.me 访问 Nextcloud服务:

    docker-nextcloud-finish2.png


    其他配置

    在完成 Nextcloud 服务搭建后,我们发现存在几个问题:

    • 无法上传较大文件
    • 在 Nextcloud 管理后台中的管理-概览中出现警告:
      docker-nextcloud-warning.png

    下面我们解决这两个问题:

    修改 nginx 配置以上传大文件

    上传文件大小限制,主要由 nginx 配置文件中的client_max_body_size的值决定,其默认值为 1M,我们根据需求调整其大小:

    docker-nextcloud-bodysize.png

    直接修改 nginx 配置文件目录下的 nginx.conf 文件,增加如上图所示红色内容:

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 8000m;
    

    各项的值可以根据需求修改。

    之后重启 docker 镜像即可:

    docker restart nginx
    

    解决后台警告

    我们需要修改之前添加的cloud.域名.conf文件,增加两条规则:

     location = /.well-known/carddav {
            return 301 $scheme://$host/remote.php/dav;
        }
    
       location = /.well-known/caldav {
            return 301 $scheme://$host/remote.php/dav;
        }
    

    将以上内容添加至 cloud.域名.conf文件下的 server 部分即可。

    添加完成后重启 nginx 容器:

    docker restart nginx
    

    再去后台查看,警告已经消失。