自从开始使用docker以后,不管遇到什么项目,总想看看有没有相应的docker镜像。享受那种输入一连串命令,然后回车一键完成的快感。正好前段时间搞了个软路由,在上边虚拟了一个黑群晖,可惜,无奈自己没有公网,玩了一阵之后就闲置了。不过最近发现以前注册的一个半公益内网穿透用着效果还不错,于是乎就想搭个网盘玩玩。
然后我就上网搜了下好用的免费网盘,但找来找去发现还是之前有上手过的NextCloud
和Cloudreve
比较适合我,然后我又发现Cloudreve
貌似现在打包成一个可执行文件了,而我原本想在群晖上边的宝塔(当然也是docker版)里边安装的,所以最后还是选择了NextCloud
。
当然用宝塔安装就非常简单:建站-上传-解压-访问-安装,一下子就好了,用着效果还不错,然后我又想到了dock而版本,所以下边我就来说说,怎样用docker来安装这一整套服务(包括内网穿透)。
安装Docker
根据自己的系统,选择对应的方式。
1 2 3 4 5 6 7 8 9 10 11
| #CentOS 6 rpm -iUvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum update -y yum -y install docker-io service docker start chkconfig docker on
#CentOS 7、Debian、Ubuntu curl -sSL https://get.docker.com/ | sh systemctl start docker systemctl enable docker
|
当然新系统可能会提示没有curl
,自己安装一下就好。
1 2 3 4
| #Centos yum update && yum install curl -y #Debian , Ubuntu apt-get update && apt-get install curl -y
|
准备工作
Portainer
首先安装一个能可视化管理docker容器的容器Portainer
方便后边可能用到的操作。
拉取Portainer
1
| docker pull portainer/portainer-ce
|
启动Portainer
1 2 3 4 5 6 7
| docker run -d \ -p 9000:9000 \ --name portainer \ --restart=unless-stopped \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /home/portainer/data:/data \ portainer/portainer-ce
|
Cecos-Caas
如果你不习惯英文版的Portainer,可以试试基于Portainer的全中文的Cecos-Caas
这两个可以同时存在,只需要保证映射到外部的端口不同就行了。接着访问 http://ip:9000 根据提示完成首次注册安装。
准备好需要的镜像
为节约时间,方便后边的操作,这一步开始你就可以先把需要到的镜像全部拉取到本地,后边就可以直接使用了。
数据库 - MariaDB
1
| docker pull mariadb:latest
|
主程序 - NextCloud
1
| docker pull nextcloud:latest
|
反向代理 - Nginx
1
| docker pull nginx:alpine
|
证书申请 - Acme.sh
1
| docker pull guillaumedsde/acme.sh:latest
|
内网穿透 - Frpc
1 2 3 4
| #amd64 docker pull leonismoe/frpc:latest #arm64 docker pull leonismoe/frpc:arm64-latest
|
开始搭建
安装数据库
尽管NextCloud
支持Sqlite
,但是以防万一还是选择MariaDB
(官方MySQL镜像不支持arm)
1 2 3 4 5 6 7 8 9 10 11 12
| docker run -d \ -p 8306:3306 \ #映射出去的端口 --name mariadb \ -v $home/mariadb/data:/var/lib/mysql \ # 映射数据库路径 -e MYSQL_ROOT_PASSWORD=rootpassword \ #root密码 -e MYSQL_DATABASE=databasename \ #新建一个数据库 -e MYSQL_USER=username \ #新建用户 -e MYSQL_PASSWORD=userpassword \ #用户密码 --restart=unless-stopped \ mariadb:latest \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| mkdir -p /home/docker/mariadb/data docker run -d \ -p 8306:3306 \ --name mariadb \ -v /home/docker/mariadb/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=159753 \ -e MYSQL_DATABASE=nextcloud \ -e MYSQL_USER=nextcloud \ -e MYSQL_PASSWORD=159753 \ --restart=unless-stopped \ mariadb:latest \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci
|
安装NextCloud
运行容器:
1 2 3 4 5 6 7 8 9 10 11
| docker run -d \ --name nextcloud \ --link mariadb:mariadb \ # 把数据库连接起来 -v nextcloud:/var/www/html \ # 程序主目录 -v apps:/var/www/html/custom_apps \ # 应用及插件 -v config:/var/www/html/config \ # 本地配置文件 -v data:/var/www/html/data \ # 网盘文件位置(强烈建议将其映射到外置硬盘或U盘) -v theme:/var/www/html/themes/<YOUR_CUSTOM_THEME> \ # 主题目录 -p 8380:80 \ --restart=unless-stopped \ nextcloud:latest
|
这里我用了--link
的方式将容器连接起来,当然你也可以新建一个网络,然后把这些容器都放进去。
例如:
1 2
| docker network create nextcloud # 不指定类型默认创建 bridge docker network create -d overlay # 也可以用参数`-d`来指定类型
|
想了解更多docker网络可以点击查看
在创建好网络之后,运行容器的时候指定一下就可以了。
例如:
1 2 3 4 5 6 7
| docker run -d \ --name nextcloud \ --network nextcloud \ # 指定网络名称 --network-alias nextcloud \ # 指定其在该网络下的别名 -v /media/SystemOS/nextcloud/www/html:/var/www/html \ -p 8380:80 \ nextcloud:latest
|
但这里我不用这种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| # 在外置硬盘上新建好存储目录(记得更改`xxx`) mkdir -p /media/xxx/docker/nextcloud 或者 mkdir -p /mnt/xxx/docker/nextcloud 或者 mkdir -p /volume1/xxx/docker/nextcloud
docker run -d \ --name nextcloud \ --link mariadb:mariadb \ -v /media/xxx/docker/nextcloud/nextcloud:/var/www/html \ -v /media/xxx/docker/nextcloud/apps:/var/www/html/custom_apps \ -v /media/xxx/docker/nextcloud/config:/var/www/html/config \ -v /media/xxx/docker/nextcloud/data:/var/www/html/data \ -p 8380:80 \ --restart=unless-stopped \ nextcloud:latest # 当然也可以不分类,直接放一个目录 docker run -d \ --name nextcloud \ --link mariadb:mariadb \ --restart=unless-stopped \ -v /media/xxx/docker/nextcloud/www/html:/var/www/html \ -p 8380:80 \ nextcloud:latest
|
至此,本地的NextCloud
就可以通过 http://ip:8380 访问了。

依次填写好用户名
还有密码
点击存储与数据库
选择中间那个,如下图按照之前设定好的信息填入。

安装即可,这大概会花费一点时间。
如果你有公网ip那么不用继续看了,直接用Caddy反代自动续签ssl就可以了;如果没有或者想用内网穿透的方式咱们就继续吧!
装好之后基本上就可以使用了,但是这样不支持https,这是就需要nginx出场了。
Nginx反向代理
这个其实很简单,改一改配置文件就可以了。
首先是运行容器:
1 2 3 4 5 6 7 8
| docker run -d \ --name nginx \ --link nextcloud:nextcloud \ # 也可以不用link直接外部链接或者`--network host`主网络模式 --restart=unless-stopped \ -p 8480:80 \ -p 8443:443 \ -v /media/SystemOS/nginx/conf.d:/etc/nginx/conf.d \ # 配置文件所在目录 nginx:alpine
|
然后新建一个配置文件default.conf
填入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| server { listen 80; listen 443 ssl http2; server_name pan.nerocats.com; if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } ssl_certificate /etc/nginx/conf.d/cert/fullchain.pem; ssl_certificate_key /etc/nginx/conf.d/cert/privkey.pem; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000" always; error_page 497 https://$host$request_uri; location / { proxy_pass http://nextcloud; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } location = /.well-known/carddav { return 301 $scheme://$host:$server_port/remote.php/dav; } location = /.well-known/caldav { return 301 $scheme://$host:$server_port/remote.php/dav; }
error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
|
1 2 3 4 5 6 7 8 9
| mkdir -p /media/xxx/docker/nginx/conf.d/cert docker run -d \ --name nginx \ --link nextcloud:nextcloud \ --restart=unless-stopped \ -p 8480:80 \ -p 8443:443 \ -v /media/xxx/docker/nginx/conf.d:/etc/nginx/conf.d \ nginx:alpine
|
接着新建文件:
1
| vi /media/xxx/docker/nginx/conf.d/default.conf
|
按下i
,输入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| server { listen 80; listen 443 ssl http2; server_name localhost; if ($server_port !~ 443){ rewrite ^(/.*)$ https://$host$1 permanent; } ssl_certificate /etc/nginx/conf.d/cert/fullchain.pem; ssl_certificate_key /etc/nginx/conf.d/cert/privkey.pem; ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000" always; error_page 497 https://$host$request_uri; location / { proxy_pass http://nextcloud; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; } location = /.well-known/carddav { return 301 $scheme://$host:$server_port/remote.php/dav; } location = /.well-known/caldav { return 301 $scheme://$host:$server_port/remote.php/dav; }
error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
|
然后按Esc
输入:wq
回车。
现在反代就算是弄好了,但是别急着重启Nginx,那样会报错,因为还没部署好证书。
申请证书
其实证书可以自己手动申请,但是!我不喜欢。所以我就用acme.sh来自动申请+部署。
1 2 3 4 5 6 7 8
| docker run -itd \ -v /media/xxx/docker/acme.sh/out:/acme.sh \ -eAli_Key=1111111111111 \ # 阿里云 key -eAli_Secret=2222222222222222222222 \ # 阿里云 密钥 --network host \ --entrypoint /bin/sh \ --name=acme.sh \ guillaumedsde/acme.sh
|
阿里云的API key以及其他域名解析商的API key的获取方式请看这里
然后就是申请&安装证书:
1 2 3 4 5 6 7 8
| # 进入容器 docker attach acme.sh # 申请证书 acme.sh --issue --dns dns_ali -d example.com # 安装证书 acme.sh --install-cert -d example.com \ --key-file /acme.sh/privkey.pem \ --fullchain-file /acme.sh/fullchain.pem
|
这一步也可以在Portainer
或者Cecos-Caas
上边完成。
接着把证书拷贝过去就可以了
1
| cp /media/xxx/docker/acme.sh/out/*.pem /media/xxx/docker/nginx/conf.d/cert/
|
最后重启一下Nginx就可以了。
内网穿透
这里使用frpc:
1 2 3 4 5 6
| docker run -d \ --network host \ --name frpc \ --restart=unless-stopped \ -v /media/xxx/docker/frpc/frpc.ini:/etc/frpc.ini \ leonismoe/frpc:arm64-latest # 根据系统选择标签
|
首先得准备好配置文件。
新建一个frpc.ini
文件:
1 2 3 4
| # 新建目录 mkdir -p /media/xxx/docker/frpc # 新建文件 touch /media/xxx/docker/frpc/frpc.ini
|
接下来去Sakura Frp注册并登录,然后点击左侧创建隧道
菜单。

列表下拉选择适合的服务器。(注意选择标有可建站
的,其中打钩的是无须域名备案即可使用,其他则是需要域名有备案的。)

接着如图填写好相应的信息:

注意,要想使用https需要创建两条隧道即http和https,只需要修改一下类型和端口就可以了,最后就能在隧道列表找到刚创建的隧道信息了。

然后点击配置文件
,选择里边的内容,将其复制到frpc.ini
文件中。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| # 服务器信息 [common] protocol = tcp server_addr = xx.xx.xx.xx server_port = xxxx
user = 1234567890 token = 0123456789 sakura_mode = true use_recover = true
tcp_mux = true pool_count = 1 dns_server = 223.5.5.5
# 本地服务信息 [xxxxxxxx] type = http # 类型
local_ip = 192.168.1.1 local_port = 1111 # 端口
use_encryption = 0 use_compression = 0
custom_domains = pan.nerocats.com
[xxxxxxxx] type = https # 类型
local_ip = 192.168.1.1 local_port = 2222 # 端口
use_encryption = 0 use_compression = 0
custom_domains = pan.nerocats.com
|
将两条隧道的信息都拷贝进去,但是只保留一个的[common]
信息放在最前边。
最后确认frpc.ini
信息无误之后,重启一下frpc
容器就可以直接访问域名了。
NextCloud
温馨小提示
在这个过程中,我遇到了不少小问题,就在这里总结下。
通过不被信任的域名访问
首先就是出于安全保护,nextcloud会限制域名访问,如下图:

这时候也不必慌张,只需要在配置文件(/config/config.json
)里边修改一下就可以了。
1 2 3 4 5 6 7 8 9
| 'trusted_domains' => array ( 0 => '127.0.0.1', 1 => preg_match('/cli/i',php_sapi_name())?'127.0.0.1':$_SERVER['SERVER_NAME'], # 不限制ip访问 2 => 'xx.com', # 可自行添加域名 3 => 'aa.cn', 4 => 'bb.cc', 5 => 'dd.xyz', ),
|

登录无法跳转
弄完以后,我测试发现填写完用户名及密码之后,点击登录无法跳转到主页。但是刷新一下又是登录状态了,最后上网查了下,这是因为web使用https反向代理了http导致的。只需要在配置文件(/config/config.json
)中加上一条信息就可以了。
1
| 'overwriteprotocol' => 'https',
|

上传大文件失败
这个网页上传应该会遇到,因为Nginx做了限制。
首先,映射出Nginx的配置文件:
1
| -v /volume1/docker/nginx/nginx.conf:/etc/nginx/nginx.conf
|
然后修改一下,添加一个参数就可以了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| user nginx; worker_processes auto;
error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type application/octet-stream; client_max_body_size 2048M;
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;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf; }
|
[0901]程序更新
今天,在使用的时候,提示更新到19.0.2
,网上看了看docker的方法貌似很简单,尝试着在Cecos-Caas
里边直接重新创建
了一下。没想到等了一会儿就直接更新好了,因为数据库独立加上文件都是映射到宿主机的,所以也不需要备份什么的,太方便了。
所以以后更新直接点击一下重新创建
就OK了!

记得选择拉取最新镜像
或者说怕这里等待时间太长,自己提前pull好最新镜像。
OK,差不多就这些了,遇到新问题再贴出来。