假如已經按照上一篇的流程創建了一個容器,並且在容器內安裝了python環境以及flask相關的包,接下來啓動一個服務,供容器外調用。
1. A quick start
首先要使用docker start
命令啓動一個已經停止的容器:
docker start -i c2f30
指定-i
參數,則可以進入容器內部。
接下來,創建一個python腳本:
# test.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def func():
return "Hello docker!"
if __name__ == '__main__':
app.run('0.0.0.0', port=5000)
然後運行python test.py
,控制檯應該打印以下內容:
* Serving Flask app "test" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
好了,至此我們已經啓動了一個簡單的HTTP服務。接下來,需要讓容器掛起在後臺運行,然後去宿主機看看能不能請求到這個服務。
爲了退出容器時讓其在後臺運行,可以按住Ctrl+P+Q
退出。退出後用docker ps
查看,發現該容器的狀態是Up
,即“掛起”。
打開宿主機的瀏覽器,在地址欄輸入http://localhost:5000/
,就可以看到屏幕顯示的“Hello docker!”了。或者利用curl
命令:
curl http://127.0.0.1:5000/
2. 爲什麼沒有做端口映射?
注意到在第一步中,並沒有做所謂的端口映射,但宿主機仍然可以請求到容器內的服務,這是因爲在創建容器時指定了--network
參數的值爲host
,其作用可以理解爲容器和宿主機是網絡共享的。既然網絡都是共享的,當然不需要額外指定端口了。
比較正式的說法,可以去官網查看。
如果在用docker run
創建新容器時不指定--network
,此時的網絡連接方式爲bridge
,那麼要想宿主機可以訪問容器內的服務,就需要指定端口映射了:
docker run -it -p 50001:5000 my-first-image /bin/bash
-p
參數的意思是將容器的端口(5000)映射到宿主機的50001上。
想象中,按照上述方式啓動了一個容器,並執行python test.py
。那麼在容器外訪問http://127.0.0.1:50001/
,然而,我執行了curl
命令後,得到的結果是:
[root@localhost ~]# curl http://127.0.0.1:50001/
curl: (56) Recv failure: Connection reset by peer
這是什麼原因呢?我查了很久的資料,也在不同的平臺上提問過,但目前仍然沒有找到原因及解決方案。所以,只能採用--network host
的方式生成容器了。
具體的問題描述我貼在了這裏,如果哪位大神路過,歡迎不吝賜教!感激!