如何在 docker 容器中设置 flask-socketio?
Posted
技术标签:
【中文标题】如何在 docker 容器中设置 flask-socketio?【英文标题】:How to setup flask-socketio in a docker container? 【发布时间】:2019-01-25 23:09:30 【问题描述】:您好,我正在尝试在 docker 容器中设置 flask-socketio。 它似乎可以运行,但是当我尝试访问端口 5000 上的 localhost 时出现错误(来自浏览器),就像我习惯使用烧瓶应用程序一样。它说:无法连接!
我将向你展示 5 个重要文件:Dockerfile、requirements.txt、docker-compose.yml、web_app.py 和 index.html
Dockerfile:
FROM python:3.6.5
WORKDIR /code
COPY * /code/
RUN pip install -r requirements.txt
requirements.txt:
Flask==1.0.2
Flask-SocketIO==3.0.1
eventlet==0.24.1
docker-compose.yml:
version: "3"
services:
web:
build: ./web
ports:
- '5000:5000'
volumes:
- './web:/code'
我使用命令docker-compose up --build
和docker-compose run web /bin/bash
以交互模式进入这个容器。
web_app.py:
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('my event')
def log_message(message):
emit('my response', 'data': 'got it!')
if __name__ == '__main__':
socketio.run(app)
index.html:
<!doctype html>
<html>
<head>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<title>SocketIO</title>
</head>
<body>
<script type="text/javascript" charset="utf-8">
//Establish connection and emit a message to confirm.
var socket = io.connect('http://' + document.domain + ':' + location.port);
socket.on('connect', function()
socket.emit('my event', data: 'I\'m connected!');
);
</script>
</body>
</html>
进入容器后,我简单地运行:python web_app.py
,但没有任何反应。没有错误,也没有工作页面。
我觉得我错过了正确初始化所有内容的步骤,但我不知道它是什么。网络上到处都是非常不同的例子,我很困惑。更难的是我在这里使用了 eventlet,但并不是每个例子都走这条路。有些使用 gevent 或其他东西。
如果有人给我一点提示,我会非常高兴。 干杯
【问题讨论】:
试试socketio.run(app, host='0.0.0.0')
。我认为您默认情况下仅在 localhost 上运行,这意味着只有 docker 容器内的其他应用程序可以访问它(即无)
@Hitobat 好吧,我可以将主机作为第二个参数传递而不会出错,但一切都保持不变。没有网站,也没有错误。应用程序“IS”正在运行,但我看不到它:(
如果我在 docker-compose.yaml 中包含暴露?
你能先验证一下代码在没有 docker 的情况下可以工作吗?即,如果您在本地运行它,您可以正确加载页面吗?然后我们可以看看这是代码问题还是docker问题。
@Hitbat 是的,这将是一件好事,但问题是我不想在本地安装任何东西。我以虚拟环境的方式使用 docker 来保持我的操作系统干净。
【参考方案1】:
开始撰写时,请确保为烧瓶设置了所有环境变量。还提供--host=0.0.0.0
以在您的入口点或命令中侦听所有网络接口。
更新的 docker-compose 文件:
version: "3"
services:
web:
build: ./web
volumes:
- './application:/application'
environment:
FLASK_DEBUG: 1
FLASK_ENV: development
FLASK_APP: web_app.py
ports:
- '5000:5000'
entrypoint:
- flask
- run
- --host=0.0.0.0
当您想以交互模式运行容器以用于开发目的时,您可以使用docker-compose run 下面的命令来运行它。 --service-ports
需要公开撰写文件中指定的容器端口。如果未提供此标志,则不会有外部流量到达应用程序。那是我最初的问题。
docker-compose run --service-ports web bash
您也可以手动发布端口
docker-compose run --publish 5000:5000 web bash
【讨论】:
感谢您之后写下答案。【参考方案2】:您尚未在 docker 容器中启动应用程序。在 Dockerfile 中再添加两行:
EXPOSE 5000
ENTRYPOINT ["python", "/code/web_app.py"]
【讨论】:
好吧,如果您仔细阅读我写的内容,您会意识到,虽然当我使用docker-compose up --build
时 docker-compose 确实不会启动应用程序,但这就是为什么我在构建图像后运行以下逗号的原因:docker-compose run app /bin/bash
,在里面我运行python web_app.py
。(我的帖子里都是这样写的)无论如何,我会尝试使用expose并尽快让你知道。
所以结果很奇怪。我不需要公开,但是当我使用入口点时,它可以工作,但只能在我的 socketio 应用程序中将主机设置为 0.0.0.0 。我会在下面发布答案以上是关于如何在 docker 容器中设置 flask-socketio?的主要内容,如果未能解决你的问题,请参考以下文章
当在docker容器中设置php时,如何在vscode中设置php可执行路径php.validate.executablePath?
如何在 Docker 容器中设置 Java 堆大小(Xms/Xmx)?
如何在 Debian/Ubuntu Docker 容器中设置语言环境?