Azure: erro do aplicativo Docker "... o site não foi iniciado dentro do limite de tempo esperado " e "o contêiner X não respondeu a pings HTTP na porta 80"

Eu tenho um aplicativo Python Flask que é executado via Gunicorn a partir de um contêiner Docker Linux. A execução do contêiner Docker no Ubuntu funciona bem localmente, mas quando o contêiner é enviado para o registro do contêiner do Azure e implantado como um aplicativo do Azure, ele falha com as seguintes mensagens de erro:

  1. Container my-app_900f4c para o site my-app não foi iniciado dentro do limite de tempo esperado.
  2. Container my-app_900f4c não respondeu a pings HTTP na porta: 80, falhando no início do site.

Docker Log

2020-02-17 INFO  - Pull Image successful, Time taken: 0 Minutes and 15 Seconds2020-02-17 INFO  - Starting container for site2020-02-17 INFO  - docker run -d -p 9031:80 --name my-app_900f4c -e PORT=80 -e WEBSITES_PORT=80 -e WEBSITE_SITE_NAME=my-app -e WEBSITE_AUTH_ENABLED=False -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=my-app.azurewebsites.net -e WEBSITE_INSTANCE_ID=eaaf...51e441df96704916ba7b506b6150b26cdc7 -e HTTP_LOGGING_ENABLED=1 myazureappregistry.azurecr.io/my_app:v1  2020-02-17 INFO  - Initiating warmup request to container my-app_900f4c for site my-app2020-02-17 ERROR - Container my-app_900f4c for site my-app did not start within expected time limit. Elapsed time = 255.9515056 sec2020-02-17 ERROR - Container my-app_900f4c didn't respond to HTTP pings on port: 80, failing site start. See container logs for debugging.2020-02-17 INFO  - Stopping site my-app because it failed during startup.

Log Do Docker Padrão

2020-02-17 [1] [INFO] Starting gunicorn 20.0.42020-02-17 [1] [INFO] Listening at: http://0.0.0.0:80 (1)2020-02-17 [1] [INFO] Using worker: gthread2020-02-17 [7] [INFO] Booting worker with pid: 72020-02-17 [8] [INFO] Booting worker with pid: 82020-02-17 [9] [INFO] Booting worker with pid: 92020-02-17 [10] [INFO] Booting worker with pid: 10

No portal do Azure em Configurações & gt; Configuração Eu tenho o seguinte Configuracao:

  • Porto 80
  • WEBSITES_PORT 80

Dockerfile

FROM python:3.8-slim-busterLABEL Name=my_app Version=0.0.1EXPOSE 80WORKDIR /appRUN python3 -m pip install --upgrade pipRUN python3 -m pip install -r requirements.txtADD . /appCMD ["gunicorn", "-c", "gunicorn.conf.py", "main:app"]

Não entendo o que está causando pings HTTP na porta 80 para falhar, quando os logs mostram que Gunicorn está ouvindo http://0.0.0.0:80.

Perguntas semelhantes que têm nao resolvido o problema:

O contêiner deve implementar um manipulador de erro HTTP 404 (não encontrado).

Quando o Azure inicia um contêiner, o solicitação de aquecimento verifica o servidor solicitando recursos para garantir que ele esteja respondendo. Se um dos recursos solicitados não for encontrado e o contêiner não tiver um HTTP 404 (Não encontrado) manipulador de erros, então a solicitação será tempo limite e o contêiner será interrompido.

Configuração Da Porta Do Contêiner Docker

azul PORT bandeira não é necessário. O WEBSITES_PORT o sinalizador deve ser definido para qualquer porta exposta dentro do contêiner.

Definir WEBSITES_PORT do Azure CLI da seguinte forma:

az webapp config appsettings set --resource-group <resource-group-name> --name <app-name> --settings WEBSITES_PORT=8000

Ou use o Portal do Azure:
Seu aplicativo & gt; Configurações & gt; Configuração & gt; Configurações do aplicativo

Exemplo Flask-manipulador de erro HTTP 404

from flask import Flaskfrom werkzeug.exceptions import Forbidden, HTTPException, NotFound, RequestTimeout, Unauthorizedapp = Flask(__name__)@app.route('/')def hello():    return "Hello Flask!"@app.errorhandler(NotFound)def page_not_found_handler(e: HTTPException):    return render_template('404.html'), 404@app.errorhandler(Unauthorized)def unauthorized_handler(e: HTTPException):    return render_template('401.html'), 401@app.errorhandler(Forbidden)def forbidden_handler(e: HTTPException):    return render_template('403.html'), 403@app.errorhandler(RequestTimeout)def request_timeout_handler(e: HTTPException):    return render_template('408.html'), 408if __name__ == '__main__':    app.run()