如何在Docker容器中设置flask-socketio?

时间:2018-08-19 17:43:52

标签: python docker flask flask-socketio eventlet

你好,我正在尝试在Docker容器中设置flask-socketio。 它似乎正在运行,但是当我尝试访问端口5000上的localhost时,出现了错误(来自浏览器),就像我以前使用flask应用程序一样。上面写着:无法连接!

我将向您展示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 --builddocker-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或其他东西。

如果有人给我一点提示,我将非常高兴。 欢呼声

2 个答案:

答案 0 :(得分:2)

Update2 尽管我在下面写的是正确的做法,也是更好的做法,但我发现了docker-compose的一个功能,该功能可以使问题的初始代码运行。我们需要添加--service-ports,否则run命令将不会暴露端口:

 docker-compose run --service-ports web

更新:我发现我们也可以在docker-compose.yaml中定义本地主机,而不必在python文件中将其作为参数传递。 主机的入口点需要加倍-像这样: - --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: __init__.py

    ports:
      - '5000:5000'

    entrypoint:
      - flask
      - run
      - --host=0.0.0.0

旧-----:

因此,事实证明,解决方案(我尚不知道它有多有用)是这里建议的东西的组合。

所以首先我需要像下面这样在我的python文件中将主机设置为参数:

if __name__ == '__main__':
socketio.run(app, host='0.0.0.0')

此外,我不能只使用docker-compose run web /bin/bash,然后再使用python web_app.py,但是我必须在docker-compose文件中为这样的Web服务使用和entrypoint:

    entrypoint:
    - python
    - web_app.py

将这两件事结合在一起时,使用docker-compose up时,我实际上可以在端口5000上看到我的页面。该Web服务被附加并运行该应用程序。现在,我只需要查看它的用处,因为我将代码目录安装为卷,因此不必一直重建映像。我不确定这是否仍然可以正常工作。

感谢大家在这里帮助我。

编辑:因此,要获得所需的行为,我可以使用flask环境变量。 我在docker-compose.yml中将它们设置为我的Web服务:

  environment:
    FLASK_DEBUG: 1
    FLASK_ENV: development

P.s。这是更完整的docker-compose.yml:

version: "3"

services:

  web:
    build: ./web
    environment:
      FLASK_DEBUG: 1
      FLASK_ENV: development
    ports:
      - '5000:5000'
    volumes:
      - './web:/code'
    entrypoint:
      - python
      - web_app.py

答案 1 :(得分:0)

您尚未在Docker容器中启动应用程序。在Dockerfile中再添加两行:

EXPOSE 5000

ENTRYPOINT ["python", "/code/web_app.py"]