- A+
最近发现常用的APP都加上了Webdav的备份选项,考虑到公网的webdav速度和成本,索性就用刚买的N1整一个临时的,用来备份APP。
Webdav简介
WebDAV 简介 WebDAV 是一组基于超文本传输协议的技术集合,有利于用户间协同编辑和管理存储在万维网服务器文档。 即 Web-based Distributed Authoring and Versioning (WebDAV),直译过来就是基于万维网的分布式创作和版本控制。
其实操作逻辑上类似RESTful,使用HTTP协议中规定的操作,完成对文件的增删改查等操作。
操作方案
自建云盘
比较有名的ownCloud,NextCloud等开源网盘项目是完全支持webdav协议的,但是这些应用依赖数据库,N1的内存就2G,更何况还想在上面跑点其他的应用,索性就pass了。
P.S. 自建云盘在大文件的操作上很可能使php进入崩溃状态,这也是我放弃自建云盘的原因。不过对于N1以上量级的板子可以考虑Seafile这样的解决方案,家庭场景下还是有着不错的性能。
webserver
常用的webserver都支持了webdav协议,但是我最习惯的Nginx对于部分指令的支持并不完善,还需要加入其他的模块,我想了想N1这个四核A53的编译速度,还是含泪放弃了(尤其是Nginx我都是apt安装的)
Caddy也支持http.webdav插件,配置起来非常友好,但是我不是Caddy党,对于Caddy目前还是观望状态。(Caddy2这个也没整明白)
Apache(httpd)倒是完全支持,但是对于N1来说确实用不到这个玩意,如果用Apache的话,后续的webserver配置学习成本太高(还是懒)
Docker
俗话说Docker一把梭就是干,但是遇到了问题,在Dockerhub上一番搜索之后,发现比较靠谱的image都是至少一年前更新的了,而且还是只build了amd64版本。
最终选择了bytemark/webdav进行改装。
docker官方提供了基于alpine的httpd镜像,但是不知道为什么bytemark/webdav
没能自动同步构建。
梳理一下这个Dockerfile
FROM httpd:alpine
# These variables are inherited from the httpd:alpine image:
# ENV HTTPD_PREFIX /usr/local/apache2
# WORKDIR "$HTTPD_PREFIX"
# Copy in our configuration files.
COPY conf/ conf/
RUN set -ex; \
# Create empty default DocumentRoot.
mkdir -p "/var/www/html"; \
# Create directories for Dav data and lock database.
mkdir -p "/var/lib/dav/data"; \
touch "/var/lib/dav/DavLock"; \
chown -R www-data:www-data "/var/lib/dav"; \
\
# Enable DAV modules.
for i in dav dav_fs; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Make sure authentication modules are enabled.
for i in authn_core authn_file authz_core authz_user auth_basic auth_digest; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Make sure other modules are enabled.
for i in alias headers mime setenvif; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Run httpd as "www-data" (instead of "daemon").
for i in User Group; do \
sed -i -e "s|^$i .*|$i www-data|" "conf/httpd.conf"; \
done; \
\
# Include enabled configs and sites.
printf '%s\n' "Include conf/conf-enabled/*.conf" \
>> "conf/httpd.conf"; \
printf '%s\n' "Include conf/sites-enabled/*.conf" \
>> "conf/httpd.conf"; \
\
# Enable dav and default site.
mkdir -p "conf/conf-enabled"; \
mkdir -p "conf/sites-enabled"; \
ln -s ../conf-available/dav.conf "conf/conf-enabled"; \
ln -s ../sites-available/default.conf "conf/sites-enabled"; \
# Install openssl if we need to generate a self-signed certificate.
apk add --no-cache openssl
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
EXPOSE 80/tcp 443/tcp
ENTRYPOINT [ "docker-entrypoint.sh" ]
CMD [ "httpd-foreground" ]
在实际build的过程中,需要替换alpine的软件源(日常),并且遇到了(20019)DSO load failed: [client 127.0.0.1:43752] Could not open property database.
这样的报错。排查出问题是来自于apr-util-dbm_db
这个软件包。(这个软件包的描述是The Apache Portable Runtime Utility Library - Berkley DB driver),也就是说由于数据库驱动的缺失导致报错。
修改完成后的Dockerfile
如下
FROM httpd:alpine
# These variables are inherited from the httpd:alpine image:
# ENV HTTPD_PREFIX /usr/local/apache2
# WORKDIR "$HTTPD_PREFIX"
# Copy in our configuration files.
COPY conf/ conf/
RUN set -ex; \
# Replace repo with Aliyun
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories; \
# Create empty default DocumentRoot.
mkdir -p "/var/www/html"; \
# Create directories for Dav data and lock database.
mkdir -p "/var/lib/dav/data"; \
touch "/var/lib/dav/DavLock"; \
chown -R www-data:www-data "/var/lib/dav"; \
\
# Enable DAV modules.
for i in dav dav_fs; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Make sure authentication modules are enabled.
for i in authn_core authn_file authz_core authz_user auth_basic auth_digest; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Make sure other modules are enabled.
for i in alias headers mime setenvif; do \
sed -i -e "/^#LoadModule ${i}_module.*/s/^#//" "conf/httpd.conf"; \
done; \
\
# Run httpd as "www-data" (instead of "daemon").
for i in User Group; do \
sed -i -e "s|^$i .*|$i www-data|" "conf/httpd.conf"; \
done; \
\
# Include enabled configs and sites.
printf '%s\n' "Include conf/conf-enabled/*.conf" \
>> "conf/httpd.conf"; \
printf '%s\n' "Include conf/sites-enabled/*.conf" \
>> "conf/httpd.conf"; \
\
# Enable dav and default site.
mkdir -p "conf/conf-enabled"; \
mkdir -p "conf/sites-enabled"; \
ln -s ../conf-available/dav.conf "conf/conf-enabled"; \
ln -s ../sites-available/default.conf "conf/sites-enabled"; \
# Install openssl if we need to generate a self-signed certificate.
apk add --no-cache openssl apr-util apr-util-dbm_db
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
EXPOSE 80/tcp 443/tcp
ENTRYPOINT [ "docker-entrypoint.sh" ]
CMD [ "httpd-foreground" ]
为了dav的数据持久化,使用了数据卷语法
--mount type=bind,source=/src/webapp,target=/opt/webapp
其中,source是主机,target是容器内的目标,默认给的权限是读写。
(与-v参数的区别是--mount不会自动创建主机目录)
随后则是配置Nginx的反向代理,这里和平常的反向代理的配置方法大同小异,主要是注意修改Nginx的最大上传限制,不然大的APP备份很容易的就超过8M。另外如果对家用机的端口安全十分敏感,可以选择-p 127.0.0.1:8080:80
强制只监听本地转发的端口,可以起到保护的作用。
关于这个镜像的环境变量,官方给出的说明还是较为详细的,可以去dockerhub上围观。
另外一个小坑是如果使用Digest的认证方式,部分webdav客户端可能出现报错,保险起见还是使用了Basic方式。
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫