docker下构建基于nginx的具有完整webdav功能的镜像并运行

------------------------------------------------2023-09-01 更新-----------------------------------------------------

关于设置多个共享位置方法:

修改nginx.conf

再复制一份 location,修改

location /share2 {
            alias /home/share2;
            charset utf-8;
            autoindex on;
            dav_methods PUT DELETE MKCOL COPY MOVE;
            dav_ext_methods PROPFIND OPTIONS;
            create_full_put_path  on;
            dav_access user:rw group:rw all:r;
            auth_basic "Authorized Users Only";
            auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
            client_max_body_size 2g;
        }

注意 需要用 alias 而不是root,然后 不要忘了docker 需要重新编辑运行参数把新的共享位置映射到docker里,访问时 https://地址:端口号/share2/ 即可

-------------------------------------------------------------2023年7月17日更新注意事项-----------------------------

共享文件夹的权限会影响webdav访问的权限,虽然使用的是 .htpasswd,但并不能脱离系统权限,

看其他博客似乎Apache的可以脱离系统,但是我没有实验,不知道;

还找了一些博文,类似设置文件夹 所有者和所有组 为 nobody 或者www-data,但我测试了并没有作用;

最后还是要把权限设置成777才可以.

其他参考文章:

❖ Webdav (Apache) 的文件权限问题 - 简书

 ---------------------------------------------------------------------------------------------------------------

可能是webdav协议用的人少,dockerhub上下载量靠前的几个镜像都是四五年前的了,nginx1.22之前的版本又有漏洞,而且nginx想实现完整的webdav功能需要借助第三方模块,遂想自己构建,查找了很多资料,终于找到一个大佬关于如何在docker下自定义nginx模块的文章,而且方法不断更新,但是最新的动态模块的方法我不是太理解,还是借鉴他21年的一篇文章,主要的理念就是参考nginx官方的Dockerfile,然后加入自定义模块,然后编译即可.

大佬文章地址:https://soulteary.com/2021/01/07/use-docker-and-nginx-to-build-high-performance-qr-code-services-2.html

官方Dockerfile地址:https://github.com/nginxinc/docker-nginx/blob/master/stable/alpine/Dockerfile

我最后修改的Dockerfile:

 1 #nginx官方包
 2 FROM nginx:1.22.1-alpine
 3 #各模块版本变量参数
 4 ARG NGINX_VERSION=1.22.1
 5 ARG NGX_WEBDAV_VERSION=3.0.0
 6 #将宿主机的文件复制到镜像目录
 7 COPY ./dav-${NGX_WEBDAV_VERSION}.tar.gz /tmp
 8 #换国内清华源,阿里源很慢
 9 RUN cat /etc/apk/repositories | sed -e "s/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/" | tee /etc/apk/repositories
10 #编译环境
11 RUN apk add --no-cache --virtual .build-deps gcc libc-dev make openssl-dev pcre2-dev zlib-dev linux-headers libxslt-dev gd-dev geoip-dev perl-dev libedit-dev mercurial bash alpine-sdk findutils && \    
12     mkdir -p /usr/src && cd /usr/src && \    
13     curl -L "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" -o nginx.tar.gz && \    
14     tar zxvf /tmp/dav-${NGX_WEBDAV_VERSION}.tar.gz && mv nginx-dav-ext-module-${NGX_WEBDAV_VERSION} ngx_dav && \
15     tar -zxC /usr/src -f nginx.tar.gz && \
16     cd /usr/src/nginx-$NGINX_VERSION && \
17     CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') \
18     CONFARGS=${CONFARGS/-Os -fomit-frame-pointer -g/-Os} && \
19     echo $CONFARGS && \
20     ./configure --with-compat $CONFARGS --with-http_dav_module --add-module=../ngx_dav/ && \
21     make && make install && \
22     apk del .build-deps && \
23     rm -rf /tmp/* && rm -rf /var/cache/apk/* && rm -rf /usr/src/ 
24     

其中考虑到github可能有联通问题 nginx-dav-ext-module第三方模块我是先下载到 本地 /home/webdav/ ,Dockerfile也是放这里,所以要切换到此目录下执行,当然nginx的源码也可以先下载下来

然后执行构建命令: 

docker build -t nginx-dav .

最开始生成镜像后,运行报错,提示库文件找不到,但在容器中很难找原因,后来经过与官方Dockerfile对比,发现编译环境的工具pcre-dev已更新为pcre2-dev,修改后再构建运行成功.

构建好镜像,用工具创建webdav的密码文件

安装工具: 

yum -y install httpd-tools

生成密码文件:

 

htpasswd -c /home/webdav/.htpasswd dav
# 如果还有用户
htpasswd /home/webdav/.htpasswd user1

编写nginx配置文件nginx.conf

#user  nobody;
worker_processes  1;                             # 只启动一个工作进程
events {
    worker_connections  1024;               # 每个工作进程的最大连接为1024
}
http {
    include       mime.types;                    # 引入MIME类型映射表文件
    default_type  application/octet-stream;   # 全局默认映射类型为application/octet-stream

    #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  logs/access.log  main;
    sendfile        on;                             # 启用零复制机制
    keepalive_timeout  65;                  # 保持连接超时时间为65s
    server {
        listen       443 ssl;
            listen       [::]:443 ssl;
        #    listen        80;
            server_name  aaa.dynv6.net;
            
            ssl_certificate /etc/nginx/cert/aq.pem;
            ssl_certificate_key /etc/nginx/cert/aq.key;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
            ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
            keepalive_timeout 70;
            ssl_session_cache shared:SSL:10m;
            ssl_session_timeout 10m;
            client_max_body_size 10m;                         # 最大允许上传的文件大小
       
       
        error_log /var/log/nginx/webdav.error.log error;
        access_log  /var/log/nginx/webdav.access.log combined;
        location / {
            root /root/;
            #root /root/VpsDownload/;
            charset utf-8;
            autoindex on;
            dav_methods PUT DELETE MKCOL COPY MOVE;
            dav_ext_methods PROPFIND OPTIONS;
            create_full_put_path  on;
            dav_access user:rw group:r all:r;
            auth_basic "Authorized Users Only";
            auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
            client_max_body_size 100m;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
}

 

 

最后运行命令:

docker run --name dav -v /home/webdav/nginx.conf:/etc/nginx/nginx.conf -v /home/webdav/.htpasswd:/etc/nginx/conf.d/.htpasswd:ro -v /home/test/:/root/ -v /home/docker/web/nginx/cert/:/etc/nginx/cert/ -p 37777:443 -d nginx-dav

为了安全,使用ssl,配置好自己的域名和证书

 

然后访问

https://域名:37777,本机测试使用https://localhost:37777

提示输入用户名密码,登录可以浏览查看文件

 

使用手机 app: cx文件管理器,添加- 网络- 新位置 即可查看和上传文件;电脑端推荐raidrive作为webdav客户端,可以模拟成一个分区,使用方便;

其他参考文章:

https://www.jianshu.com/p/50cc357c4391

 

posted @ 2023-04-12 14:42  dirgo  阅读(1431)  评论(0编辑  收藏  举报