将 ownCloud 迁移到 Docker 容器
继之前将博客迁移到 Docker 容器后,最近由于我在 Vultr 的 ownCloud 服务器性能出现严重问题,甚至在同步时出现宕机,我终于抽空把 ownCloud 迁移到了 HostDare 的VPS。总体来说迁移过程是非常简单的,而 ownCloud 也提供了官方的 Docker 支持,下面我会分享从零开始到HTTPS加密等具体的步骤。
致谢:本文思路主要来自于官方手册、官博文章、以及众多的 StackOverflow 问答,在此表示感谢。
1 准备工作
- 一台能胜任工作的 VPS
- 什么叫“能胜任工作”?这里说点题外话,之前在 Vultr 的VPS只有1vCPU/250G HDD/1G的配置,这也导致了网页访问缓慢和突发需求时宕机。再加上 Vultr 家没有特别的网络线路,导致使用起来非常的糟心。
- 本文使用 Ubuntu 22.04 LTS,当然别的发行版也没问题,毕竟是 Docker。但是配置的路径等差别就需要朱军自己来判断了
- 防火墙开通 80、443 和 8080 端口
- SSH
sudo
访问权限到原始机器和目标机器 - (可选)如果需要HTTPS的话,需要开通域名并解析到你的目标机器
ownCloud 官方的 Docker 容器中已经包含了 MariaDB 数据库和 Redis 缓存,配置完成后即可使用,无需额外操心。
2 在目标机器上安装 Docker
这里可以打开官方文档,选择自己服务器的发行版,然后按照文档上的步骤进行安装。
请注意,如果你是以非 root
身份运行下面的脚本,安装完成后可以将自己加到 docker
用户组内,这样无需使用 sudo
也可以执行 Docker 命令
以 Ubuntu 为例:
|
|
完成后重新登录或者重启机器,让新权限生效。
另外,可以将 Docker 设为自动启动,这样服务器重启后 Docker 会一起启动。
|
|
3 配置并运行 ownCloud 容器
在进一步操作之前,我们需要新建一个文件夹来存放配置文件。可以放在任何地方。
example
等字样均为示例,需要替换成你自己的内容。
|
|
完成后,从官方 GitHub 下载 docker compose 配置文件并创建一个 .env
文件来安全储存需要的环境变量。
|
|
接下来运行 docker compose 并测试 ownCloud 是否正常工作
docker compose up -d
初次启动时可能需要一些时间,你可以通过执行以下命令来了解容器的运行状态
docker ps
当三个容器(ownCloud、MariaDB、Redis)的状态 (Status) 都显示 Healthy 的时候,就可以继续下一步了。
3.1 验收初步成果
很简单,浏览器打开 example.com:8080
(或者IP地址:8080
),查看 ownCloud 是否正常运行。
正常情况下应该看到的页面
到这里为止我们的 ownCloud 实例已经正常工作了。当然,如果这么简单的话我也不会专门写一篇文章。接下来我们要做的就是迁移数据并为我们的实例申请免费的 Let’s Encrypt 证书。
4 迁移资料和数据库
4.1 【原始机器】导出数据库
首先,将原始机器的 ownCloud 进入维护模式。
sudo -u www-data ./occ maintenance:mode --on
然后执行以下命令,导出 ownCloud 相关的数据库。回车后你会被要求输入数据库用户的密码。请根据自己服务器的实际情况修改用户名和数据库名称。
mysqldump --single-transaction -h localhost -u example -p exampleDB > owncloud-dbbackup_`date +"%Y%m%d"`.bak
(ownCloud安装目录)/config/config.php
里找到。相关字串有:
dbname
、dbhost
、dbuser
、dbpassword
。4.2 【目标机器】确定 ownCloud 映射的目录
如果你仔细观察官方提供的 yml 文件,你会发现 ownCloud 实例使用了一个 volume
命令创建和本地磁盘的映射,这样我们的文件就不会在 Docker 容器退出后消失。那么文件究竟在哪呢?下面是 yml 文件的一个节选:
|
|
那么我们的文件在哪里呢?事实上他们被存放在了 /var/lib/docker/volumes/(ownCloud 实例名)_files
。具体的文件夹名称似乎是根据你在第二步时候文件夹起的名字决定的(需要DP)。接下来的教程里我们假设 ownCloud 文件储存在 /var/lib/docker/volumes/example_files
。
4.3 【目标机器】进入维护模式
由于我们新的 ownCloud 实例在 Docker 容器里,正常 bash 里的命令是不会影响容器的。我们需要先进入 ownCloud 容器的 bash。
首先,cd
到你 docker-compose.yml
的目录,然后执行
docker compose exec owncloud occ maintenance:mode --on
如果我们需要和 ownCloud 容器交互,只需要
cd
到 ownClouddocker-compose.yml
的目录- 在命令前面加
docker compose exec owncloud
4.4 【原始机器】用 rsync 复制文件
现在我们知道了复制的目的地,就可以开始着手复制了。
仔细观察以下不难发现,
原始机器的 (ownCloud安装目录)/data
对应的是
目标机器的 /var/lib/docker/volumes/example_files/_data/files
由于二者文件夹路径不一样,我们复制的时候要多加小心。
执行以下命令:
cd (ownCloud安装目录)
rsync -azvP --exclude 'owncloud.log' data/* root@(目标机器IP):/var/lib/docker/volumes/example_files/_data/files
回车后,你会被要求输入目标机器 root
账户的密码。
复制的过程可能会有数十分钟甚至数小时,取决于你文件的大小、目标和原始机器的带宽等。不如开局 DOTA、去R6反反恐、下楼散个步… 你可以用同样的方法传输数据库的备份文件,在此不再赘述。
rsync 是很多 Linux 发行版内置的一个同步/备份软件。简单解释一下参数:
-a
:存档模式,等于 -rlptgoD
。这样会复制子目录、保留软链接、权限、修改日期、用户组、拥有人、设备文件、特殊文件-z
:启用压缩。(虽然效果可能只是个位数百分比,但好歹也是宝贵的流量呀)-v
:众所周知的“啰嗦模式”-P
:保存部分传输的文件并显示进度--exclude 'xxx'
:不要传输特定的文件/文件夹。在这里我们不需要传输 owncloud.log
,节省可观的时间和流量。(你是不会相信我的log文件竟然有10G多大!)
4.5 【目标机器】导入配置参数和数据库备份
首先修改以下文件:/var/lib/docker/volumes/example_files/_data/config/config.php
找到以下字串:passwordsalt
和 secret
。从原始机器的配置文件中复制并覆写这两个字串(否则用户将无法登录)。然后执行以下命令导入数据库:
docker compose exec owncloud mysql -h db -u owncloud -p owncloud < ~/owncloud-dbbackup_xxxxx.bak
你会被要求输入密码,默认是 owncloud
。
4.6 【目标机器】一些扫尾工作
执行这个命令让服务器重新扫描所有用户的文件。否则你的文件不会出现在客户端:
docker compose exec owncloud occ files:scan --all
执行以下命令通知客户端服务器已经迁移:
docker-compose exec owncloud occ maintenance:data-fingerprint
经过以上步骤你的文件和配置应该已经完美导入到新的服务器了。
5 用 Traefik 实现反代和 HTTPS
本来呢我是想请出我们的老熟人 Nginx 的,但是经过研究发现有个更好、更方便的方案,下面给大家介绍一下。
5.1 准备工作
首先创建一个 Traefik 的文件夹,类似我们 ownCloud 的文件夹,用来存放配置。接下来我们以 /srv/traefik
为例
|
|
5.2 创建 Docker 网络
在 Docker 新建一个专用的“局域网”,这样可以分隔出反代网站的流量。(名字可以随便起,我们接下来用 traefik_proxy
作为示范。
docker network create traefik_proxy
5.3 修改 Traefik 配置
编辑 /srv/traefik/compose.yml
,复制进去以下内容
|
|
下面稍微解释一下配置内容。
- 第 10 行的
traefik_proxy
需要和之前创建的网络名称对应。 - 31 行 - 33 行的
port
将主机的 80、443 端口映射到 Traefik 容器 80、443 端口,用作 HTTP 访问。- 事实上 Traefik 是用户和你服务器上各种服务/网站的一个中间人(代理)。每当用户访问你的网站时,Traefik 会根据用户请求的网址等条件将相对应的服务/网站呈现给用户。Image from Traefik.io
- 16 行启用 Docker 反代,18 行默认禁用 Docker 代理,这样 Traefik 不会自动反代所有的 Docker 容器。Traefik 支持多种后端,包括 Docker、Kubernetes、静态文件等。通过第 36 行,我们把系统的 Docker socket 暴露给 Traefik,这样 Traefik 可以自动监听 Docker 容器的启动/停止等事件并配置反代。
- 23 - 29 行配置了 Let’s Encrypt 的证书。Traefik 集成了 Let’s Encrypt,并且可以自动给所有反代的服务申请证书。 这里我们使用 HTTP Challenge,可以兼容 CloudFlare 等 CDN。
- 最后三行使用了
traefik_proxy
这个“外部”网络。这里的外部不是指互联网,而是“这个docker-compose配置之外”。
5.4 将 ownCloud 接入 Traefik
接下来就是修改 ownCloud 的 yml 文件,接入 Traefik。由于修改地方比较多,在这里我贴上完整的 yml 文件,供大家参考。
|
|
可以看到,在 43-56 行,我们做的事情主要有:
将 ownCloud 加入先前创建的 Traefik 反代网络里。
通过
labels
指令启用了 Traefik 对 ownCloud 容器的反代。由于之前的配置,我们必须特别指定启用反代,否则 Traefik 会无视这个 ownCloud 实例。设定 HTTP 路由规则:任何访问
owncloud.example.com
域名的用户都会进到这个 ownCloud 实例。另外我们还加入了 HTTP 到 HTTPS 的重定向。创建了名为
owncloud_internal
(你可以用别的名字)的“内网”并把 ownCloud、Redis 和 MariaDB 容器添加进去。 因为我们不需要,也不应该把 Redis 和 DB 暴露给外面,我们完全可以把他们另外加到一个“内部”网络,让他们在这个网络里通信。对于 Traefik(和用户)来说,Redis 和 DB 是透明的,他们只看到 ownCloud。如果你还是有点困惑的话,那下面请参看我用幼儿园水平画的一个示意图。
5.5 扫尾工作
重启 ownCloud 服务器让配置生效 – cd
到 ownCloud yml 文件的目录,然后执行
docker compose up -d
如果没有问题的话,在ownCloud 启动完毕后 Traefik 会自动将其反代并申请 HTTPS 证书。
恭喜!现在你应该有一个 Docker 化、Let’s Encrypt 证书加密的 ownCloud 实例了。
6 后期维护
6.1 升级 ownCloud
相信大家已经感受到了 Docker 带来的便利,那么在 ownCloud 新版本释出后,如何更新呢?这非常简单,因为我们在 yml 里面(其实是 .env
里面)定义的 ownCloud 版本是 latest
(即最新版),我们只需要 cd
到 ownCloud 所在的文件夹,执行
docker compose pull
docker compose up -d
就更新完毕。
同理,我们可以用这个方法去升级 Traefik。
6.2 备份 ownCloud 文件
ownCloud 的文件和配置都在 /var/lib/docker/volumes/example_files/_data/
文件夹下,分别是 config
和 data
两个文件夹。
如果需要备份的话你可以用 rsync + cron 或者其他办法。
这篇教程就到此为止,由于编写仓促,如果我有遗漏的地方,或者你有更多问题,欢迎在下面评论。
相关内容
如果你喜欢这篇文章,欢迎给我买杯咖啡 :)