隨著容器化技術的普及,Docker 已成為不少雲端原生應用程式開發和部署的首選平台。而其中一個常見的應用場景是容器與外部資源的交互,例如上傳、下載檔案等。但有時在使用 Docker 容器上傳檔案時,會發現檔案流讀取不到的情況。本文將探討這種情況出現的原因,以及解決方法。
一、問題描述
我在使用 Docker 容器上傳檔案時,發現上傳成功,但讀取檔案流時出現了問題,檔案流為空。我嘗試了多種方法,包括使用本機檔案讀取、遠端檔案讀取,都無法解決。以下是我的程式碼範例:
import io from datetime import datetime from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/upload', methods=['POST']) def upload_file(): f = request.files['file'] stream = io.StringIO() stream.write(f.stream.read()) stream.seek(0) print(stream.read()) return jsonify({'success': True}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)
使用curl
指令上傳檔案時,可以看到上傳成功了,但讀取檔案流時卻為空:
$ curl -X POST -F "file=@test.txt" http://localhost:5000/upload {"success": true} $ python app.py 2019-12-26 16:10:10,990 - INFO - * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 2019-12-26 16:10:16,930 - INFO -
二、問題分析
在容器內部,可以透過docker cp
指令將檔案複製到容器內部進行測試,可以發現檔案流讀取沒有問題。所以問題顯然不是出在讀取檔案流的程式碼上面。
我查閱了一些資料,發現 Docker 在處理上傳檔案時,會使用 TempFS 做為上傳檔案的暫存目錄。而可能出現的原因是,容器內部的檔案系統隔離導致上傳的檔案無法被讀取。
三、解決方法
解決問題需要使用三種方法中的任一種:
--privileged
運行容器啟用特權模式,即使用--privileged
運行容器。這個選項會讓容器擁有主機的 root 權限。
$ docker run --privileged -d -p 5000:5000 my-image
--tmpfs /path/to/tmpfs:rw
選項使用--tmpfs
掛載臨時檔案系統,可以保證上傳的檔案能夠被正確地讀取。
$ docker run -d -p 5000:5000 --tmpfs /tmp:rw my-image
直接將主機檔案系統中的目錄掛載到容器的某個路徑下,可以使得容器內外都能夠正確讀取上傳的檔案。
$ docker run -d -p 5000:5000 -v /path/to/host/drive:/path/to/container/drive my-image
使用以上任一方法,再次上傳測試,可以看到上傳和讀取檔案流都成功了:
$ curl -X POST -F "file=@test.txt" http://localhost:5000/upload {"success": true} $ python app.py 2019-12-26 16:55:01,697 - INFO - * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 2019-12-26 16:55:03,428 - INFO - This is a test file.
總之,Docker 的檔案系統隔離機制有時會導致上傳文件不能正確讀取,但有以上三種解決方法可以選擇。希望本文能對您在使用 Docker 應用程式時遇到的問題有所幫助。
以上是docker上傳檔案流讀取不到怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!