假如已经按照上一篇的流程创建了一个容器,并且在容器内安装了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
的方式生成容器了。
具体的问题描述我贴在了这里,如果哪位大神路过,欢迎不吝赐教!感激!