Usando AWS re:Post, accetti AWS re:Post Termini di utilizzo

Getting Nginx 502 Bad Gateway after deploying Flask API to Elastic Beanstalk |111: Connection refused while connecting to upstream

0

I'm really new into servers and stepping from development into production and lately I've had some errors while deploying a Flask API to AWS Elastic Beanstalk. I "successfully" deployed my API through EB CLI as it said so, but when I open the domain, it only says "502 Bad Gateway - nginx".

I downloaded the logs, and I'm pretty concerned about what nginx's error.log says:

connect() failed (111: Connection refused) while connecting to upstream, client: 172.31.41.209, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8000/", host: "172.31.22.111"

I thought the proccess was pretty straightforward when it comes to deploying to EB, but I've tried to solve this problem and I haven't been able. My API runs perfectly in development; I've tested it a lot of times in localhost at default port, but now in deployment it no longer works. So I think it's more of a reverse-proxy-related problem, but I don't know much about this, so I'd appreciate so much your help. I've used Windows the whole time and virtually every info out there is Linux-related, so I'm very limited to it.

I'm going to paste a fragment of web.stdout.log, which looks like to show some errors related to Gunicorn:

Apr 27 23:44:18 ip-172-31-22-111 web[2165]: [2024-04-27 23:44:18 +0000] [2165] [INFO] Starting gunicorn 22.0.0

Apr 27 23:44:18 ip-172-31-22-111 web[2165]: [2024-04-27 23:44:18 +0000] [2165] [INFO] Listening at: http://127.0.0.1:8000 (2165)

Apr 27 23:44:18 ip-172-31-22-111 web[2165]: [2024-04-27 23:44:18 +0000] [2165] [INFO] Using worker: gthread

Apr 27 23:44:18 ip-172-31-22-111 web[2197]: [2024-04-27 23:44:18 +0000] [2197] [INFO] Booting worker with pid: 2197

Apr 27 23:44:18 ip-172-31-22-111 web[2197]: [2024-04-27 23:44:18 +0000] [2197] [ERROR] Exception in worker process

Apr 27 23:44:18 ip-172-31-22-111 web[2197]: Traceback (most recent call last): Apr 27 23:44:18 ip-172-31-22-111 web[2197]: File "/var/app/venv/staging-LQM1lest/lib64/python3.11/site-packages/gunicorn/arbiter.py", line 609, in spawn_worker

Please help!

Within my limited knowledge of servers, deploying, AWS, I've tried to find an error with the way the API interacts with server but I haven't get so far yet, so I expect someone who knows about this and is willing to help me, may tell me what to fix and how to do it (what tools needed, commands, etc.) in order to solve this problem. Thanks a lot beforehand.

This is the Python Flask API I've coded and tested successfully:


import json
from flask_cors import CORS
from flask import (Flask, Response, request)
import util


application = Flask(__name__)
CORS(application)  
RESPONSE_HEADERS = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' }    

@application.route('/welcome')
def welcome():
    valA, valB = util.get_years(-1, -1, 1)
    message = "This is a test for the API and the underlying function. Val A: " + str(valA) + ", Val B: " + str(valB)
    return message

@application.route('/years2pay', methods=['POST'])
def calc():
    data = request.get_json()
    strategy_pA = data.get('strategy_pA', None)
    strategy_pB = data.get('strategy_pB', None)
    w = data.get('w', None)
    
    if not strategy_pA or not strategy_pB or w == None:
        return Response(json.dumps({ 'error': 'Not enough data' }), status=400, headers=RESPONSE_HEADERS)
    
    valA, valB = util.get_years(int(strategy_pA), int(strategy_pB), float(w))
    return Response(json.dumps({ 'years_playerA': valA, 'years_playerB': valB }), status=200, headers=RESPONSE_HEADERS)
        


if __name__ == '__main__':
    application.debug = True
    application.run()

I used CORS because I need it to serve as backend for my frontend which is already deployed on another domain. I know that as it's configured, it's unsafe for deployment, but just to make clear that it hasn't been a problem

**Implementation details: **

  • I added a .ebignore file which contains the string virt (the python's virtual environment)
  • I ran pip freeze > requirements.txt so EB knows the modules the app needs to run
  • Having everything ready, I cd to the directory and ran eb init -p python-3.11 myapp-deploy --region us-east-2
  • Ran eb init
  • Set up my SSH keypair
  • Ran eb create app-instance
  • Waited 4 minutes and it said the app was succesfully deployed. Ran eb open, and got to that domain on my browser which explicitly said 502 Bad Gateway - nginx
  • Checking the health status it said a 100% petitions were rejected and went from "Severe" to "Degrade".
  • I terminated the instance.
posta 7 mesi fa838 visualizzazioni
1 Risposta
1
Risposta accettata

Hello.

From the contents of the error log, it appears that port 8000 is not being accessed properly.
It may be that FlaskAPI is not running properly.
Could you please share the specific configuration files and commands you are running?

profile picture
ESPERTO
con risposta 7 mesi fa
  • Hi, Riku. Thanks for answering; I thank you so much. I've updated my post with the Python Flask code. It uses a function from a file contained in the same directory where the API is. As I said, in development it worked pretty fine, both the GET and POST methods. Nonetheless, here in deployment it no longer works. I'll add some info about how I did the proccess too. Thanks again, Sir.

  • "/welcome" and "/years2pay" are set for GET and POST, will it work if I access them? Looking at the log, it appears that only "/" is being accessed. In other words, try accessing something like the following and see if it works.

    http://elasticbeanstalk-dns-name/welcome
    

    I think it is also possible that a module required for the application is not listed in "requirements.txt".

  • Hi, Riku. You were correct! Actually this port wasn't being accessed. The API wasn't even loading. I'm a bit ashamed of saying the reason why: my API file name was not application.py! I wasn't even aware of this, and didn't even know that. I changed the name and it worked so fine! Thanks for taking the time to answer, Sir. Have a good one.

Accesso non effettuato. Accedi per postare una risposta.

Una buona risposta soddisfa chiaramente la domanda, fornisce un feedback costruttivo e incoraggia la crescita professionale del richiedente.

Linee guida per rispondere alle domande