【问题标题】:Why are my ports not being mapped in docker-compose?为什么我的端口没有在 docker-compose 中映射?
【发布时间】:2018-07-20 18:41:31
【问题描述】:

我目前有一个用 Flask 编写的用于与 CNN 交互的小 api,我正在设置在 Docker 中运行它的配置,一切运行良好,这是我的实际配置:

Dockerfile:

FROM python:2.7.15-jessie
RUN mkdir -p usr/src/app
COPY . usr/src/app
WORKDIR usr/src/app
RUN which python
RUN apt-get update && apt-get install -y
RUN pip install flask flask_uploads Werkzeug opencv-python numpy tensorflow
ENV PORT 5000
EXPOSE 5000
CMD ["flask", "run"]

Docker 撰写:

version: "2.2"
services:
  api:
    container_name: "pyserver"
    build: .
    volumes:
      - ".:/usr/src/app"
    environment:
      FLASK_APP: server.py
    ports:
      - "5000:5000"
    command: ["flask", "run"]

server.py

import os
from base64 import b64encode, b64decode
from flask import Flask, redirect, request, url_for, json, send_file
from flask_uploads import UploadSet, configure_uploads
from werkzeug.utils import secure_filename
from GW_predict import predict

UPLOAD_FOLDER = 'CNN/Files'
ALLOWED_EXTENSIONS = set(['txt', 'csv', 'png', 'jpg', 'jpeg'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config["DEBUG"] = True

def allowed_file(filename):
    ext = '.' in filename and \
           filename.rsplit('.', 1)[1].lower()
    return ext, ext in ALLOWED_EXTENSIONS

@app.route('/status', methods=['GET'])
def status():
    return create_response({ 'online': True, 'message': 'UP AND RUNNING @ 5000' }, 200)

@app.route('/uploadFile', methods=['POST'])
def upload_file():
    if 'h1' not in request.files or 'l1' not in request.files:
        return create_response({'result': False, 'message': 'File missing'}, 422)

    h1_file = request.files['h1']
    l1_file = request.files['l1']

    if h1_file.filename == '' or l1_file.filename == '':
        return create_response({'result': False, 'message': 'File missing'}, 422)

    h1_ext, h1res = allowed_file(h1_file.filename)
    l1_ext, l1res = allowed_file(l1_file.filename)

    if h1_file and l1_file and h1res and l1res:
        h1_filename = secure_filename(h1_file.filename)
        l1_filename = secure_filename(l1_file.filename)
        h1 = os.path.join(app.config['UPLOAD_FOLDER'], h1_filename)
        l1 = os.path.join(app.config['UPLOAD_FOLDER'], l1_filename)
        h1_file.save(h1)
        l1_file.save(l1)
        # img = b64encode((open(img, "rb").read()))
        if h1_ext == 'png' and l1_ext == 'png':
            result = predict(h1, l1)
            return create_response({'result': True, 'prediction': result}, 200)

        return create_response({'result': False, 'message': 'Images format must be png'}, 422)

    return create_response({'result': False, 'message': 'No allowed file'}, 422)

def create_response(message, status):
    response = app.response_class(
        response= json.dumps(message),
        status= status,
        mimetype='application/json'
    )
    return response

if __name__ == '__main__':
    app.run()

问题在于,在我的 docker-compose 文件中,我已经配置了“ports”指令,我在其中定义了在我的主机中公开 de 端口 5000 并转发到容器中的同一端口。

这不起作用。

在容器内我可以通过 CURL 向端点发出请求,但在容器外我无法这样做。有什么问题?

【问题讨论】:

  • docker ps 显示什么?
  • 什么都没有:/,但是docker ps -a 显示了这个:> 06bd82268dc9 cnn_api "flask run" 22 minutes ago Up 4 seconds 0.0.0.0:5000->5000/tcp pyserver
  • 您能否分享用于 curl 的代码,该代码在容器内部工作,而在容器外部不工作。另外,您能否确认在主机上您还没有 5000 个?
  • 您的应用在容器内监听哪些接口?请参阅netstat usage with netshoot,了解如何在不安装网络工具的情况下检查这一点。
  • @Const 内部:curl http://localhost:5000/status,外部:curl http://localhost:5000/statuscurl http://127.0.0.1:5000/status 它们(外部)都不起作用

标签: python docker flask


【解决方案1】:

也许您需要指定--host=0.0.0.0 标志? (来自here)。

您可以尝试在 docker-compose 中覆盖您的 command 吗?

version: "2.2"
services:
  api:
    container_name: "pyserver"
    build: .
    command: flask run --host=0.0.0.0
    volumes:
      - ".:/usr/src/app"
    environment:
      FLASK_APP: server.py
    ports:
      - "5000:5000"
    command: ["flask", "run"]

顺便说一句,如果您仅从主机(而不是其他容器)进行通信,则不确定 dockerfile 中的 EXPOSE 是否必要。

【讨论】:

  • 很确定就是这样(因此我的评论询问接口)。如果烧瓶默认为环回,则无法从外部访问它。你也可以在python脚本中app.run(host='0.0.0.0',port='5000')
  • @BMitch 对,只是想给出一个快速的解决方案,看看是不是这样..
  • 就是这样!谢谢你,兄弟。添加标志使其工作。
  • 根据您的公开评论,除了文档之外不需要任何其他内容。在发布端口或容器之间通信时,它对 docker 网络的行为没有影响。
  • 是的,我知道它除了文档之外什么都不做。谢谢你的时间! @BMitch
猜你喜欢
  • 2022-10-17
  • 2021-04-04
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多