在容器中使用nginx搭建上传下载服务器


Posted in Servers onMay 11, 2022

一、安装nginx容器

为了让nginx支持文件上传,需要下载并运行带有nginx-upload-module模块的容器:

sudo podman pull docker.io/dimka2014/nginx-upload-with-progress-modules:latest
sudo podman -d --name nginx -p 83:80 docker.io/dimka2014/nginx-upload-with-progress-modules

该容器同时带有nginx-upload-module模块和nginx-upload-progress-module模块。

注意该容器是Alpine Linux ,没有bash,有些命令与其它发行版本的Linux不一样。

使用下面的命令进入容器:

sudo podman exec -it nginx /bin/sh

作为文件服务器, 需要显示本地时间,默认不是本地时间。通过下面一系列命令设置为本地时间:

apk update
apk add tzdata
echo "Asia/Shanghai" > /etc/timezone
rm -rf /etc/localtime
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
apk del tzdata

创建文件服务器的根目录:

mkdir -p /nginx/share

二、配置nginx

配置文件的路径为/etc/nginx/conf.d/default.conf,作为

server {
    ……
    charset utf-8; # 设置字符编码,避免中文乱码
    location / {
            root   /nginx/share; # 根目录
            autoindex   on;  # 开启索引功能
            autoindex_exact_size off; # 关闭计算文件确切大小(单位bytes),只显示大概大小(单位kb、mb、gb)
            autoindex_localtime on; # 显示本地时间
        }
}

此时我们的文件服务就配置好了,需要使用下面的命令让配置生效:

nginx -s reload

在容器中使用nginx搭建上传下载服务器

三、支持文件上传

1. 配置nginx

上面的配置已经完成文件服务器的配置了,但是不能上传文件,想要上传文件,还需要做如下配置:

server {
    ……
    charset utf-8; # 设置字符编码,避免中文乱码
    client_max_body_size 32m; 
    upload_limit_rate 1M; # 限制上传速度最大1M
    
    # 设置upload.html页面路由
    location = /upload.html {                                                        
            root /nginx;  # upload.html所在路径                                                       
    }

    location /upload {
            # 限制上传文件最大30MB
            upload_max_file_size 30m;
            # 设置后端处理交由@rename处理。由于nginx-upload-module模块在存储时并不是按上传的文件名存储的,所以需要自行改名。
            upload_pass @rename;
            # 指定上传文件存放目录,1表示按1位散列,将上传文件随机存到指定目录下的0、1、2、...、8、9目录中(这些目录要手动建立)
            upload_store /tmp/nginx 1;
            # 上传文件的访问权限,user:r表示用户只读,w表示可写
            upload_store_access user:r;

            # 设置传给后端处理的表单数据,包括上传的原始文件名,上传的内容类型,临时存储的路径
            upload_set_form_field $upload_field_name.name "$upload_file_name";
            upload_set_form_field $upload_field_name.content_type "$upload_content_type";
            upload_set_form_field $upload_field_name.path "$upload_tmp_path";
            upload_pass_form_field "^submit$|^description$";

            # 设置上传文件的md5值和文件大小
            upload_aggregate_form_field "${upload_field_name}_md5" "$upload_file_md5";
            upload_aggregate_form_field "${upload_field_name}_size" "$upload_file_size";

            # 如果出现下列错误码则删除上传的文件
            upload_cleanup 400 404 499 500-505;
     }

    location @rename {
            # 后端处理
            proxy_pass http://localhost:81;
    }
}

上面的配置中,临时存储时是按1位散列来存储的,需要在上传目录下手动创建0~9几个目录。

mkdir -p /tmp/nginx
 cd /tmp/nginx
 mkdir 1 2 3 4 5 6 7 8 9 0
 chown nginx:root . -R

2. 添加upload.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>上传</title>
</head>
<body>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<form name="upload" method="POST" enctype="multipart/form-data" action="upload">
<input type="file" name="file"/>
<input type="submit" name="submit" value="上传"/>
</form>
</body>
</html>

3. 添加后面的处理服务

需要先安装python及所需的库

apk add python3
pip3 install bottle
pip3 install shutilwhich

python服务源码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

from bottle import *
import shutil

@post("/upload")
def postExample():
    try:
        dt = request.forms.dict
        filenames = dt.get('file.name')
        tmp_path = dt.get("file.tmp_path")
        filepaths = dt.get("file.path")
        count = filenames.__len__()
        dir = os.path.abspath(filepaths[0])
        for i in range(count):
            print("rename %s to %s" % (tmp_path[i],  os.path.join(dir, filenames[i])))
            target = os.path.join(dir, filenames[i])
            shutil.move(tmp_path[i], target)
            shutil.chown(target, "nginx", "root") # 由于shutil.move不会保持用户归属,所以需要显示修改,否则访问时会报403无访问权限
    except Exception as e:
        print("Exception:%s" % e)
        redirect("50x.html") # 如果是在容器中部署的nginx且映射了不同的端口,需要指定IP,端口
    redirect('/') # 如果是在容器中部署的nginx且映射了不同的端口,需要指定IP,端口

run(host='localhost', port=81)

四、获取上传进度

1.修改配置

# 开辟一个空间proxied来存储跟踪上传的信息1MB
upload_progress proxied 1m;
server {
    ……
    location ^~ /progress {
        # 报告上传的信息
        report_uploads proxied;
    }
    location /upload {
        ...
        # 上传完成后,仍然保存上传信息5s
        track_uploads proxied 5s;
    }
}

2. 修改上传页面

<form id="upload" enctype="multipart/form-data" action="/upload" method="post" onsubmit="openProgressBar(); return true;">
    <input name="file" type="file" label="fileupload" />
    <input type="submit" value="Upload File" />
</form>
<div>
    <div id="progress" style="width: 400px; border: 1px solid black">
        <div id="progressbar" style="width: 1px; background-color: black; border: 1px solid white"> </div>
    </div>
   <div id="tp">(progress)</div>
</div>
<script type="text/javascript">
    var interval = null;
    var uuid = "";
    function openProgressBar() {
        for (var i = 0; i < 32; i++) {
            uuid += Math.floor(Math.random() * 16).toString(16);
        }
        document.getElementById("upload").action = "/upload?X-Progress-ID=" + uuid;
        /* 每隔一秒查询一下上传进度 */
        interval = window.setInterval(function () {
            fetch(uuid);
        }, 1000);
    }
    function fetch(uuid) {
        var req = new XMLHttpRequest();
        req.open("GET", "/progress", 1);
        req.setRequestHeader("X-Progress-ID", uuid);
        req.onreadystatechange = function () {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    var upload = eval(req.responseText);
                    document.getElementById('tp').innerHTML = upload.state;
                    /* 更新进度条 */
                    if (upload.state == 'done' || upload.state == 'uploading') {
                        var bar = document.getElementById('progressbar');
                        var w = 400 * upload.received / upload.size;
                        bar.style.width = w + 'px';
                    }
                    /* 上传完成,不再查询进度 */
                    if (upload.state == 'done') {
                        window.clearTimeout(interval);
                    }
                    if (upload.state == 'error') {
                        window.clearTimeout(interval);
                        alert('something wrong');
                    }
                }
            }
        }
        req.send(null);
    }
</script>

在容器中使用nginx搭建上传下载服务器

参考:

https://breeze2.github.io/blog/scheme-nginx-php-js-upload-process

https://www.tiantanhao.com/34031.html

https://blog.csdn.net/scugxl/article/details/107180138

https://octocat9lee.github.io/2020/03/11/Nginx%E6%90%AD%E5%BB%BA%E6%96%87%E4%BB%B6%E6%9C%8D%E5%8A%A1%E5%99%A8/

到此这篇关于容器中使用ngnix搭建支持上传下载的文件服务器的文章就介绍到这了!


Tags in this post...

Servers 相关文章推荐
Nginx实现反向代理
Sep 20 Servers
本地通过nginx配置反向代理的全过程记录
Mar 31 Servers
Nginx配置并兼容HTTP实现代码解析
Mar 31 Servers
nginx里的rewrite跳转的实现
Mar 31 Servers
Filebeat 采集 Nginx 日志的方法
Mar 31 Servers
提升Nginx性能的一些建议
Mar 31 Servers
解决使用了nginx获取IP地址都是127.0.0.1 的问题
Sep 25 Servers
tomcat默认最大连接数及相关调整方法
May 06 Servers
nginx 配置指令之location使用详解
May 25 Servers
详解Nginx的超时keeplive_timeout配置步骤
May 25 Servers
利用Apache Common将java对象池化的问题
Jun 16 Servers
win server2012 r2服务器共享文件夹如何设置
Jun 21 Servers
阿里云国际版 使用Nginx作为HTTPS转发代理服务器
May 11 #Servers
nginx 配置缓存
May 11 #Servers
Nginx的gzip相关介绍
May 11 #Servers
详解如何使用Nginx解决跨域问题
May 06 #Servers
配置nginx负载均衡
May 06 #Servers
tomcat下部署jenkins的方法
排查Tomcat进程假死的问题
May 06 #Servers
You might like
PHP学习资料汇总与网址
2007/03/16 PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
2015/12/08 PHP
PHP共享内存使用与信号控制实例分析
2018/05/09 PHP
jQuery实现有动画淡出效果的二级折叠菜单代码
2015/10/17 Javascript
html判断当前页面是否在iframe中的实例
2016/11/30 Javascript
Vue数据驱动模拟实现3
2017/01/11 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
AngularJS ng-repeat指令及Ajax的应用实例分析
2017/07/06 Javascript
基于js粘贴事件paste简单解析以及遇到的坑
2017/09/07 Javascript
详解vue-cli与webpack结合如何处理静态资源
2017/09/19 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
2017/12/09 Javascript
深入浅析Vue中的slots/scoped slots
2018/04/03 Javascript
15分钟深入了解JS继承分类、原理与用法
2019/01/19 Javascript
JavaScript数组、json对象、eval()函数用法实例分析
2019/02/21 Javascript
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
用js编写留言板
2020/03/17 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
Python中关于使用模块的基础知识
2015/05/24 Python
python如何通过protobuf实现rpc
2016/03/06 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
python3使用flask编写注册post接口的方法
2018/12/28 Python
python爬虫获取小区经纬度以及结构化地址
2018/12/30 Python
python基于SMTP协议发送邮件
2019/05/31 Python
pandas的相关系数与协方差实例
2019/12/27 Python
解决Python logging模块无法正常输出日志的问题
2020/02/21 Python
如何使用python记录室友的抖音在线时间
2020/06/29 Python
英国男女豪华配饰和礼品网站:Black.co.uk
2020/02/28 全球购物
食品营养与检测应届生求职信
2013/11/08 职场文书
大学生个人简历中的自我评价
2013/12/27 职场文书
2014年公司迎新年活动方案
2014/02/24 职场文书
质量主管工作职责
2014/09/26 职场文书
保卫工作个人总结
2015/03/03 职场文书
2015年七夕情人节感言
2015/08/03 职场文书
中学音乐课教学反思
2016/02/18 职场文书
一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的
2021/05/25 MySQL
Pygame Time时间控制的具体使用详解
2021/11/17 Python