Ravindra BagaleCourses & study guides English

EC2 वर Python Flask App: Gunicorn आणि Nginx सह Hosting

तुमच्या phone वरचे बहुतेक apps web pages download करत नाहीत. ते server कडे data मागतात आणि screen स्वतः काढतात. ती server बाजू म्हणजे API, आणि Python आणि Flask हा तो बनवायचा सगळ्यात सोपा मार्ग आहे. या chapter मध्ये API website पेक्षा कसा वेगळा ते शिकाल, Amazon Linux 2023 EC2 instance वर Python, pip आणि virtual environment set up कराल, छोटा Flask app लिहाल, आणि तो test server पासून योग्य setup पर्यंत न्याल: gunicorn तो background मध्ये चालवतो, समोर nginx reverse proxy म्हणून, port 5000 बंद, आणि systemd service जी तो boot ला start करते आणि code बदलला की reload करते.

या class मध्ये काय शिकणार

  • Website आणि API मधला फरक, आणि JSON data कसा नेतो
  • Python app hosting ला काय लागतं: python3, pip, virtual environment, gunicorn आणि nginx
  • Package managers: yum, pip, npm आणि composer
  • Virtual environment बनवणं आणि activate करणं, आणि sudo pip चूक का
  • requirements.txt आणि दोन routes चा Flask app.py लिहिणं
  • Flask development server आणि तात्पुरत्या port 5000 rule ने testing
  • gunicorn ने app background मध्ये चालवणं, आणि app:app चा अर्थ
  • Reverse proxy म्हणून nginx, त्याचे worker processes आणि worker_connections
  • gunicorn 127.0.0.1 वर bind करणं आणि port 5000 बंद करणं
  • JSON API route टाकणं आणि kill -HUP ने gunicorn reload करणं
  • gunicorn साठी systemd service, आणि एका nginx वर अनेक sites
  • 502 Bad Gateway, nginx welcome page आणि nginx -t errors सोडवणं

1. Website की API

का: Laptop screen साठी बनवलेलं web page Android phone, iPhone आणि tablet ला एकाच वेळी बसत नाही. आजचे apps यावर उपाय म्हणून server कडे फक्त data मागतात.

काय:

  1. Website पूर्ण HTML page ने उत्तर देते: layout, text आणि images एकत्र. Browser फक्त ते दाखवतो.
  2. API (Application Programming Interface) फक्त data ने उत्तर देतो. प्रत्येक app, Android, iPhone किंवा web, त्या data वरून स्वतःची screen काढतो.
  3. Data बहुतेक वेळा JSON म्हणून जातो: curly braces { } मधल्या key: value जोड्या. Text values double quotes मध्ये, numbers quotes शिवाय, आणि जोड्यांमध्ये comma.

Classroom line

If the server sends back a page, it's a website.

Classroom line

These days, servers send data.

Website पूर्ण page पाठवते; API फक्तdata पाठवतो Website Browser Server <html><body> <h1>Reels</h1> <img src="..."> ...</body></html> Server पूर्ण HTML page बनवतो.Browser ला चालतं, प्रत्येक phone app ला नाही बसत. API Android, iPhone, web Server {"username": "ravi", "likes": 50, "caption": "on the top"} Server फक्त data पाठवतो, JSON मध्ये.प्रत्येक app तोच data वापरून स्वतःची screen काढतो.

Figure 1. Website पूर्ण HTML page पाठवते; API फक्त data JSON मध्ये पाठवतो, आणि प्रत्येक app, Android, iPhone किंवा web, त्यावरून स्वतःची screen काढतो.

Worked example: short-video app मधली एक reel. App server कडे पुढची reel मागतो आणि त्याला मिळतं:

{
  "username": "ravi",
  "profile_pic": "https://.../ravi.jpg",
  "caption": "on the top",
  "video_url": "https://.../reel42.mp4",
  "likes": 50
}
  1. App username आणि profile_pic screen च्या वर दाखवतो.
  2. video_url मधला video मध्यभागी चालवतो.
  3. caption आणि likes चा आकडा video खाली लिहितो.

Classroom line

JSON sits inside curly braces.

एक reel JSON मध्ये, आणि app प्रत्येक value कुठेदाखवतो { "username": "ravi", "profile_pic": "https://.../ravi.jpg", "caption": "on the top", "video_url": "https://.../reel42.mp4", "likes": 50 } ◯ ravi ▶ video इथे चालतो on the top ♥ 50 likes JSON = curly braces { } मधल्या key:value जोड्या. Text double quotes मध्ये, numbers quotes शिवाय, जोड्यांमध्ये comma. App ला keys माहीत असतात आणि तो प्रत्येक value जागेवर ठेवतो.

Figure 2. एक reel JSON मध्ये: app ला keys माहीत असतात आणि तो username आणि profile_pic वर, video मध्यभागी, आणि caption आणि likes खाली ठेवतो.

या chapter च्या पुढच्या भागात तुम्ही असाच छोटा API Python मध्ये बनवाल आणि EC2 वर host कराल.

2. Python app hosting ला काय लागतं

का: Python app म्हणजे एक program नाही, stack आहे. सहा भाग माहीत असले की काय install करायचं ते कळतं, आणि app बंद पडलं की कोणता भाग तपासायचा ते कळतं.

काय: खालून वर, सहा भाग:

  1. python3, भाषा स्वतः. Python 2 retire झालाय; Python 3 मध्ये इतके बदल झाले की दोघांच्या commands वेगळ्या आहेत, python2 आणि python3. Amazon Linux 2023 मध्ये फक्त python3 येतो.
  2. pip, Python चा package manager. तो Flask सारख्या libraries download करतो.
  3. Virtual environment (venv), एक folder ज्यात एका app च्या libraries असतात, बाकी सगळ्या apps पासून वेगळ्या.
  4. App: Flask मध्ये लिहिलेला app.py, आणि त्याला लागणाऱ्या libraries ची यादी असलेला requirements.txt.
  5. gunicorn, production app server. तो WSGI server आहे: Flask आणि Django सारखे Python web apps चालवतो. FastAPI सारख्या async frameworks साठी uvicorn सारखा ASGI server वापरतात.
  6. समोर port 80 वर nginx, जो requests gunicorn ला देतो.

तुम्हाला भेटणारे package managers:

  1. yum (किंवा dnf) Amazon Linux वर Linux packages install करतो: sudo yum install nginx -y.
  2. pip Python libraries install करतो: pip install flask.
  3. npm Node.js libraries install करतो, आणि composer PHP libraries.

बहुतेक Linux systems वर आणि macOS वर Python आधीच install असतो; Windows वर तो स्वतः install करावा लागतो.

3. Server launch करा आणि Python तपासा

का: खालचं सगळं याच server वर चालतं. आधी Python version तपासलं की नवीन Python लागणाऱ्या libraries install करायचं टळतं.

कसं:

  1. EC2 instance launch करा: Amazon Linux 2023, t2.micro किंवा t3.micro, तुमची key pair, 8 GiB gp3 disk, आणि SSH (22) My IP वरून आणि HTTP (80) सगळीकडून allow करणारा security group.
  2. Laptop वरून connect करा:

    ssh -i mykey.pem ec2-user@PUBLIC_IP
    
  3. Python तपासा आणि pip install करा:

    python3 -V
    sudo yum install python3-pip -y
    pip3 -V
    
  4. python3 -V Python 3.9.x सारखं version दाखवतो. नुसतं python लिहिलं तर command not found येतं, कारण command python3 आहे.

Classroom line

First let's check whether Python is there.

Classroom line

Type just python and you get 'command not found'.

4. Virtual environment बनवा

का: एका server वर बऱ्याचदा अनेक Python apps चालतात. App A ला Flask 3.1 आणि app B ला Django 4.2 लागू शकतो, त्याच helper libraries च्या वेगळ्या versions सह. एकत्र install केले तर clash होतो. System Python OS आणि yum पण वापरतात, म्हणून app च्या libraries तिथे नकोत.

काय: venv म्हणजे स्वतःचा python, स्वतःचा pip आणि स्वतःच्या libraries असलेला folder. venv module python3 मध्येच असतो; वेगळं package लागत नाही.

कसं:

mkdir ~/pythonapp
cd ~/pythonapp
python3 -m venv myenv
ls
source myenv/bin/activate
  1. ls आता myenv नावाचा folder दाखवतो.
  2. source नंतर prompt (myenv) ने सुरू होतो. आता python आणि pip म्हणजे myenv मधले.
  3. deactivate venv मधून बाहेर काढतो.
  4. Venv मध्ये कधीच sudo pip किंवा sudo python वापरू नका: sudo root म्हणून root च्या PATH ने चालतो आणि venv टाळतो, म्हणून libraries system Python मध्ये जातात.
  5. pip install ने Permission denied दिलं, तर folder sudo ने बनवला होता. तो परत तुमच्या user ला द्या, मग sudo शिवाय pip install चालवा:
    sudo chown -R ec2-user:ec2-user ~/pythonapp
    

Classroom line

Run ls; you should see a folder called myenv.

Classroom line

When the prompt looks like this, the venv is active.

Virtual environment प्रत्येक appला स्वतःच्या libraries देतो एक EC2 server System Python /usr/bin/python3 OS आणि yum वापरतात.App च्या librariesइथे install करू नका. App A ~/pythonapp/myenv python, pip, Flask 3.1,gunicorn App B ~/shopapp/myenv python, pip, Django 4.2,स्वतःची versions Clash नाही: प्रत्येक venv एक folder. python3 -m venv myenv # create (builtinto python3)source myenv/bin/activate # promptstarts with (myenv)pip install -r requirements.txt # nosudo inside a venv

Figure 3. प्रत्येक app ला स्वतःचा python, pip आणि libraries असलेला venv folder मिळतो, म्हणून एका app मधला Flask आणि दुसऱ्यातला Django कधी clash होत नाहीत, आणि system Python स्वच्छ राहतो.

5. requirements.txt आणि app.py लिहा

का: requirements.txt मुळे कोणीही app ला लागणाऱ्या नेमक्या libraries एका command ने install करू शकतो. app.py म्हणजे app स्वतः.

कसं: ~/pythonapp मध्ये, venv active ठेवून:

  1. nano requirements.txt आणि दोन ओळी लिहा:

    Flask
    gunicorn
    
  2. nano app.py आणि लिहा:

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def home():
        return 'Hello from Python on EC2'
    
    @app.route('/hi')
    def hi():
        return 'Hi! This is the second page.'
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000)
    

प्रत्येक भाग काय करतो:

  1. app = Flask(__name__) Flask app object बनवतो, नाव app.
  2. @app.route('/') URL path त्याखालच्या function ला जोडतो. / म्हणजे page चं नाव नसलेला नुसता address; /hi म्हणजे http://ADDRESS/hi.
  3. Python code group करायला indentation वापरतो. return च्या ओळी spaces ने एकसारख्या indent हव्यात; एक जास्त space दिली की IndentationError येतो.
  4. host='0.0.0.0' server च्या कुठल्याही address वर आलेल्या requests घेतो; port=5000 म्हणजे test server ज्या port वर ऐकतो तो.

Classroom line

Python cares about spaces; one extra space and it won't run.

Classroom line

Just "/" means only the IP, no page name.

6. Libraries install करा आणि Flask server ने test करा

का: आधी Flask च्या स्वतःच्या server ने app चालवलं की code आणि libraries चालतात हे सिद्ध होतं, gunicorn आणि nginx मुळे चूक व्हायच्या आणखी जागा वाढण्याआधी.

कसं:

  1. काहीही install करण्याआधी app चालवून बघा:

    python3 app.py
    

    तो ModuleNotFoundError: No module named 'flask' देऊन fail होतो. Venv active नसेल तेव्हाही हाच error येतो.

  2. Libraries venv मध्ये install करा, आणि नेमक्या versions नोंदवा:

    pip install -r requirements.txt
    pip freeze > requirements.txt
    

    pip freeze Flask==3.1.x सारख्या ओळी लिहितो, म्हणून पुढच्या server ला त्याच versions मिळतात.

  3. Test server सुरू करा:

    python3 app.py
    

    तो Running on http://127.0.0.1:5000 आणि एक warning दाखवतो: "This is a development server. Do not use it in a production deployment." Flask server फक्त testing साठी आहे.

  4. EC2 console मध्ये security group ला तात्पुरता inbound rule टाका: Custom TCP, port 5000, source 0.0.0.0/0.

  5. Browser मध्ये http://PUBLIC_IP:5000 आणि http://PUBLIC_IP:5000/hi उघडा. नुसता http://PUBLIC_IP अजून चालत नाही, कारण port 80 कोणी serve करत नाही.
  6. Terminal आता busy आहे: server foreground मध्ये चालतोय. Ctrl+C दाबलं की तो थांबतो, आणि site पण बंद पडते. SSH window बंद केली तरी तो थांबतो.

Classroom line

It accepts requests on port 5000 from any IP in the world.

Classroom line

Foreground means I can't do anything else in this terminal.

Classroom line

Press Ctrl+C and the server stops.

App चालवायचे तीन मार्ग python3 app.py Flask development server. Foreground: terminal busy राहतो. Ctrl+Cकिंवा SSH बंद केलं की थांबतो. फक्त testing साठी. gunicorn --daemon Production WSGI server. Background: terminal मोकळा. Logout नंतरचालतो, reboot नंतर नाही. Stop, restart हाताने करायचं. systemd service OS चालवतो तो gunicorn. Boot ला start, crash नंतर restart. sudo service gunicorn restart Live app साठी योग्य मार्ग.

Figure 4. App चालवायचे तीन मार्ग: testing साठी foreground मधला Flask development server, background मधला --daemon सह gunicorn, आणि boot ला start होणारी systemd service म्हणून gunicorn, live app साठी योग्य मार्ग.

7. gunicorn ने app background मध्ये चालवा

का: Live app logout नंतरही चालू राहायला हवा, आणि एकदम अनेक requests सांभाळायला हवा. gunicorn दोन्ही करतो.

कसं: Venv active ठेवून, ~/pythonapp मध्ये:

gunicorn --bind 0.0.0.0:5000 --workers 2 --daemon app:app
curl http://127.0.0.1:5000
curl http://127.0.0.1:5000/hi
  1. app:app म्हणजे "app.py file, त्यातला app नावाचा Flask object".
  2. --bind address आणि port ठरवतो. तो नसेल तर gunicorn त्याच्या default 127.0.0.1:8000 वर ऐकतो.
  3. --workers 2 एका master process खाली दोन worker processes सुरू करतो.
  4. --daemon तो background मध्ये चालवतो: prompt परत येतो, आणि logout नंतरही app चालू राहतो.
  5. curl browser शिवाय server वरूनच app test करतो.
  6. SSH तुटलं, तर नवीन session मध्ये venv active नसतो. कुठल्याही python, pip किंवा gunicorn command आधी परत cd ~/pythonapp आणि source myenv/bin/activate चालवा.

Classroom line

--daemon means run in the background.

Classroom line

Re-activating is a must after SSH reconnects.

8. समोर nginx reverse proxy म्हणून ठेवा

का: Visitors नी port 5000 नाही, port 80 वर (आणि नंतर HTTPS साठी 443 वर) नुसता http://ADDRESS वापरायला हवा. nginx internet समोर उभं राहायलाच बनलाय: तो हजारो connections सांभाळतो, static files देतो, आणि नंतर HTTPS पण सांभाळतो.

काय:

  1. nginx reverse proxy आहे: front desk सारखा, तो प्रत्येक request घेतो आणि app च्या requests proxy_pass ने gunicorn ला, म्हणजे back office ला, देतो. Visitor फक्त nginx शीच बोलतो.
  2. nginx काही worker processes चालवतो; worker_processes auto प्रत्येक CPU ला एक सुरू करतो. प्रत्येक worker एक event loop चालवतो जो एकदम अनेक connections सांभाळतो, worker_connections पर्यंत, जे Amazon Linux च्या nginx.conf मध्ये 1024 आहे.
nginx म्हणजे front desk; gunicorn म्हणजेback office Visitors शेकडोbrowsers आणिapps एकदम nginx, reverse proxy (port 80/443) प्रत्येक request आधी हाच घेतो.Static files स्वतः देतो; app च्याrequests gunicorn ला देतो (proxy_pass). worker event loop 1024 conn. worker event loop 1024 conn. worker event loop 1024 conn. gunicorn (app server) 127.0.0.1:5000 त्याचे workers तुमचंFlask code चालवतात आणिउत्तर nginx ला देतात. worker_processes auto: प्रत्येक CPU ला एक nginx worker.प्रत्येक worker चा event loop अनेक connections एकदम सांभाळतो;Amazon Linux च्या nginx.conf मध्ये प्रत्येक worker लाworker_connections 1024.

Figure 5. nginx म्हणजे front desk: तो port 80 किंवा 443 वर प्रत्येक request घेतो, static files स्वतः देतो आणि app च्या requests 127.0.0.1:5000 वरच्या gunicorn ला देतो. प्रत्येक nginx worker चा event loop worker_connections इतके connections सांभाळतो, Amazon Linux च्या nginx.conf मध्ये 1024.

कसं:

  1. nginx install करा आणि start करा:

    sudo yum install nginx -y
    sudo service nginx start
    
  2. sudo nano /etc/nginx/nginx.conf ने config उघडा. आधीच्या server { ... } block मध्ये, root च्या ओळीनंतर, हे टाका:

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
  3. प्रत्येक directive ; ने संपतो आणि प्रत्येक { ला त्याचा } हवा. File तपासा, मग reload करा:

    sudo nginx -t
    sudo service nginx reload
    
  4. nginx -t ने syntax is ok आणि test is successful म्हटलं पाहिजे. Error दाखवला तर nginx जुन्या config ने चालू राहतो; त्याने सांगितलेली ओळ दुरुस्त करा आणि परत test करा.

  5. Port शिवाय http://PUBLIC_IP उघडा: Flask app nginx मधून उत्तर देतो.

Classroom line

Don't forget the semicolon here.

काळा terminal, nano मध्ये nginx.conf उघडलेली: server {, listen 80;, listen [::]:80;, server_name _;, root /usr/share/nginx/html;, मग location /{, proxy_pass http://localhost:5000; आणि बंद करणारा brace.

Whiteboard: nginx.conf मधला default server block, आणि requests port 5000 कडे देणारा location / block. localhost ऐवजी 127.0.0.1 लिहिलं की nginx आधी IPv6 address ::1 try करत नाही.

proxy_set_header च्या ओळी खरा visitor address आणि मूळ host name app पर्यंत पोचवतात; त्या नसतील तर प्रत्येक request nginx कडूनच आल्यासारखी वाटते.

Port 5000 बंद करा: आता nginx समोर आहे, बाहेरच्या कोणालाही port 5000 ची गरज नाही.

  1. Test चा gunicorn थांबवा (त्याचा PID कसा शोधायचा ते section 9 दाखवतो) आणि तो फक्त server पुरता bind करून सुरू करा:

    gunicorn --bind 127.0.0.1:5000 --workers 2 --daemon app:app
    
  2. Security group मधून port 5000 चा rule delete करा. 22 My IP वरून, 80, आणि HTTPS टाकलं तर 443 ठेवा.

  3. http://PUBLIC_IP अजून चालतो; http://PUBLIC_IP:5000 आता उत्तर देत नाही.
Security group: testing करताना, आणिnginx समोर आल्यावर Flask server ने testing Inbound rules 22 My IP SSH 80 0.0.0.0/0 HTTP 5000 0.0.0.0/0 तात्पुरता test Live, nginx मागे Inbound rules 22 My IP SSH 80 0.0.0.0/0 HTTP 443 0.0.0.0/0 HTTPS 5000 0.0.0.0/0 rule delete केला gunicorn 0.0.0.0:5000 वर असेल तरport 5000 गाठणाऱ्या कुणालाही उत्तर देतो. gunicorn 127.0.0.1:5000 वर: फक्त nginx पोचतो.

Figure 6. Testing करताना security group मध्ये port 5000 चा तात्पुरता rule असतो; nginx समोर आल्यावर 5000 चा rule delete होतो आणि gunicorn 127.0.0.1:5000 वर bind करतो, म्हणून फक्त nginx तिथे पोचू शकतो.

Request तुमच्या Python app पर्यंत कशीपोचते Browser GET /getusers nginx :80 reverse proxy gunicorn 127.0.0.1:5000 Flask app.py get_users() 80 Private: फक्त 127.0.0.1, port 5000 बंद 1. Browser http://PUBLIC_IP/getusers उघडतो.Security group port 80 आत येऊ देतो. 2. nginx ती घेतो आणि location / { proxy_passhttp://127.0.0.1:5000; } नुसार पुढे देतो. 3. gunicorn चा एक worker /getusers साठीचं Flaskfunction चालवतो. 4. JSON त्याच मार्गाने परत जातो: gunicorn, nginx,browser. nginx internet समोर; gunicorn आणि app 127.0.0.1 वर private राहतात.

Figure 7. Browser port 80 वर nginx पर्यंत पोचतो; nginx request 127.0.0.1:5000 वरच्या gunicorn ला देतो; gunicorn चा worker Flask function चालवतो, आणि JSON त्याच मार्गाने परत जातो.

9. API route टाका आणि gunicorn reload करा

का: API म्हणजे फक्त data परत देणारा route. तो टाकला की background server चं सगळ्यात नेहमीचं आश्चर्य दिसतं: server reload करेपर्यंत नवीन code काहीच करत नाही.

कसं:

  1. app.py मध्ये if __name__ च्या ओळीच्या वर एक route टाका:

    @app.route('/getusers')
    def get_users():
        return {"username": "ravi", "likes": 50, "caption": "on the top"}
    
  2. Flask परत दिलेल्या dictionary चं JSON करतो आणि application/json content type लावतो.

  3. http://PUBLIC_IP/getusers उघडा: 404 Not Found दिसतं. gunicorn ने workers सुरू होताना app.py load केला, आणि तो अजून जुनाच code चालवतोय.
  4. gunicorn चे processes शोधा:

    ps aux | grep gunicorn
    ps -ef | grep gunicorn
    
  5. ps aux सगळे processes दाखवतो: a सगळे users, u user-oriented columns, x terminal नसलेले processes पण. ps -ef parent PID चा column दाखवतो: ज्या gunicorn process चा parent दुसरा gunicorn नाही तो master; workers त्याची मुलं.

  6. Master च्या PID ने code हळूच reload करा:

    kill -HUP 4101
    
  7. HUP मुळे master नवीन code सह नवीन workers सुरू करतो आणि जुने त्यांच्या requests संपल्यावर थांबवतो. /getusers परत उघडा: तो {"caption":"on the top","likes":50,"username":"ravi"} देतो.

  8. gunicorn थांबवायला kill 4101 (TERM) चालवा: तो व्यवस्थित बंद होतो. kill -9 फक्त तो अडकला तरच.

Classroom line

Suppose you need a new API; what will you do?

Classroom line

How to find it? Run ps aux.

पांढरं browser page, त्यावर JSON ची एक ओळ: {"username":"ravi","likes":50,"caption":"on the top"}.

Whiteboard: /getusers route JSON ने उत्तर देतोय. या app ने तयार JSON string परत दिली होती; dictionary परत दिली तर तिच्या keys sorted येतात, step 7 सारख्या.

नवीन code ला gunicorn reload लागतो 1. app.py मध्ये /getusers टाकला, पण चालू gunicorn कडेजुनाच code आहे curl -s -o /dev/null -w "%{http_code}\n"http://127.0.0.1:5000/getusers 404 Workers start होताना Python app.py एकदाच load करतो. File save करूनअजून काही बदलत नाही. 2. Master process शोधा आणि त्याला HUP पाठवा ps -ef | grep [g]unicorn ec2-user 4101 1 ... gunicorn --bind 127.0.0.1:5000--daemon app:app ec2-user 4102 4101 ... gunicorn --bind 127.0.0.1:5000--daemon app:app kill -HUP 4101 Master म्हणजे ज्याचा parent (तिसरा column) दुसरा gunicorn नाही.HUP नवीन workers नवीन code सह सुरू करतो आणि जुने हळूच थांबवतो.kill 4101 थांबवतो; kill -9 फक्त अडकल्यावर. 3. नवीन route उत्तर देतो curl http://127.0.0.1:5000/getusers {"caption":"on the top","likes":50,"username":"ravi"} systemd असेल तर: sudo service gunicorn reload हाच HUP तुमच्यासाठीकरतो.

Figure 8. नवीन route 404 देतो कारण चालू workers कडे जुना code आहे; ps ने master PID शोधा, त्याला HUP पाठवा, आणि नवीन workers JSON ने उत्तर देतात.

10. gunicorn systemd service म्हणून चालवा

का: --daemon वाला gunicorn reboot किंवा crash नंतर परत सुरू होत नाही, आणि तो सांभाळायला PIDs शोधावे लागतात. systemd service तिन्ही सोडवते. Live app चालवायचा हा योग्य मार्ग आहे.

कसं:

  1. --daemon वाला gunicorn kill <master PID> ने थांबवा.
  2. sudo nano /etc/systemd/system/gunicorn.service ने unit file बनवा:

    [Unit]
    Description=Gunicorn for pythonapp
    After=network.target
    
    [Service]
    User=ec2-user
    Group=ec2-user
    WorkingDirectory=/home/ec2-user/pythonapp
    ExecStart=/home/ec2-user/pythonapp/myenv/bin/gunicorn --workers 2 --bind 127.0.0.1:5000 app:app
    ExecReload=/bin/kill -s HUP $MAINPID
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    
  3. ExecStart venv मधल्या gunicorn चा पूर्ण path वापरतो, म्हणून activate लागत नाही. --daemon नाही: systemd स्वतः तो background मध्ये ठेवतो.

  4. Load करा, boot साठी enable करा, आणि start करा:

    sudo systemctl daemon-reload
    sudo systemctl enable gunicorn
    sudo service gunicorn start
    sudo service gunicorn status
    
  5. Code बदलल्यावर: sudo service gunicorn reload (section 9 सारखाच HUP). Unit file बदलल्यावर: sudo systemctl daemon-reload, मग sudo service gunicorn restart.

  6. त्याचे logs sudo journalctl -u gunicorn ने वाचा.

11. एका nginx वर अनेक sites

का: एक EC2 server अनेक apps आणि sites host करू शकतो. वेगवेगळे server { } blocks त्यांना वेगळं ठेवतात, म्हणून प्रत्येक site साठी वेगळ्या server चे पैसे भरावे लागत नाहीत.

काय: एक nginx अनेक sites serve करू शकतो, प्रत्येक स्वतःच्या server { } block मध्ये.

  1. /etc/nginx/nginx.conf मधल्या पहिल्या block मध्ये server_name _; असतो. _ म्हणजे catch-all नाव: ज्या requests चं host name दुसऱ्या कुठल्याही block शी जुळत नाही, उदा. नुसता IP, त्यांना हा default block उत्तर देतो.
  2. प्रत्येक site साठी एक block टाका, प्रत्येकाचा स्वतःचा server_name आणि स्वतःचा proxy_pass किंवा root:

    server {
        listen 80;
        server_name api.example.com;
        location / {
            proxy_pass http://127.0.0.1:5000;
        }
    }
    
  3. दुसरा Python app दुसऱ्या port वर चालतो, उदा. 127.0.0.1:5001, स्वतःच्या venv आणि service सह.

  4. प्रत्येक बदलानंतर sudo nginx -t आणि sudo service nginx reload चालवा.

12. काही चुकलं तर

  1. python: command not found: python3 वापरा.
  2. ModuleNotFoundError: No module named 'flask': venv activate करा, मग pip install -r requirements.txt.
  3. pip install करताना Permission denied: folder sudo ने बनवला; sudo chown -R ec2-user:ec2-user ~/pythonapp चालवा, मग sudo शिवाय pip install.
  4. SSH परत जोडल्यावर commands fail: परत cd ~/pythonapp आणि source myenv/bin/activate.
  5. Testing करताना http://PUBLIC_IP:5000 उघडत नाही: host='0.0.0.0' आणि security group मधला port 5000 चा rule तपासा.
  6. तुमच्या app ऐवजी nginx welcome page: location / { proxy_pass ...; } block नाही किंवा server block च्या बाहेर आहे, किंवा nginx reload केला नाही.
  7. 502 Bad Gateway: nginx चालतोय पण gunicorn उत्तर देत नाही. gunicorn सुरू करा, किंवा proxy_pass मधला port दुरुस्त करा.
  8. nginx -t म्हणतो unexpected end of file, expecting "}": बंद करणारा } नाही. तो टाका, sudo nginx -t चालवा, मग reload.
  9. nginx -t म्हणतो invalid number of arguments: त्याने सांगितलेल्या ओळीच्या शेवटी ; नाही.
  10. नवीन route 404 देतो: जुनाच code load आहे. kill -HUP <master PID> किंवा sudo service gunicorn reload चालवा.
EC2 वर Python app: काय दिसतं, काय तपासायचं python: command not found → Amazon Linux 2023 वर python3 आहे: python3 -V, python3 -m venv ModuleNotFoundError: No module named 'flask' → Venv activate करा, मग pip install -r requirements.txt pip install करताना Permission denied → sudo ने बनवलेला folder: sudo chown -R ec2-user:ec2-user~/pythonapp SSH परत जोडल्यावर commands fail → cd ~/pythonapp, मग परत source myenv/bin/activate http://IP:5000 उघडत नाही → फक्त testing: 0.0.0.0 वर bind? Security group मध्ये port 5000? App ऐवजी "Welcome to nginx" → location / { proxy_pass ...; } नाही, किंवा nginx reload केला नाही 502 Bad Gateway → gunicorn चालू नाही, किंवा proxy_pass मध्ये चुकीचा port nginx -t: unexpected end of file, expecting "}" → शेवटचा } नाही: टाका, nginx -t, reload nginx -t: invalid number of arguments → त्या ओळीच्या शेवटी ; नाही नवीन route ला 404 → Old code still loaded: kill -HUP &lt;master PID&gt; or service reload Logs: sudo tail /var/log/nginx/error.log, आणि service साठी sudo journalctl-u gunicorn

Figure 9. EC2 वर Python app: काय दिसतं आणि काय तपासायचं, python3 आणि venv पासून security group, proxy_pass, 502, nginx -t messages आणि gunicorn reload पर्यंत. Logs /var/log/nginx/error.log मध्ये आणि journalctl -u gunicorn मध्ये असतात.

Ravindra Bagale's Tip

तीन सवयी ठेवा. Venv मध्ये काम करा आणि pip आधी कधीच sudo लिहू नका. प्रत्येक nginx reload आधी sudo nginx -t चालवा, म्हणजे typo मुळे site कधी बंद पडत नाही. आणि nginx समोर आला की gunicorn 127.0.0.1 वर bind करा आणि port 5000 चा rule delete करा: internet ला जितके कमी ports उघडे, तितके आत यायचे मार्ग कमी.

Practice झाल्यावर EC2 instance stop करा.

13. पूर्ण class एका page वर

  1. Website पूर्ण HTML pages देते; API data JSON मध्ये देतो, { } मधल्या key: value जोड्या, आणि प्रत्येक app स्वतःची screen काढतो.
  2. Python hosting ला python3, pip, venv, app, gunicorn (WSGI) आणि nginx लागतात. yum, pip, npm आणि composer हे package managers.
  3. Amazon Linux 2023 वर: python3 -V, sudo yum install python3-pip -y. Command python3 आहे, python नाही.
  4. python3 -m venv myenv, source myenv/bin/activate, prompt (myenv). कधीच sudo pip नाही; Permission denied chown ने सोडवा.
  5. requirements.txt मध्ये libraries ची यादी; pip install -r requirements.txt; pip freeze versions pin करतो.
  6. Flask: @app.route('/'), indentation महत्त्वाचं, app.run(host='0.0.0.0', port=5000). Flask server फक्त testing साठी.
  7. gunicorn --bind 127.0.0.1:5000 --workers 2 --daemon app:app; --bind नसेल तर 127.0.0.1:8000. SSH परत जोडल्यावर venv परत activate करा.
  8. nginx reverse proxy: location / { proxy_pass http://127.0.0.1:5000; }, मग sudo nginx -t आणि sudo service nginx reload. Event loops असलेले workers, worker_connections 1024.
  9. nginx मागे असताना security group मध्ये port 5000 बंद करा.
  10. नवीन code ला reload लागतो: ps aux | grep gunicorn, kill -HUP <master PID>; kill थांबवतो, kill -9 फक्त अडकल्यावर.
  11. योग्य मार्ग: venv मधल्या gunicorn सह systemd unit, systemctl enable, sudo service gunicorn start|reload|restart, journalctl -u gunicorn.
  12. server_name _; हा catch-all default block; प्रत्येक site साठी एक server { } block टाका.

14. Hands-on lab: gunicorn आणि nginx मागे Flask app

हा lab का. हा lab stack खालून वर बनवतो आणि पुढचा layer जोडण्याआधी प्रत्येक layer curl ने तपासतो: Python, virtual environment, Flask, gunicorn, मग समोर nginx.

  1. Python तपासा आणि pip install करा
    • Command: python3 -V && sudo yum install python3-pip -y
    • काय दिसेल: Python 3.x, मग Complete!.
    • Check करा: pip3 -V version print करतो.
    • का: Amazon Linux मध्ये python3 असतो पण pip नसतो. या server वर command python3, python नाही.
  2. App folder आणि virtual environment बनवा
    • Command: mkdir ~/pythonapp && cd ~/pythonapp && python3 -m venv myenv && source myenv/bin/activate
    • काय दिसेल: Prompt (myenv) ने सुरू होतो.
    • Check करा: which python → /home/ec2-user/pythonapp/myenv/bin/python
    • का: प्रत्येक app ला स्वतःच्या libraries मिळतात, म्हणून वेगवेगळे Flask versions लागणारे दोन apps भांडत नाहीत.
  3. requirements.txt आणि app.py लिहा
    • करा: nano requirements.txt मध्ये Flask आणि gunicorn या दोन ओळी; nano app.py मध्ये section 5 मधलं दोन routes चं app.
    • Check करा: ls → app.py myenv requirements.txt
    • का: requirements.txt मुळे कोणीही हीच libraries एका command ने install करू शकतो.
  4. Libraries install करा
    • Command: pip install -r requirements.txt
    • काय दिसेल: Successfully installed ... flask ... gunicorn ... ने संपणाऱ्या download ओळी.
    • Check करा: pip list मध्ये Flask आणि gunicorn दिसतात.
    • का: (myenv) च्या आत त्या फक्त या app मध्ये install होतात, आणि sudo लागत नाही.
  5. gunicorn ने background मध्ये चालवा
    • Command: gunicorn --bind 127.0.0.1:5000 --workers 2 --daemon app:app
    • काय दिसेल: काहीच नाही.
    • Check करा: curl http://127.0.0.1:5000 → Hello from Python on EC2; curl http://127.0.0.1:5000/hi → Hi! This is the second page.
    • का: app:app म्हणजे app.py मधलं app object. 127.0.0.1 port 5000 private ठेवतो, म्हणून फक्त त्याच server वरचा nginx पोहोचू शकतो; --daemon logout नंतरही चालू ठेवतो.
  6. reverse proxy म्हणून nginx install करा
    • Command: sudo yum install nginx -y
    • काय दिसेल: Complete!
    • Check करा: nginx -v version print करतो.
    • का: Visitors port 80 वापरतात. nginx तिथे त्यांच्या requests घेतो आणि 5000 वरच्या gunicorn कडे देतो.
  7. Proxy settings जोडा
    • करा: /etc/nginx/nginx.conf च्या server { } block मध्ये section 8 मधला location / { proxy_pass http://127.0.0.1:5000; ... } block जोडा.
    • Check करा: sudo nginx -t → syntax is ok आणि test is successful.
    • का: proxy_pass ही प्रत्येक request पुढे पाठवणारी ओळ. Start आधी test केल्याने राहिलेला semicolon पकडला जातो.
  8. nginx start करा आणि app उघडा
    • Command: sudo service nginx start && curl http://localhost
    • काय दिसेल: Hello from Python on EC2
    • Check करा: Security group मध्ये HTTP allowed असेल तर browser मध्ये http://PUBLIC_IP/hi दुसरं page दाखवतो.
    • का: Port 80 वर तेच उत्तर आलं म्हणजे nginx gunicorn कडे पाठवतो. Port 5000 internet साठी कधीच उघडावा लागत नाही.
  9. Reboot नंतरही चालू राहील असं करा
    • करा: Section 10 मधला gunicorn systemd service बनवा, मग sudo systemctl daemon-reload आणि sudo systemctl enable gunicorn चालवा.
    • Check करा: Instance stop आणि start केल्यावरही curl http://localhost उत्तर देतो (sudo systemctl enable nginx पण).
    • का: --daemon gunicorn reboot किंवा crash नंतर परत येत नाही; systemd तो परत start करतो. आधी --daemon वाली copy थांबवा, म्हणजे दोघं port 5000 साठी भांडणार नाहीत.

15. Try at home

Try at home

Task 1: app

  1. Amazon Linux 2023 instance launch करा, pip install करा, venv सह ~/pythonapp बनवा, आणि requirements.txt आणि app.py लिहा.
  2. एकदा venv active नसताना python3 app.py चालवा आणि error वाचा. मग तो activate करा, install करा, आणि port 5000 तात्पुरता उघडा.

Task 2: gunicorn आणि nginx

  1. gunicorn ने app background मध्ये चालवा आणि curl ने test करा.
  2. nginx install करा, location block टाका, sudo nginx -t चालवा, reload करा, आणि site port 80 वर उघडा.
  3. एक ; काढा, sudo nginx -t चालवा, आणि message वाचा. परत टाका.
  4. gunicorn 127.0.0.1:5000 वर bind करा आणि port 5000 चा rule delete करा.

Task 3: API आणि service

  1. /getusers टाका, 404 बघा, मग kill -HUP ने gunicorn reload करा आणि JSON बघा.
  2. gunicorn थांबवा आणि 502 Bad Gateway page बघा.
  3. systemd unit बनवा, enable करा, instance reboot करा, आणि तुम्ही काहीही start न करता app उत्तर देतो का ते तपासा.

Recap

थोडक्यात

  1. API पूर्ण pages ऐवजी data JSON मध्ये पाठवतो, म्हणून प्रत्येक app स्वतःची screen काढू शकतो.
  2. Venv प्रत्येक app च्या libraries वेगळ्या ठेवतो; तो python3 -m venv ने बनवा, आणि त्यात कधीच sudo pip वापरू नका.
  3. Flask server testing साठी; gunicorn app खरा चालवतो, आणि app:app file आणि object चं नाव सांगतो.
  4. समोरचा nginx reverse proxy; gunicorn 127.0.0.1:5000 वर bind करतो, आणि port 5000 बंद राहतो.
  5. प्रत्येक reload आधी sudo nginx -t राहिलेले ; आणि } पकडतो.
  6. नवीन code ला master वर kill -HUP किंवा sudo service gunicorn reload लागतो; systemd service gunicorn boot ला सुरू करते आणि crash नंतर परत सुरू करते.

सराव Tasks

या scenario बद्दल

Cape Town Safaris हा केप टाऊन मधला पर्यटन व्यवसाय आहे. Thabo Nkosi त्यांचं IT व cloud काम पाहतात. त्यांचे पैसे ZAR मध्ये मोजले जातात आणि AWS resources af-south-1 Region मध्ये चालतात. खालच्या tasks मध्ये तुम्ही या lesson मध्ये शिकलेलं वापरून त्यांची खरी कामं करता. सगळी नावं, account IDs, IP addresses व numbers सरावासाठी काल्पनिक आहेत.

0 / 12

सोपं बदलानंतर service restart करा

का: Config बदल service restart/reload नंतरच लागू होतात.

काय करायचं: nginx service restart करा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

सोपं Service चालू आहे का ते पाहा

का: Site बंद असेल तर आधी web server चालू आहे का ते पाहा.

काय करायचं: httpd service चं status दाखवा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

सोपं Ubuntu वर package install करा

का: Ubuntu apt वापरतं. Package नावं वेगळी: Ubuntu वर Apache म्हणजे apache2.

काय करायचं: Ubuntu वर apache2 package confirm न विचारता install करा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

सोपं Amazon Linux वर package install करा

का: Amazon Linux 2023 वर dnf हा package manager. -y आपोआप yes देतो.

काय करायचं: Amazon Linux 2023 वर httpd package confirm न विचारता install करा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

सोपं Server वरून website test करा

का: DNS तयार होण्याआधीही web server उत्तर देतो का ते curl दाखवतो.

काय करायचं: http://localhost ला request पाठवा व फक्त response headers दाखवा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

सोपं GitHub वरून code घ्या

का: git clone पूर्ण repository server वर copy करतो.

काय करायचं: https://github.com/capetownsafari/website.git सध्याच्या folder मध्ये clone करा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

मध्यम nginx config test करा

का: Restart मुळे site बंद पडण्याआधी test चुका पकडतो.

काय करायचं: nginx configuration files मधल्या चुका तपासा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

मध्यम Service आत्ता व boot ला सुरू करा

का: enable reboot नंतर सुरू करतो; --now आत्ताच सुरू करतो.

काय करायचं: nginx service enable करा व लगेच सुरू करा, एका command ने.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

मध्यम Port 80 सगळ्यांसाठी उघडा

का: Security group HTTP allow करत असेल तरच visitors website पाहू शकतात.

काय करायचं: Security group sg-022b36ab6b244c3b2 वर 0.0.0.0/0 कडून inbound TCP port 80 allow करा.

कसं करायचं:
  1. Task वाचा आणि ते कोणत्या AWS service बद्दल आहे ते ठरवा.
  2. aws लिहा, मग service चं नाव, मग operation (action शब्द).
  3. प्रत्येक आवश्यक flag (--name) व त्यापुढे task मधली value लिहा.
  4. Flags कोणत्याही क्रमाने चालतात. Check answer दाबा.

मध्यम CloudFormation: web SG

का: फक्त 443 उघडल्याने server सुरक्षित.

काय करायचं: 0.0.0.0/0 कडून TCP 443 allow करणारा AWS::EC2::SecurityGroup. GroupDescription द्या.

कसं करायचं:
  1. Task मधल्या top-level keys पासून सुरू करा.
  2. Child keys 2 spaces ने indent करा (tabs नकोत).
  3. प्रत्येक property मध्ये task मधली value भरा.
  4. Check answer दाबा. Keys चा क्रम महत्त्वाचा नाही.

मध्यम Security group बनवा

का: Security group म्हणजे instance भोवतीचा firewall.

काय करायचं: vpc-0f3cafcf24deadbee मध्ये capetownsafari-web-sg नावाचा security group "Web servers" description सह बनवा.

कसं करायचं:
  1. Task वाचा आणि ते कोणत्या AWS service बद्दल आहे ते ठरवा.
  2. aws लिहा, मग service चं नाव, मग operation (action शब्द).
  3. प्रत्येक आवश्यक flag (--name) व त्यापुढे task मधली value लिहा.
  4. Flags कोणत्याही क्रमाने चालतात. Check answer दाबा.

अवघड Ubuntu वर nginx site enable करा

का: Ubuntu वर sites-available पासून sites-enabled ला symbolic link ने site enable होते.

काय करायचं: /etc/nginx/sites-enabled/ मध्ये /etc/nginx/sites-available/capetownsafari ची symbolic link बनवा.

कसं करायचं:
  1. हे काम करणारा Linux command शोधा.
  2. Task ला लागणारे options (उदा. -r, -h) जोडा.
  3. File नावं, folders किंवा users योग्य क्रमाने लिहा.
  4. System files/users बदलत असाल तर sudo वापरा. Check answer दाबा.

उजळणी, तुलना आणि मुलाखत cards

हा lesson काही मिनिटांत revise करा. Cards phone वर save करा किंवा PNG download करा. प्रत्येक card वरचा QR हा lesson उघडतो.

उजळणी card: Python virtual environment. sudo pip ने libraries install केल्यास system Python मध्ये मिसळतात आणि yum तुटू शकतो. Virtual environment (venv) म्हणजे एका app साठी Python libraries चा private folder. बनवा, activate करा, मग requirements.txt मधून pip install. Setup:
उजळणी card: Python virtual environment · PNG download करा
उजळणी card: gunicorn ने Flask चालवा. Flask development server slow, एकाच user साठी, आणि SSH बंद झाला की थांबतो. gunicorn हा Python apps साठी production server. app:app म्हणजे file app.py, object app. 127.0.0.1 ला bind करा म्हणजे फक्त Nginx पोचेल, आणि background मध्ये चालवा. Command:
उजळणी card: gunicorn ने Flask चालवा · PNG download करा
उजळणी card: Flask साठी Nginx reverse proxy. gunicorn internet ला उघडा नसावा, आणि users ना port 80 हवा. Reverse proxy 80 वर requests घेतो आणि 5000 वरच्या app ला देतो. proxy_pass add करा, nginx -t, reload, मग port 5000 चा SG rule काढा. Location:
उजळणी card: Flask साठी Nginx reverse proxy · PNG download करा
उजळणी card: gunicorn साठी systemd service. Reboot नंतर हाताने सुरू केलेला gunicorn जातो आणि site 502 दाखवते. systemd service म्हणजे program कसा start, stop, restart करायचा हे Linux ला सांगणारी छोटी file. /etc/systemd/system/flask.service बनवा, मग enable --now. Commands:
उजळणी card: gunicorn साठी systemd service · PNG download करा
तुलना: Website vs API. Website: Browser मध्ये लोकांनी वाचायची pages. API: इतर programs नी वापरायचा data.
तुलना: Website vs API · PNG download करा
तुलना: Flask dev server vs gunicorn. Flask dev server: flask run ने सुरू होणारा built-in server. gunicorn: अनेक workers सोबत Flask चालवणारा production WSGI server.
तुलना: Flask dev server vs gunicorn · PNG download करा
मुलाखत card: sudo pip install ही चूक का?. तो yum आणि AWS tools अवलंबून असलेल्या system Python मध्ये लिहितो. चुकीचं version system commands तोडू शकतं. त्याऐवजी venv:
मुलाखत card: sudo pip install ही चूक का? · PNG download करा
मुलाखत card: gunicorn मध्ये app:app म्हणजे काय?. Module app (file app.py) : object app (Flask instance). कोणती file आणि कोणता object चालवायचा हे gunicorn ला कळायला हवं. main.py मध्ये server = Flask(__name__) › main:server.
मुलाखत card: gunicorn मध्ये app:app म्हणजे काय? · PNG download करा
मुलाखत card: gunicorn 127.0.0.1 ला का bind करायचा?. म्हणजे फक्त त्याच server वरचे programs, उदा. Nginx, पोचू शकतात. 0.0.0.0 app port internet ला उघडा करेल. Bind करा आणि SG मध्ये port 5000 बंद करा.
मुलाखत card: gunicorn 127.0.0.1 ला का bind करायचा? · PNG download करा
मुलाखत card: Code बदलल्यानंतर gunicorn reload कसा करता?. Master process ला HUP पाठवा, किंवा systemd service restart करा. Port न सोडता workers नवीन code सोबत restart होतात. Commands:
मुलाखत card: Code बदलल्यानंतर gunicorn reload कसा करता? · PNG download करा

अजून cards: Ravi Sir's Cards.