Home >Operation and Maintenance >Nginx >How to use nginx to build a file server for uploading and downloading in a container

How to use nginx to build a file server for uploading and downloading in a container

王林
王林forward
2023-05-15 23:49:042105browse

1. Install nginx container

In order for nginx to support file upload, you need to download and run the container with the nginx-upload-module 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

The container also has nginx- upload-module module and nginx-upload-progress-module module.

NoteThis container is Alpine Linux, there is no bash, and some commands are different from other Linux distributions.

Use the following command to enter the container:

sudo podman exec -it nginx /bin/sh

As a file server, you need to display the local time, which is not the local time by default. Set the local time through the following series of commands:

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

Create the root directory of the file server:

mkdir -p /nginx/share

2. Configure nginx

The path of the configuration file is / etc/nginx/conf.d/default.conf, as

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

At this point our file service is configured, you need to use the following command to make the configuration take effect:

nginx -s reload

How to use nginx to build a file server for uploading and downloading in a container

3. Support file upload

1. Configure nginx

The above configuration has completed the configuration of the file server, but the file cannot be uploaded. I want to upload the file. , you also need to make the following configuration:

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;
    }
}

In the above configuration, temporary storage is stored by 1-bit hash, and you need to manually create several directories 0~9 in the upload directory.

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

2. Add 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. Add subsequent processing services

You need to install python and the required libraries first

apk add python3
pip3 install bottle
pip3 install shutilwhich

python Service source code:

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

from bottle import *
import shutil

@post("/upload")
def postExample():
    try:
        dt = request.forms.dict
        filenames = dt.get(&#39;file.name&#39;)
        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(&#39;/&#39;) # 如果是在容器中部署的nginx且映射了不同的端口,需要指定IP,端口

run(host=&#39;localhost&#39;, port=81)

4. Get the upload progress

1. Modify the configuration

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

2. Modify the upload page

<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" >
        <div id="progressbar" > </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(&#39;tp&#39;).innerHTML = upload.state;
                    /* 更新进度条 */
                    if (upload.state == &#39;done&#39; || upload.state == &#39;uploading&#39;) {
                        var bar = document.getElementById(&#39;progressbar&#39;);
                        var w = 400 * upload.received / upload.size;
                        bar.style.width = w + &#39;px&#39;;
                    }
                    /* 上传完成,不再查询进度 */
                    if (upload.state == &#39;done&#39;) {
                        window.clearTimeout(interval);
                    }
                    if (upload.state == &#39;error&#39;) {
                        window.clearTimeout(interval);
                        alert(&#39;something wrong&#39;);
                    }
                }
            }
        }
        req.send(null);
    }
</script>

How to use nginx to build a file server for uploading and downloading in a container

The above is the detailed content of How to use nginx to build a file server for uploading and downloading in a container. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete