开局碎碎念:

自从开始使用docker以后,不管遇到什么项目,总想看看有没有相应的docker镜像。享受那种输入一连串命令,然后回车一键完成的快感。正好前段时间搞了个软路由,在上边虚拟了一个黑群晖,可惜,无奈自己没有公网,玩了一阵之后就闲置了。不过最近发现以前注册的一个半公益内网穿透用着效果还不错,于是乎就想搭个网盘玩玩。

然后我就上网搜了下好用的免费网盘,但找来找去发现还是之前有上手过的NextCloudCloudreve比较适合我,然后我又发现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

  • 拉取Cecos-Caas(根据系统架构选择对应的镜像)

    1
    2
    3
    4
    #amd
    docker pull openfans/cecos-caas:latest
    #arm64
    docker pull openfans/cecos-caas:2.21.0-arm64
  • 启动Cecos-Caas

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #amd
    docker run -d \
    -p 9000:18080 \
    --name cecos-caas \
    --restart=unless-stopped \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /home/cecos-caas/data:/data \
    openfans/cecos-caas:latest
    #arm64
    docker run -d \
    -p 9000:18080 \
    --name cecos-caas \
    --restart=unless-stopped \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /home/cecos-caas/data:/data \
    openfans/cecos-caas:2.21.0-arm64

这两个可以同时存在,只需要保证映射到外部的端口不同就行了。接着访问 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;
}
#HTTP_TO_HTTPS_END
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;
#SSL-END
location / {
proxy_pass http://nextcloud; # link了容器,直接使用别名,不担心IP变动
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;
}
#HTTP_TO_HTTPS_END
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;
#SSL-END
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文件中。

Snipaste_2020-08-13_16-20-02-tuya

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',
),

Snipaste_2020-08-13_17-04-10

登录无法跳转

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

1
'overwriteprotocol' => 'https',

Snipaste_2020-08-13_17-03-24

上传大文件失败

这个网页上传应该会遇到,因为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;
# set client body size to 2M #
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;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

[0901]程序更新

今天,在使用的时候,提示更新到19.0.2,网上看了看docker的方法貌似很简单,尝试着在Cecos-Caas里边直接重新创建了一下。没想到等了一会儿就直接更新好了,因为数据库独立加上文件都是映射到宿主机的,所以也不需要备份什么的,太方便了。

所以以后更新直接点击一下重新创建就OK了!

更新

记得选择拉取最新镜像或者说怕这里等待时间太长,自己提前pull好最新镜像。

OK,差不多就这些了,遇到新问题再贴出来。