{"id":393024,"date":"2024-06-29T10:45:48","date_gmt":"2024-06-29T10:45:48","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=393024"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=393024","title":{"rendered":"<span>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 MinIO \u043f\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0438\u043b\u0438 \u043d\u0435\u0442?<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438: \u042f \u0445\u043e\u0447\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0417\u0434\u0435\u0441\u044c \u0432\u0440\u043e\u0434\u0435 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u0414\u0430\u043b\u044c\u0448\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041d\u0443\u0436\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>GUI \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e API.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0430\u0439\u043b\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u043f\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 URL \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0431\u0435\u0437 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043e\u0440\u0442\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e).<\/p>\n<\/li>\n<li>\n<p>&#8230;<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 OpenSource \u0440\u0435\u0448\u0438\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c <a href=\"https:\/\/min.io\/\">MinIO<\/a>: \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442, \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435. ?<\/p>\n<h2>\u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c<\/h2>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0441\u0435\u0440\u0432\u0435\u0440. \u0418 \u043d\u0430 \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <a href=\"https:\/\/github.com\/AlexNik\/MinIO-tutorial\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/h2>\n<p>\u0412\u043e\u0437\u044c\u043c\u0451\u043c \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 http.server \u0438\u0437 Python, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u043e\u0441\u0442\u0438\u0442\u044c <a href=\"https:\/\/min.io\/docs\/minio\/linux\/integrations\/presigned-put-upload-via-browser.html#a-name-createclient-a-2-create-the-client-side-web-application\">\u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443<\/a> \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432. \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043a\u0430\u043a \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/13a\/c8c\/123\/13ac8c1233b13c31b5ce616281a73229.png\" width=\"751\" height=\"391\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/13a\/c8c\/123\/13ac8c1233b13c31b5ce616281a73229.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0432\u0430 \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u0442\u043a\u0440\u044b\u0442\u044b \u043f\u043e\u0440\u0442\u044b \u043d\u0430\u0440\u0443\u0436\u0443. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0443 MinIO \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0444\u0430\u0439\u043b. \u0412\u0441\u0435 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>server.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import http.server import socketserver import os from minio import Minio  PORT = 8080  remote_url = os.getenv('REMOTE_URL') minio_host = os.getenv('MINIO_HOST') minio_port = os.getenv('MINIO_PORT') minio_url = f'{minio_host}:{minio_port}'  minio_user = os.getenv('MINIO_USER') minio_password = os.getenv('MINIO_PASSWORD')  bucket_name = 'uploads'  client = Minio(     minio_url,     access_key=minio_user,     secret_key=minio_password,     secure=False )  if not client.bucket_exists(bucket_name):     client.make_bucket(bucket_name)   class Handler(http.server.SimpleHTTPRequestHandler):     def do_GET(self):         if '\/presignedUrl' in self.path:             self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              filename = self.path.split('=')[1]             original_minio_str = client.presigned_put_object(bucket_name, filename)             self.wfile.write(str.encode(original_minio_str))             return         elif '\/files' in self.path:             self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              files = list(client.list_objects(bucket_name, recursive=True))             files_str = '&lt;br>'.join(                 [f'&lt;p>{file.object_name} &amp;emsp; {client.stat_object(bucket_name, file.object_name).metadata}&lt;\/p>' for                  file in files])              self.wfile.write(str.encode(files_str))              return         else:             with open('index.html', 'r') as web_page_file:                 web_page = web_page_file.read()              self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              self.wfile.write(str.encode(web_page))              return   with socketserver.TCPServer((\"\", PORT), Handler) as httpd:     print(\"serving at port\", PORT)     httpd.serve_forever() <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>index.html<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\"> &lt;input type=\"file\" id=\"selector\" multiple> &lt;button onclick=\"upload()\">Upload&lt;\/button>  &lt;div id=\"status\">No uploads&lt;\/div>  &lt;script type=\"text\/javascript\">   \/\/ `upload` iterates through all files selected and invokes a helper function called `retrieveNewURL`.   function upload() {         \/\/ Get selected files from the input element.         var files = document.querySelector(\"#selector\").files;         for (var i = 0; i &lt; files.length; i++) {             var file = files[i];             \/\/ Retrieve a URL from our server.             retrieveNewURL(file, (file, url) => {                 \/\/ Upload the file to the server.                 uploadFile(file, url);             });         }     }      \/\/ `retrieveNewURL` accepts the name of the current file and invokes the `\/presignedUrl` endpoint to     \/\/ generate a pre-signed URL for use in uploading that file:      function retrieveNewURL(file, cb) {         fetch(`\/presignedUrl?name=${file.name}`).then((response) => {             response.text().then((url) => {                 cb(file, url);             });         }).catch((e) => {             console.error(e);         });     }      \/\/ ``uploadFile` accepts the current filename and the pre-signed URL. It then uses `Fetch API`     \/\/ to upload this file to S3 at `play.min.io:9000` using the URL:     function uploadFile(file, url) {         if (document.querySelector('#status').innerText === 'No uploads') {             document.querySelector('#status').innerHTML = '';         }         fetch(url, {             method: 'PUT',             body: file         }).then(() => {             \/\/ If multiple files are uploaded, append upload status on the next line.             document.querySelector('#status').innerHTML += `&lt;br>Uploaded ${file.name}.`;         }).catch((e) => {             console.error(e);         });     } &lt;\/script><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>FROM python:alpine  RUN pip install minio  WORKDIR \/server  COPY server.py index.html .\/  ENTRYPOINT [\"python\", \"\/server\/server.py\"] <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>docker-compose.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> version: \"3.8\"  services:   minio:     image: minio\/minio     command: server \/data\/minio     ports:       - 9000:9000     environment:       - MINIO_ROOT_USER=minioadmin       - MINIO_ROOT_PASSWORD=minioadmin     networks:       - minio-local   server:     container_name: server     ports:       - 8080:8080     build: .     environment:       - MINIO_HOST=192.168.44.76       - MINIO_PORT=9000       - MINIO_USER=minioadmin       - MINIO_PASSWORD=minioadmin     networks:       - minio-local   networks:   minio-local:     driver: bridge<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a (\u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 MINIO_HOST \u043d\u0430 \u0441\u0432\u043e\u0451).<\/p>\n<pre><code> docker-compose up -d --build<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u0430\u0439\u043f\u0438\u0448\u043d\u0438\u043a\u0443 \u0438 \u043f\u043e\u0440\u0442\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (\u043d\u0438\u0436\u0435 \u0432\u0435\u0437\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 http:\/\/192.168.44.76, \u043f\u043e\u043c\u0435\u043d\u044f\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0439)<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9c2\/962\/126\/9c296212653ad468f5f0ff282232999f.png\" alt=\"http:\/\/192.168.44.76:8080\" title=\"http:\/\/192.168.44.76:8080\" width=\"367\" height=\"101\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9c2\/962\/126\/9c296212653ad468f5f0ff282232999f.png\"\/><figcaption>http:\/\/192.168.44.76:8080<\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c <code>\/files<\/code>, \u0433\u0434\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a MinIO \u0438 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/43a\/55c\/1db\/43a55c1db837fcc32c7ac3c5f3eda7bf.png\" width=\"687\" height=\"176\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43a\/55c\/1db\/43a55c1db837fcc32c7ac3c5f3eda7bf.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0440\u044f\u0447\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430 Nginx<\/h2>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u0441\u043f\u0440\u044f\u0447\u0435\u043c \u0437\u0430 Nginx \u043f\u043e \u043f\u0443\u0442\u0438 <code>\/server<\/code>. MinIO \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 9000.<\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c nginx \u0432 <code>docker-file.yml<\/code> \u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433 nginx. \u0415\u0449\u0451 \u043d\u0430 \u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0443\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443: <code>\/presignedUrl<\/code> -> <code>\/server\/presignedUrl<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d91\/b22\/9de\/d91b229debe94945e3cff3b6c7f2f5de.png\" width=\"751\" height=\"391\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d91\/b22\/9de\/d91b229debe94945e3cff3b6c7f2f5de.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8f6\/05c\/154\/8f605c1543d125208403eb7ba5fb4095.png\" alt=\"http:\/\/192.168.44.76\/server\" title=\"http:\/\/192.168.44.76\/server\" width=\"393\" height=\"107\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8f6\/05c\/154\/8f605c1543d125208403eb7ba5fb4095.png\"\/><figcaption>http:\/\/192.168.44.76\/server<\/figcaption><\/figure>\n<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c1f\/150\/442\/c1f150442371e1e9f32cac8dacfbadfd.png\" alt=\"http:\/\/192.168.44.76\/server\/files\" title=\"http:\/\/192.168.44.76\/server\/files\" width=\"685\" height=\"170\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c1f\/150\/442\/c1f150442371e1e9f32cac8dacfbadfd.png\"\/><figcaption>http:\/\/192.168.44.76\/server\/files<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u043e\u0447\u0442\u0438 \u0443 \u0446\u0435\u043b\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043f\u0440\u044f\u0442\u0430\u0442\u044c MinIO \u0437\u0430 Nginx \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0435\u043d\u0430. \u041d\u043e \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439&#8230; \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/minio\/console\/pull\/2174\">issue <\/a>\u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u044b, \u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0440\u0442. \u0414\u0430\u0436\u0435 \u0432 \u0440\u043e\u0434\u043d\u044b\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u0445 MinIO \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u0443\u0442\u0451\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430. \u041d\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0430\u0439\u043b\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e &#171;\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443&#187; \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438 \u0434\u043e\u043a\u0435\u0440\u0430, \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0451, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u043e\u0442\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0430 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430 Nginx \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d68\/e00\/b83\/d68e00b8310873d06495a75480640260.png\" width=\"751\" height=\"391\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d68\/e00\/b83\/d68e00b8310873d06495a75480640260.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0411\u0435\u0440\u0451\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Nginx <a href=\"https:\/\/min.io\/docs\/minio\/linux\/integrations\/setup-nginx-proxy-with-minio.html\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c location <code>\/minio-api<\/code>. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>nginx.conf<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> user  nginx; worker_processes auto; worker_priority -20;  error_log  \/var\/log\/nginx\/error.log; pid        \/var\/run\/nginx.pid;  events {     worker_connections  4000; }  http {     server {         listen 80;         resolver 127.0.0.11 valid=5s ipv6=off;          # To allow special characters in headers         ignore_invalid_headers off;         # Allow any size file to be uploaded.         # Set to a value such as 1000m; to restrict file size to a specific value         client_max_body_size 0;         # To disable buffering         proxy_buffering off;          proxy_redirect off;          set $server http:\/\/server:8080;          location \/server {                 rewrite ^\/server(.*) \/$1 break;                 proxy_pass $server;         }          set $minio_port 9000;         set $minio_host minio;         set $minio_url http:\/\/$minio_host:$minio_port;          location ~* ^\/minio-api {            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_set_header X-Forwarded-Proto $scheme;            proxy_set_header Host $http_host;             proxy_connect_timeout 300;            # Default is HTTP\/1, keepalive is only enabled in HTTP\/1.1            proxy_http_version 1.1;            proxy_set_header Connection \"\";            chunked_transfer_encoding off;             proxy_pass $minio_url;         }     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0438&#8230;.. <strong>\u0424\u0418\u0410\u0421\u041a\u041e&#8230; <\/strong>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f 403 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 curl \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0442\u0432\u0435\u0442 (\u043f\u0440\u0438\u0432\u0451\u043b \u043a \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c\u0443 \u0432\u0438\u0434\u0443):<\/p>\n<pre><code class=\"bash\"> curl -X 'PUT' 'http:\/\/192.168.44.76\/minio-api\/uploads\/sausage.drawio?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=minioadmin%2F20230214%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20230214T124222Z&amp;X-Amz-Expires=604800&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Signature=83d00d24d975f6c6263129d85f9a820b319d78d7d6738513a86429a2441b5f03'  &lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;Error> &lt;Code>SignatureDoesNotMatch&lt;\/Code> &lt;Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.&lt;\/Message> &lt;Key>uploads\/sausage.drawio&lt;\/Key> &lt;BucketName>minio-api&lt;\/BucketName> &lt;Resource>\/minio-api\/uploads\/sausage.drawio&lt;\/Resource> &lt;RequestId>1743B1AB6535B5E1&lt;\/RequestId> &lt;HostId>e96154ee-0e6d-422b-8102-feea5d741fae&lt;\/HostId> &lt;\/Error><\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0447\u0442\u043e \u0437\u0430\u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c rewrite, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0440\u0430\u0442\u044c <code>minio-api<\/code> \u0438\u0437 \u043f\u0443\u0442\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c.<\/p>\n<pre><code>rewrite ^\/minio-api(.*) $1 break;<\/code><\/pre>\n<p>\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0444\u0430\u0439\u043b, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 &#8212; \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c.<\/p>\n<h2>\u0418\u0442\u043e\u0433\u043e<\/h2>\n<p>\u041d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0437\u0430 Nginx \u0431\u0435\u0437 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043e\u0440\u0442\u043e\u0432 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b.<\/p>\n<p>\u0410 \u0447\u0442\u043e \u0442\u0430\u043c \u0441 HTTPS? \u0412\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c SSL Termination \u043d\u0430 Nginx. \u041f\u043b\u044e\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c  \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f minIO. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u043d\u0430\u0434\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0432 \u0441\u0441\u044b\u043b\u043a\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <code>http<\/code> \u043d\u0430 <code>https<\/code>. \u041e\u0441\u0442\u0430\u0432\u043b\u044e \u044d\u0442\u043e \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u041a\u043e\u0434 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/AlexNik\/MinIO-tutorial\">\u0442\u0443\u0442<\/a>.<\/p>\n<h2>PS<\/h2>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0451 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0441\u0430\u043c\u044b\u0439 &#171;\u043a\u043e\u0441\u0442\u044b\u043b\u044c&#187;, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f \u0438 \u0445\u043e\u0442\u0435\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e, \u0443\u0448\u0451\u043b&#8230; \u0412 \u0445\u043e\u0434\u0435 \u043c\u043e\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0431\u0435\u0437 \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u043a\u0438 http \u0437\u0430\u0433\u043b\u043e\u0432\u043a\u0430 Host \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>minio:9000<\/code>. \u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e <code>rewrite<\/code> \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/716910\/\"> https:\/\/habr.com\/ru\/articles\/716910\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041f\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438: \u042f \u0445\u043e\u0447\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0417\u0434\u0435\u0441\u044c \u0432\u0440\u043e\u0434\u0435 \u0432\u0441\u0451 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u0414\u0430\u043b\u044c\u0448\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u041d\u0443\u0436\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u043e\u043d\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>GUI \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e API.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0430\u0439\u043b\u044b \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c \u043f\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 URL \u0441\u0435\u0440\u0432\u0438\u0441\u0430 (\u0431\u0435\u0437 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043e\u0440\u0442\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e).<\/p>\n<\/li>\n<li>\n<p>&#8230;<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0437 OpenSource \u0440\u0435\u0448\u0438\u043b\u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c <a href=\"https:\/\/min.io\/\">MinIO<\/a>: \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442, \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435. ?<\/p>\n<h2>\u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c<\/h2>\n<p>\u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0441\u0435\u0440\u0432\u0435\u0440. \u0418 \u043d\u0430 \u0435\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c <a href=\"https:\/\/github.com\/AlexNik\/MinIO-tutorial\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h2>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430<\/h2>\n<p>\u0412\u043e\u0437\u044c\u043c\u0451\u043c \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 http.server \u0438\u0437 Python, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u043e\u0441\u0442\u0438\u0442\u044c <a href=\"https:\/\/min.io\/docs\/minio\/linux\/integrations\/presigned-put-upload-via-browser.html#a-name-createclient-a-2-create-the-client-side-web-application\">\u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0443<\/a> \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432. \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043a\u0430\u043a \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u0432\u0430 \u0434\u043e\u043a\u0435\u0440 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u0442\u043a\u0440\u044b\u0442\u044b \u043f\u043e\u0440\u0442\u044b \u043d\u0430\u0440\u0443\u0436\u0443. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0443 MinIO \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0444\u0430\u0439\u043b. \u0412\u0441\u0435 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>server.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import http.server import socketserver import os from minio import Minio  PORT = 8080  remote_url = os.getenv('REMOTE_URL') minio_host = os.getenv('MINIO_HOST') minio_port = os.getenv('MINIO_PORT') minio_url = f'{minio_host}:{minio_port}'  minio_user = os.getenv('MINIO_USER') minio_password = os.getenv('MINIO_PASSWORD')  bucket_name = 'uploads'  client = Minio(     minio_url,     access_key=minio_user,     secret_key=minio_password,     secure=False )  if not client.bucket_exists(bucket_name):     client.make_bucket(bucket_name)   class Handler(http.server.SimpleHTTPRequestHandler):     def do_GET(self):         if '\/presignedUrl' in self.path:             self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              filename = self.path.split('=')[1]             original_minio_str = client.presigned_put_object(bucket_name, filename)             self.wfile.write(str.encode(original_minio_str))             return         elif '\/files' in self.path:             self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              files = list(client.list_objects(bucket_name, recursive=True))             files_str = '&lt;br>'.join(                 [f'&lt;p>{file.object_name} &amp;emsp; {client.stat_object(bucket_name, file.object_name).metadata}&lt;\/p>' for                  file in files])              self.wfile.write(str.encode(files_str))              return         else:             with open('index.html', 'r') as web_page_file:                 web_page = web_page_file.read()              self.send_response(200, 'OK')             self.send_header('Content-type', 'text\/html')             self.end_headers()              self.wfile.write(str.encode(web_page))              return   with socketserver.TCPServer((\"\", PORT), Handler) as httpd:     print(\"serving at port\", PORT)     httpd.serve_forever() <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>index.html<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"javascript\"> &lt;input type=\"file\" id=\"selector\" multiple> &lt;button onclick=\"upload()\">Upload&lt;\/button>  &lt;div id=\"status\">No uploads&lt;\/div>  &lt;script type=\"text\/javascript\">   \/\/ `upload` iterates through all files selected and invokes a helper function called `retrieveNewURL`.   function upload() {         \/\/ Get selected files from the input element.         var files = document.querySelector(\"#selector\").files;         for (var i = 0; i &lt; files.length; i++) {             var file = files[i];             \/\/ Retrieve a URL from our server.             retrieveNewURL(file, (file, url) => {                 \/\/ Upload the file to the server.                 uploadFile(file, url);             });         }     }      \/\/ `retrieveNewURL` accepts the name of the current file and invokes the `\/presignedUrl` endpoint to     \/\/ generate a pre-signed URL for use in uploading that file:      function retrieveNewURL(file, cb) {         fetch(`\/presignedUrl?name=${file.name}`).then((response) => {             response.text().then((url) => {                 cb(file, url);             });         }).catch((e) => {             console.error(e);         });     }      \/\/ ``uploadFile` accepts the current filename and the pre-signed URL. It then uses `Fetch API`     \/\/ to upload this file to S3 at `play.min.io:9000` using the URL:     function uploadFile(file, url) {         if (document.querySelector('#status').innerText === 'No uploads') {             document.querySelector('#status').innerHTML = '';         }         fetch(url, {             method: 'PUT',             body: file         }).then(() => {             \/\/ If multiple files are uploaded, append upload status on the next line.             document.querySelector('#status').innerHTML += `&lt;br>Uploaded ${file.name}.`;         }).catch((e) => {             console.error(e);         });     } &lt;\/script><\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>FROM python:alpine  RUN pip install minio  WORKDIR \/server  COPY server.py index.html .\/  ENTRYPOINT [\"python\", \"\/server\/server.py\"] <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>docker-compose.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> version: \"3.8\"  services:   minio:     image: minio\/minio     command: server \/data\/minio     ports:       - 9000:9000     environment:       - MINIO_ROOT_USER=minioadmin       - MINIO_ROOT_PASSWORD=minioadmin     networks:       - minio-local   server:     container_name: server     ports:       - 8080:8080     build: .     environment:       - MINIO_HOST=192.168.44.76       - MINIO_PORT=9000       - MINIO_USER=minioadmin       - MINIO_PASSWORD=minioadmin     networks:       - minio-local   networks:   minio-local:     driver: bridge<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a (\u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 MINIO_HOST \u043d\u0430 \u0441\u0432\u043e\u0451).<\/p>\n<pre><code> docker-compose up -d --build<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u0430\u0439\u043f\u0438\u0448\u043d\u0438\u043a\u0443 \u0438 \u043f\u043e\u0440\u0442\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 (\u043d\u0438\u0436\u0435 \u0432\u0435\u0437\u0434\u0435 \u0431\u0443\u0434\u0435\u0442 http:\/\/192.168.44.76, \u043f\u043e\u043c\u0435\u043d\u044f\u0439\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0439)<\/p>\n<figure class=\"\"><figcaption>http:\/\/192.168.44.76:8080<\/figcaption><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c <code>\/files<\/code>, \u0433\u0434\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a MinIO \u0438 \u0432\u0435\u0440\u043d\u0451\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0440\u044f\u0447\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430 Nginx<\/h2>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u0441\u043f\u0440\u044f\u0447\u0435\u043c \u0437\u0430 Nginx \u043f\u043e \u043f\u0443\u0442\u0438 <code>\/server<\/code>. MinIO \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 9000.<\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c nginx \u0432 <code>docker-file.yml<\/code> \u0438 \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433 nginx. \u0415\u0449\u0451 \u043d\u0430 \u0432\u0435\u0431 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0443\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443: <code>\/presignedUrl<\/code> -> <code>\/server\/presignedUrl<\/code>.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"\"><figcaption>http:\/\/192.168.44.76\/server<\/figcaption><\/figure>\n<\/p>\n<figure class=\"full-width\"><figcaption>http:\/\/192.168.44.76\/server\/files<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u043e\u0447\u0442\u0438 \u0443 \u0446\u0435\u043b\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043f\u0440\u044f\u0442\u0430\u0442\u044c MinIO \u0437\u0430 Nginx \u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0435\u0448\u0435\u043d\u0430. \u041d\u043e \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0441\u0430\u043c\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0439&#8230; \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e <a href=\"https:\/\/github.com\/minio\/console\/pull\/2174\">issue <\/a>\u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0440\u0435\u0448\u0435\u043d\u044b, \u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u0440\u0442. \u0414\u0430\u0436\u0435 \u0432 \u0440\u043e\u0434\u043d\u044b\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u0445 MinIO \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u0443\u0442\u0451\u043c \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430. \u041d\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0430\u0439\u043b\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e &#171;\u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443&#187; \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438 \u0434\u043e\u043a\u0435\u0440\u0430, \u0432\u0438\u0434\u043e\u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0451, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u043e\u0442\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0430 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u043d\u0430 Nginx \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0411\u0435\u0440\u0451\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Nginx <a href=\"https:\/\/min.io\/docs\/minio\/linux\/integrations\/setup-nginx-proxy-with-minio.html\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c location <code>\/minio-api<\/code>. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>nginx.conf<\/summary>\n<div class=\"spoiler__content\">\n<pre><code> user  nginx; worker_processes auto; worker_priority -20;  error_log  \/var\/log\/nginx\/error.log; pid        \/var\/run\/nginx.pid;  events {     worker_connections  4000; }  http {     server {         listen 80;         resolver 127.0.0.11 valid=5s ipv6=off;          # To allow special characters in headers         ignore_invalid_headers off;         # Allow any size file to be uploaded.         # Set to a value such as 1000m; to restrict file size to a specific value         client_max_body_size 0;         # To disable buffering         proxy_buffering off;          proxy_redirect off;          set $server http:\/\/server:8080;          location \/server {                 rewrite ^\/server(.*) \/$1 break;                 proxy_pass $server;         }          set $minio_port 9000;         set $minio_host minio;         set $minio_url http:\/\/$minio_host:$minio_port;          location ~* ^\/minio-api {            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_set_header X-Forwarded-Proto $scheme;            proxy_set_header Host $http_host;             proxy_connect_timeout 300;            # Default is HTTP\/1, keepalive is only enabled in HTTP\/1.1            proxy_http_version 1.1;            proxy_set_header Connection \"\";            chunked_transfer_encoding off;             proxy_pass $minio_url;         }     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0438&#8230;.. <strong>\u0424\u0418\u0410\u0421\u041a\u041e&#8230; <\/strong>\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f 403 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 curl \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0442\u0432\u0435\u0442 (\u043f\u0440\u0438\u0432\u0451\u043b \u043a \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c\u0443 \u0432\u0438\u0434\u0443):<\/p>\n<pre><code class=\"bash\"> curl -X 'PUT' 'http:\/\/192.168.44.76\/minio-api\/uploads\/sausage.drawio?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=minioadmin%2F20230214%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20230214T124222Z&amp;X-Amz-Expires=604800&amp;X-Amz-SignedHeaders=host&amp;X-Amz-Signature=83d00d24d975f6c6263129d85f9a820b319d78d7d6738513a86429a2441b5f03'  &lt;?xml version=\"1.0\" encoding=\"UTF-8\"?> &lt;Error> &lt;Code>SignatureDoesNotMatch&lt;\/Code> &lt;Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.&lt;\/Message> &lt;Key>uploads\/sausage.drawio&lt;\/Key> &lt;BucketName>minio-api&lt;\/BucketName> &lt;Resource>\/minio-api\/uploads\/sausage.drawio&lt;\/Resource> &lt;RequestId>1743B1AB6535B5E1&lt;\/RequestId> &lt;HostId>e96154ee-0e6d-422b-8102-feea5d741fae&lt;\/HostId> &lt;\/Error><\/code><\/pre>\n<p>\u0412\u0438\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u0447\u0442\u043e \u0437\u0430\u0431\u044b\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c rewrite, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0440\u0430\u0442\u044c <code>minio-api<\/code> \u0438\u0437 \u043f\u0443\u0442\u0438, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c, \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c.<\/p>\n<pre><code>rewrite ^\/minio-api(.*) $1 break;<\/code><\/pre>\n<p>\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0444\u0430\u0439\u043b, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 &#8212; \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0430\u0441\u044c.<\/p>\n<h2>\u0418\u0442\u043e\u0433\u043e<\/h2>\n<p>\u041d\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0437\u0430 Nginx \u0431\u0435\u0437 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043e\u0440\u0442\u043e\u0432 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b.<\/p>\n<p>\u0410 \u0447\u0442\u043e \u0442\u0430\u043c \u0441 HTTPS? \u0412\u0441\u0451 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0438\u0442\u044c SSL Termination \u043d\u0430 Nginx. \u041f\u043b\u044e\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c  \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f minIO. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u043d\u0430\u0434\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0432 \u0441\u0441\u044b\u043b\u043a\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <code>http<\/code> \u043d\u0430 <code>https<\/code>. \u041e\u0441\u0442\u0430\u0432\u043b\u044e \u044d\u0442\u043e \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u041a\u043e\u0434 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/AlexNik\/MinIO-tutorial\">\u0442\u0443\u0442<\/a>.<\/p>\n<h2>PS<\/h2>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-393024","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/393024","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=393024"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/393024\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=393024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=393024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=393024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}