ホームページ >運用・保守 >Nginx >nginxを使用してコンテナ内にアップロードおよびダウンロードするためのファイルサーバーを構築する方法

nginxを使用してコンテナ内にアップロードおよびダウンロードするためのファイルサーバーを構築する方法

王林
王林転載
2023-05-15 23:49:042097ブラウズ

1. 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

2. 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を使用してコンテナ内にアップロードおよびダウンロードするためのファイルサーバーを構築する方法

3. ファイルのアップロードをサポート

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(&#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. アップロードの進行状況を取得します

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" >
        <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>

nginxを使用してコンテナ内にアップロードおよびダウンロードするためのファイルサーバーを構築する方法##

以上がnginxを使用してコンテナ内にアップロードおよびダウンロードするためのファイルサーバーを構築する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。