[{"data":1,"prerenderedAt":2072},["ShallowReactive",2],{"\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide":3},{"id":4,"title":5,"body":6,"description":2062,"extension":2063,"meta":2064,"navigation":169,"path":2068,"seo":2069,"stem":2070,"__hash__":2071},"content\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide.md","Deploy Flask with Nginx + Gunicorn (Step-by-Step Guide)",{"type":7,"value":8,"toc":2051},"minimark",[9,13,17,22,25,508,511,515,531,535,1365,1369,1466,1470,1473,1494,1497,1522,1525,1543,1546,1559,1562,1579,1582,1601,1604,1622,1625,1649,1652,1664,1667,1679,1682,1698,1701,1720,1723,1738,1741,1760,1763,1796,1799,1834,1838,1923,1927,1954,1958,1969,1984,1992,2000,2008,2024,2040,2044,2047],[10,11,5],"h1",{"id":12},"deploy-flask-with-nginx-gunicorn-step-by-step-guide",[14,15,16],"p",{},"If you're trying to deploy a Flask app with Nginx and Gunicorn in production, this guide shows you the minimal working setup and the exact steps to get it running. The outcome is a Flask application served by Gunicorn, managed by systemd, and exposed safely through Nginx.",[18,19,21],"h2",{"id":20},"quick-fix-quick-setup","Quick Fix \u002F Quick Setup",[14,23,24],{},"Use this baseline to get a single-server Flask deployment running quickly:",[26,27,32],"pre",{"className":28,"code":29,"language":30,"meta":31,"style":31},"language-bash shiki shiki-themes github-light github-dark","sudo apt update && sudo apt install -y python3-venv python3-pip nginx\nmkdir -p \u002Fvar\u002Fwww\u002Fflaskapp && cd \u002Fvar\u002Fwww\u002Fflaskapp\npython3 -m venv .venv\n. .venv\u002Fbin\u002Factivate\npip install flask gunicorn\ncat > app.py \u003C\u003C'EOF'\nfrom flask import Flask\napp = Flask(__name__)\n\n@app.route('\u002F')\ndef hello():\n    return 'Flask + Gunicorn + Nginx is working'\nEOF\ncat > wsgi.py \u003C\u003C'EOF'\nfrom app import app\nEOF\nsudo tee \u002Fetc\u002Fsystemd\u002Fsystem\u002Fflaskapp.service > \u002Fdev\u002Fnull \u003C\u003C'EOF'\n[Unit]\nDescription=Gunicorn for Flask app\nAfter=network.target\n\n[Service]\nUser=www-data\nGroup=www-data\nWorkingDirectory=\u002Fvar\u002Fwww\u002Fflaskapp\nEnvironment=\"PATH=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\"\nExecStart=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\u002Fgunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable --now flaskapp\nsudo tee \u002Fetc\u002Fnginx\u002Fsites-available\u002Fflaskapp > \u002Fdev\u002Fnull \u003C\u003C'EOF'\nserver {\n    listen 80;\n    server_name _;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8000;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\nEOF\nsudo ln -sf \u002Fetc\u002Fnginx\u002Fsites-available\u002Fflaskapp \u002Fetc\u002Fnginx\u002Fsites-enabled\u002Fflaskapp\nsudo nginx -t && sudo systemctl reload nginx\ncurl -I http:\u002F\u002F127.0.0.1:8000\ncurl -I http:\u002F\u002Flocalhost\n","bash","",[33,34,35,75,95,110,119,133,152,158,164,171,177,183,189,195,209,215,220,240,246,252,258,263,269,275,281,287,293,299,305,310,316,322,327,338,354,372,378,384,390,395,401,407,413,419,425,431,437,443,448,464,486,498],"code",{"__ignoreMap":31},[36,37,40,44,48,51,55,57,59,62,66,69,72],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"sScJk","sudo",[36,45,47],{"class":46},"sZZnC"," apt",[36,49,50],{"class":46}," update",[36,52,54],{"class":53},"sVt8B"," && ",[36,56,43],{"class":42},[36,58,47],{"class":46},[36,60,61],{"class":46}," install",[36,63,65],{"class":64},"sj4cs"," -y",[36,67,68],{"class":46}," python3-venv",[36,70,71],{"class":46}," python3-pip",[36,73,74],{"class":46}," nginx\n",[36,76,78,81,84,87,89,92],{"class":38,"line":77},2,[36,79,80],{"class":42},"mkdir",[36,82,83],{"class":64}," -p",[36,85,86],{"class":46}," \u002Fvar\u002Fwww\u002Fflaskapp",[36,88,54],{"class":53},[36,90,91],{"class":64},"cd",[36,93,94],{"class":46}," \u002Fvar\u002Fwww\u002Fflaskapp\n",[36,96,98,101,104,107],{"class":38,"line":97},3,[36,99,100],{"class":42},"python3",[36,102,103],{"class":64}," -m",[36,105,106],{"class":46}," venv",[36,108,109],{"class":46}," .venv\n",[36,111,113,116],{"class":38,"line":112},4,[36,114,115],{"class":64},".",[36,117,118],{"class":46}," .venv\u002Fbin\u002Factivate\n",[36,120,122,125,127,130],{"class":38,"line":121},5,[36,123,124],{"class":42},"pip",[36,126,61],{"class":46},[36,128,129],{"class":46}," flask",[36,131,132],{"class":46}," gunicorn\n",[36,134,136,139,143,146,149],{"class":38,"line":135},6,[36,137,138],{"class":42},"cat",[36,140,142],{"class":141},"szBVR"," >",[36,144,145],{"class":46}," app.py",[36,147,148],{"class":141}," \u003C\u003C",[36,150,151],{"class":46},"'EOF'\n",[36,153,155],{"class":38,"line":154},7,[36,156,157],{"class":46},"from flask import Flask\n",[36,159,161],{"class":38,"line":160},8,[36,162,163],{"class":46},"app = Flask(__name__)\n",[36,165,167],{"class":38,"line":166},9,[36,168,170],{"emptyLinePlaceholder":169},true,"\n",[36,172,174],{"class":38,"line":173},10,[36,175,176],{"class":46},"@app.route('\u002F')\n",[36,178,180],{"class":38,"line":179},11,[36,181,182],{"class":46},"def hello():\n",[36,184,186],{"class":38,"line":185},12,[36,187,188],{"class":46},"    return 'Flask + Gunicorn + Nginx is working'\n",[36,190,192],{"class":38,"line":191},13,[36,193,194],{"class":46},"EOF\n",[36,196,198,200,202,205,207],{"class":38,"line":197},14,[36,199,138],{"class":42},[36,201,142],{"class":141},[36,203,204],{"class":46}," wsgi.py",[36,206,148],{"class":141},[36,208,151],{"class":46},[36,210,212],{"class":38,"line":211},15,[36,213,214],{"class":46},"from app import app\n",[36,216,218],{"class":38,"line":217},16,[36,219,194],{"class":46},[36,221,223,225,228,231,233,236,238],{"class":38,"line":222},17,[36,224,43],{"class":42},[36,226,227],{"class":46}," tee",[36,229,230],{"class":46}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fflaskapp.service",[36,232,142],{"class":141},[36,234,235],{"class":46}," \u002Fdev\u002Fnull",[36,237,148],{"class":141},[36,239,151],{"class":46},[36,241,243],{"class":38,"line":242},18,[36,244,245],{"class":46},"[Unit]\n",[36,247,249],{"class":38,"line":248},19,[36,250,251],{"class":46},"Description=Gunicorn for Flask app\n",[36,253,255],{"class":38,"line":254},20,[36,256,257],{"class":46},"After=network.target\n",[36,259,261],{"class":38,"line":260},21,[36,262,170],{"emptyLinePlaceholder":169},[36,264,266],{"class":38,"line":265},22,[36,267,268],{"class":46},"[Service]\n",[36,270,272],{"class":38,"line":271},23,[36,273,274],{"class":46},"User=www-data\n",[36,276,278],{"class":38,"line":277},24,[36,279,280],{"class":46},"Group=www-data\n",[36,282,284],{"class":38,"line":283},25,[36,285,286],{"class":46},"WorkingDirectory=\u002Fvar\u002Fwww\u002Fflaskapp\n",[36,288,290],{"class":38,"line":289},26,[36,291,292],{"class":46},"Environment=\"PATH=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\"\n",[36,294,296],{"class":38,"line":295},27,[36,297,298],{"class":46},"ExecStart=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\u002Fgunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app\n",[36,300,302],{"class":38,"line":301},28,[36,303,304],{"class":46},"Restart=always\n",[36,306,308],{"class":38,"line":307},29,[36,309,170],{"emptyLinePlaceholder":169},[36,311,313],{"class":38,"line":312},30,[36,314,315],{"class":46},"[Install]\n",[36,317,319],{"class":38,"line":318},31,[36,320,321],{"class":46},"WantedBy=multi-user.target\n",[36,323,325],{"class":38,"line":324},32,[36,326,194],{"class":46},[36,328,330,332,335],{"class":38,"line":329},33,[36,331,43],{"class":42},[36,333,334],{"class":46}," systemctl",[36,336,337],{"class":46}," daemon-reload\n",[36,339,341,343,345,348,351],{"class":38,"line":340},34,[36,342,43],{"class":42},[36,344,334],{"class":46},[36,346,347],{"class":46}," enable",[36,349,350],{"class":64}," --now",[36,352,353],{"class":46}," flaskapp\n",[36,355,357,359,361,364,366,368,370],{"class":38,"line":356},35,[36,358,43],{"class":42},[36,360,227],{"class":46},[36,362,363],{"class":46}," \u002Fetc\u002Fnginx\u002Fsites-available\u002Fflaskapp",[36,365,142],{"class":141},[36,367,235],{"class":46},[36,369,148],{"class":141},[36,371,151],{"class":46},[36,373,375],{"class":38,"line":374},36,[36,376,377],{"class":46},"server {\n",[36,379,381],{"class":38,"line":380},37,[36,382,383],{"class":46},"    listen 80;\n",[36,385,387],{"class":38,"line":386},38,[36,388,389],{"class":46},"    server_name _;\n",[36,391,393],{"class":38,"line":392},39,[36,394,170],{"emptyLinePlaceholder":169},[36,396,398],{"class":38,"line":397},40,[36,399,400],{"class":46},"    location \u002F {\n",[36,402,404],{"class":38,"line":403},41,[36,405,406],{"class":46},"        proxy_pass http:\u002F\u002F127.0.0.1:8000;\n",[36,408,410],{"class":38,"line":409},42,[36,411,412],{"class":46},"        proxy_set_header Host $host;\n",[36,414,416],{"class":38,"line":415},43,[36,417,418],{"class":46},"        proxy_set_header X-Real-IP $remote_addr;\n",[36,420,422],{"class":38,"line":421},44,[36,423,424],{"class":46},"        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n",[36,426,428],{"class":38,"line":427},45,[36,429,430],{"class":46},"        proxy_set_header X-Forwarded-Proto $scheme;\n",[36,432,434],{"class":38,"line":433},46,[36,435,436],{"class":46},"    }\n",[36,438,440],{"class":38,"line":439},47,[36,441,442],{"class":46},"}\n",[36,444,446],{"class":38,"line":445},48,[36,447,194],{"class":46},[36,449,451,453,456,459,461],{"class":38,"line":450},49,[36,452,43],{"class":42},[36,454,455],{"class":46}," ln",[36,457,458],{"class":64}," -sf",[36,460,363],{"class":46},[36,462,463],{"class":46}," \u002Fetc\u002Fnginx\u002Fsites-enabled\u002Fflaskapp\n",[36,465,467,469,472,475,477,479,481,484],{"class":38,"line":466},50,[36,468,43],{"class":42},[36,470,471],{"class":46}," nginx",[36,473,474],{"class":64}," -t",[36,476,54],{"class":53},[36,478,43],{"class":42},[36,480,334],{"class":46},[36,482,483],{"class":46}," reload",[36,485,74],{"class":46},[36,487,489,492,495],{"class":38,"line":488},51,[36,490,491],{"class":42},"curl",[36,493,494],{"class":64}," -I",[36,496,497],{"class":46}," http:\u002F\u002F127.0.0.1:8000\n",[36,499,501,503,505],{"class":38,"line":500},52,[36,502,491],{"class":42},[36,504,494],{"class":64},[36,506,507],{"class":46}," http:\u002F\u002Flocalhost\n",[14,509,510],{},"This is the fastest working baseline for a single-server deployment. Replace the sample app, domain, paths, and service name with your real project values before production use.",[18,512,514],{"id":513},"whats-happening","What’s Happening",[516,517,518,522,525,528],"ul",{},[519,520,521],"li",{},"Gunicorn runs the Flask WSGI app as the application server.",[519,523,524],{},"Nginx sits in front as the reverse proxy, handles client connections, and forwards requests to Gunicorn.",[519,526,527],{},"systemd keeps Gunicorn running across reboots and restarts it if the process exits.",[519,529,530],{},"Static and media paths should usually be served by Nginx directly instead of Flask in production.",[18,532,534],{"id":533},"step-by-step-guide","Step-by-Step Guide",[536,537,538,573,622,670,781,834,907,952,1017,1052,1081,1117,1191,1246,1337],"ol",{},[519,539,540,544],{},[541,542,543],"strong",{},"Install system packages",[26,545,547],{"className":28,"code":546,"language":30,"meta":31,"style":31},"sudo apt update && sudo apt install -y python3-venv python3-pip nginx\n",[33,548,549],{"__ignoreMap":31},[36,550,551,553,555,557,559,561,563,565,567,569,571],{"class":38,"line":39},[36,552,43],{"class":42},[36,554,47],{"class":46},[36,556,50],{"class":46},[36,558,54],{"class":53},[36,560,43],{"class":42},[36,562,47],{"class":46},[36,564,61],{"class":46},[36,566,65],{"class":64},[36,568,68],{"class":46},[36,570,71],{"class":46},[36,572,74],{"class":46},[519,574,575,578],{},[541,576,577],{},"Create the application directory",[26,579,581],{"className":28,"code":580,"language":30,"meta":31,"style":31},"sudo mkdir -p \u002Fvar\u002Fwww\u002Fflaskapp\nsudo chown -R $USER:$USER \u002Fvar\u002Fwww\u002Fflaskapp\ncd \u002Fvar\u002Fwww\u002Fflaskapp\n",[33,582,583,594,616],{"__ignoreMap":31},[36,584,585,587,590,592],{"class":38,"line":39},[36,586,43],{"class":42},[36,588,589],{"class":46}," mkdir",[36,591,83],{"class":64},[36,593,94],{"class":46},[36,595,596,598,601,604,607,610,613],{"class":38,"line":77},[36,597,43],{"class":42},[36,599,600],{"class":46}," chown",[36,602,603],{"class":64}," -R",[36,605,606],{"class":53}," $USER",[36,608,609],{"class":46},":",[36,611,612],{"class":53},"$USER ",[36,614,615],{"class":46},"\u002Fvar\u002Fwww\u002Fflaskapp\n",[36,617,618,620],{"class":38,"line":97},[36,619,91],{"class":64},[36,621,94],{"class":46},[519,623,624,627],{},[541,625,626],{},"Create a virtual environment and install dependencies",[26,628,630],{"className":28,"code":629,"language":30,"meta":31,"style":31},"python3 -m venv .venv\n. .venv\u002Fbin\u002Factivate\npip install --upgrade pip\npip install flask gunicorn\n",[33,631,632,642,648,660],{"__ignoreMap":31},[36,633,634,636,638,640],{"class":38,"line":39},[36,635,100],{"class":42},[36,637,103],{"class":64},[36,639,106],{"class":46},[36,641,109],{"class":46},[36,643,644,646],{"class":38,"line":77},[36,645,115],{"class":64},[36,647,118],{"class":46},[36,649,650,652,654,657],{"class":38,"line":97},[36,651,124],{"class":42},[36,653,61],{"class":46},[36,655,656],{"class":64}," --upgrade",[36,658,659],{"class":46}," pip\n",[36,661,662,664,666,668],{"class":38,"line":112},[36,663,124],{"class":42},[36,665,61],{"class":46},[36,667,129],{"class":46},[36,669,132],{"class":46},[519,671,672,675,678,679,609,682,760,678,762,609,765],{},[541,673,674],{},"Create a minimal Flask app",[676,677],"br",{},"Create ",[33,680,681],{},"app.py",[26,683,687],{"className":684,"code":685,"language":686,"meta":31,"style":31},"language-python shiki shiki-themes github-light github-dark","from flask import Flask\n\napp = Flask(__name__)\n\n@app.route(\"\u002F\")\ndef hello():\n    return \"Flask + Gunicorn + Nginx is working\"\n","python",[33,688,689,703,707,724,728,741,752],{"__ignoreMap":31},[36,690,691,694,697,700],{"class":38,"line":39},[36,692,693],{"class":141},"from",[36,695,696],{"class":53}," flask ",[36,698,699],{"class":141},"import",[36,701,702],{"class":53}," Flask\n",[36,704,705],{"class":38,"line":77},[36,706,170],{"emptyLinePlaceholder":169},[36,708,709,712,715,718,721],{"class":38,"line":97},[36,710,711],{"class":53},"app ",[36,713,714],{"class":141},"=",[36,716,717],{"class":53}," Flask(",[36,719,720],{"class":64},"__name__",[36,722,723],{"class":53},")\n",[36,725,726],{"class":38,"line":112},[36,727,170],{"emptyLinePlaceholder":169},[36,729,730,733,736,739],{"class":38,"line":121},[36,731,732],{"class":42},"@app.route",[36,734,735],{"class":53},"(",[36,737,738],{"class":46},"\"\u002F\"",[36,740,723],{"class":53},[36,742,743,746,749],{"class":38,"line":135},[36,744,745],{"class":141},"def",[36,747,748],{"class":42}," hello",[36,750,751],{"class":53},"():\n",[36,753,754,757],{"class":38,"line":154},[36,755,756],{"class":141},"    return",[36,758,759],{"class":46}," \"Flask + Gunicorn + Nginx is working\"\n",[676,761],{},[33,763,764],{},"wsgi.py",[26,766,767],{"className":684,"code":214,"language":686,"meta":31,"style":31},[33,768,769],{"__ignoreMap":31},[36,770,771,773,776,778],{"class":38,"line":39},[36,772,693],{"class":141},[36,774,775],{"class":53}," app ",[36,777,699],{"class":141},[36,779,780],{"class":53}," app\n",[519,782,783,786,811,813,814,827,829,830,833],{},[541,784,785],{},"Test Gunicorn directly before adding systemd or Nginx",[26,787,789],{"className":28,"code":788,"language":30,"meta":31,"style":31},". .venv\u002Fbin\u002Factivate\ngunicorn --bind 127.0.0.1:8000 wsgi:app\n",[33,790,791,797],{"__ignoreMap":31},[36,792,793,795],{"class":38,"line":39},[36,794,115],{"class":64},[36,796,118],{"class":46},[36,798,799,802,805,808],{"class":38,"line":77},[36,800,801],{"class":42},"gunicorn",[36,803,804],{"class":64}," --bind",[36,806,807],{"class":46}," 127.0.0.1:8000",[36,809,810],{"class":46}," wsgi:app\n",[676,812],{},"In another shell:",[26,815,817],{"className":28,"code":816,"language":30,"meta":31,"style":31},"curl -I http:\u002F\u002F127.0.0.1:8000\n",[33,818,819],{"__ignoreMap":31},[36,820,821,823,825],{"class":38,"line":39},[36,822,491],{"class":42},[36,824,494],{"class":64},[36,826,497],{"class":46},[676,828],{},"Stop Gunicorn with ",[33,831,832],{},"Ctrl+C"," after the test succeeds.",[519,835,836,839,678,841,609,844],{},[541,837,838],{},"Create the systemd service",[676,840],{},[33,842,843],{},"\u002Fetc\u002Fsystemd\u002Fsystem\u002Fflaskapp.service",[26,845,849],{"className":846,"code":847,"language":848,"meta":31,"style":31},"language-ini shiki shiki-themes github-light github-dark","[Unit]\nDescription=Gunicorn for Flask app\nAfter=network.target\n\n[Service]\nUser=www-data\nGroup=www-data\nWorkingDirectory=\u002Fvar\u002Fwww\u002Fflaskapp\nEnvironment=\"PATH=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\"\nExecStart=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\u002Fgunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n","ini",[33,850,851,855,859,863,867,871,875,879,883,887,891,895,899,903],{"__ignoreMap":31},[36,852,853],{"class":38,"line":39},[36,854,245],{},[36,856,857],{"class":38,"line":77},[36,858,251],{},[36,860,861],{"class":38,"line":97},[36,862,257],{},[36,864,865],{"class":38,"line":112},[36,866,170],{"emptyLinePlaceholder":169},[36,868,869],{"class":38,"line":121},[36,870,268],{},[36,872,873],{"class":38,"line":135},[36,874,274],{},[36,876,877],{"class":38,"line":154},[36,878,280],{},[36,880,881],{"class":38,"line":160},[36,882,286],{},[36,884,885],{"class":38,"line":166},[36,886,292],{},[36,888,889],{"class":38,"line":173},[36,890,298],{},[36,892,893],{"class":38,"line":179},[36,894,304],{},[36,896,897],{"class":38,"line":185},[36,898,170],{"emptyLinePlaceholder":169},[36,900,901],{"class":38,"line":191},[36,902,315],{},[36,904,905],{"class":38,"line":197},[36,906,321],{},[519,908,909,912],{},[541,910,911],{},"Reload systemd and start the service",[26,913,915],{"className":28,"code":914,"language":30,"meta":31,"style":31},"sudo systemctl daemon-reload\nsudo systemctl enable --now flaskapp\nsudo systemctl status flaskapp --no-pager\n",[33,916,917,925,937],{"__ignoreMap":31},[36,918,919,921,923],{"class":38,"line":39},[36,920,43],{"class":42},[36,922,334],{"class":46},[36,924,337],{"class":46},[36,926,927,929,931,933,935],{"class":38,"line":77},[36,928,43],{"class":42},[36,930,334],{"class":46},[36,932,347],{"class":46},[36,934,350],{"class":64},[36,936,353],{"class":46},[36,938,939,941,943,946,949],{"class":38,"line":97},[36,940,43],{"class":42},[36,942,334],{"class":46},[36,944,945],{"class":46}," status",[36,947,948],{"class":46}," flaskapp",[36,950,951],{"class":64}," --no-pager\n",[519,953,954,957,678,959,609,962],{},[541,955,956],{},"Create the Nginx server block",[676,958],{},[33,960,961],{},"\u002Fetc\u002Fnginx\u002Fsites-available\u002Fflaskapp",[26,963,967],{"className":964,"code":965,"language":966,"meta":31,"style":31},"language-nginx shiki shiki-themes github-light github-dark","server {\n    listen 80;\n    server_name _;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8000;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}\n","nginx",[33,968,969,973,977,981,985,989,993,997,1001,1005,1009,1013],{"__ignoreMap":31},[36,970,971],{"class":38,"line":39},[36,972,377],{},[36,974,975],{"class":38,"line":77},[36,976,383],{},[36,978,979],{"class":38,"line":97},[36,980,389],{},[36,982,983],{"class":38,"line":112},[36,984,170],{"emptyLinePlaceholder":169},[36,986,987],{"class":38,"line":121},[36,988,400],{},[36,990,991],{"class":38,"line":135},[36,992,406],{},[36,994,995],{"class":38,"line":154},[36,996,412],{},[36,998,999],{"class":38,"line":160},[36,1000,418],{},[36,1002,1003],{"class":38,"line":166},[36,1004,424],{},[36,1006,1007],{"class":38,"line":173},[36,1008,430],{},[36,1010,1011],{"class":38,"line":179},[36,1012,436],{},[36,1014,1015],{"class":38,"line":185},[36,1016,442],{},[519,1018,1019,1022],{},[541,1020,1021],{},"Enable the site",[26,1023,1025],{"className":28,"code":1024,"language":30,"meta":31,"style":31},"sudo ln -sf \u002Fetc\u002Fnginx\u002Fsites-available\u002Fflaskapp \u002Fetc\u002Fnginx\u002Fsites-enabled\u002Fflaskapp\nsudo rm -f \u002Fetc\u002Fnginx\u002Fsites-enabled\u002Fdefault\n",[33,1026,1027,1039],{"__ignoreMap":31},[36,1028,1029,1031,1033,1035,1037],{"class":38,"line":39},[36,1030,43],{"class":42},[36,1032,455],{"class":46},[36,1034,458],{"class":64},[36,1036,363],{"class":46},[36,1038,463],{"class":46},[36,1040,1041,1043,1046,1049],{"class":38,"line":77},[36,1042,43],{"class":42},[36,1044,1045],{"class":46}," rm",[36,1047,1048],{"class":64}," -f",[36,1050,1051],{"class":46}," \u002Fetc\u002Fnginx\u002Fsites-enabled\u002Fdefault\n",[519,1053,1054,1057],{},[541,1055,1056],{},"Validate and reload Nginx",[26,1058,1060],{"className":28,"code":1059,"language":30,"meta":31,"style":31},"sudo nginx -t\nsudo systemctl reload nginx\n",[33,1061,1062,1071],{"__ignoreMap":31},[36,1063,1064,1066,1068],{"class":38,"line":39},[36,1065,43],{"class":42},[36,1067,471],{"class":46},[36,1069,1070],{"class":64}," -t\n",[36,1072,1073,1075,1077,1079],{"class":38,"line":77},[36,1074,43],{"class":42},[36,1076,334],{"class":46},[36,1078,483],{"class":46},[36,1080,74],{"class":46},[519,1082,1083,1086,1088,1089,1101,1103,1104],{},[541,1084,1085],{},"Test the app through both layers",[676,1087],{},"Test Gunicorn directly:",[26,1090,1091],{"className":28,"code":816,"language":30,"meta":31,"style":31},[33,1092,1093],{"__ignoreMap":31},[36,1094,1095,1097,1099],{"class":38,"line":39},[36,1096,491],{"class":42},[36,1098,494],{"class":64},[36,1100,497],{"class":46},[676,1102],{},"Test through Nginx:",[26,1105,1107],{"className":28,"code":1106,"language":30,"meta":31,"style":31},"curl -I http:\u002F\u002Flocalhost\n",[33,1108,1109],{"__ignoreMap":31},[36,1110,1111,1113,1115],{"class":38,"line":39},[36,1112,491],{"class":42},[36,1114,494],{"class":64},[36,1116,507],{"class":46},[519,1118,1119,1122,1124,1125,1128,1129,1148,1150,1151,1165,1167,1168],{},[541,1120,1121],{},"Serve static files directly with Nginx if your app uses them",[676,1123],{},"Add this inside the same ",[33,1126,1127],{},"server"," block:",[26,1130,1132],{"className":964,"code":1131,"language":966,"meta":31,"style":31},"location \u002Fstatic\u002F {\n    alias \u002Fvar\u002Fwww\u002Fflaskapp\u002Fstatic\u002F;\n}\n",[33,1133,1134,1139,1144],{"__ignoreMap":31},[36,1135,1136],{"class":38,"line":39},[36,1137,1138],{},"location \u002Fstatic\u002F {\n",[36,1140,1141],{"class":38,"line":77},[36,1142,1143],{},"    alias \u002Fvar\u002Fwww\u002Fflaskapp\u002Fstatic\u002F;\n",[36,1145,1146],{"class":38,"line":97},[36,1147,442],{},[676,1149],{},"Ensure the directory exists:",[26,1152,1154],{"className":28,"code":1153,"language":30,"meta":31,"style":31},"mkdir -p \u002Fvar\u002Fwww\u002Fflaskapp\u002Fstatic\n",[33,1155,1156],{"__ignoreMap":31},[36,1157,1158,1160,1162],{"class":38,"line":39},[36,1159,80],{"class":42},[36,1161,83],{"class":64},[36,1163,1164],{"class":46}," \u002Fvar\u002Fwww\u002Fflaskapp\u002Fstatic\n",[676,1166],{},"Then reload Nginx:",[26,1169,1171],{"className":28,"code":1170,"language":30,"meta":31,"style":31},"sudo nginx -t && sudo systemctl reload nginx\n",[33,1172,1173],{"__ignoreMap":31},[36,1174,1175,1177,1179,1181,1183,1185,1187,1189],{"class":38,"line":39},[36,1176,43],{"class":42},[36,1178,471],{"class":46},[36,1180,474],{"class":64},[36,1182,54],{"class":53},[36,1184,43],{"class":42},[36,1186,334],{"class":46},[36,1188,483],{"class":46},[36,1190,74],{"class":46},[519,1192,1193,1196,1198,1199,1207,1209,1210,1219,1221,1222],{},[541,1194,1195],{},"Update the Gunicorn app import path for your real project",[676,1197],{},"Examples:",[26,1200,1201],{"className":846,"code":298,"language":848,"meta":31,"style":31},[33,1202,1203],{"__ignoreMap":31},[36,1204,1205],{"class":38,"line":39},[36,1206,298],{},[676,1208],{},"or",[26,1211,1213],{"className":846,"code":1212,"language":848,"meta":31,"style":31},"ExecStart=\u002Fvar\u002Fwww\u002Fflaskapp\u002F.venv\u002Fbin\u002Fgunicorn --workers 3 --bind 127.0.0.1:8000 myproject.wsgi:app\n",[33,1214,1215],{"__ignoreMap":31},[36,1216,1217],{"class":38,"line":39},[36,1218,1212],{},[676,1220],{},"After editing the unit:",[26,1223,1225],{"className":28,"code":1224,"language":30,"meta":31,"style":31},"sudo systemctl daemon-reload\nsudo systemctl restart flaskapp\n",[33,1226,1227,1235],{"__ignoreMap":31},[36,1228,1229,1231,1233],{"class":38,"line":39},[36,1230,43],{"class":42},[36,1232,334],{"class":46},[36,1234,337],{"class":46},[36,1236,1237,1239,1241,1244],{"class":38,"line":77},[36,1238,43],{"class":42},[36,1240,334],{"class":46},[36,1242,1243],{"class":46}," restart",[36,1245,353],{"class":46},[519,1247,1248,1251,1253,1254,1269,1271,1272,1281,1283,1284,609,1287,1312,1314,1315],{},[541,1249,1250],{},"Add environment variables if required",[676,1252],{},"Option A, inline in the unit:",[26,1255,1257],{"className":846,"code":1256,"language":848,"meta":31,"style":31},"Environment=\"FLASK_ENV=production\"\nEnvironment=\"SECRET_KEY=replace-me\"\n",[33,1258,1259,1264],{"__ignoreMap":31},[36,1260,1261],{"class":38,"line":39},[36,1262,1263],{},"Environment=\"FLASK_ENV=production\"\n",[36,1265,1266],{"class":38,"line":77},[36,1267,1268],{},"Environment=\"SECRET_KEY=replace-me\"\n",[676,1270],{},"Option B, environment file:",[26,1273,1275],{"className":846,"code":1274,"language":848,"meta":31,"style":31},"EnvironmentFile=\u002Fetc\u002Fflaskapp.env\n",[33,1276,1277],{"__ignoreMap":31},[36,1278,1279],{"class":38,"line":39},[36,1280,1274],{},[676,1282],{},"Example ",[33,1285,1286],{},"\u002Fetc\u002Fflaskapp.env",[26,1288,1290],{"className":28,"code":1289,"language":30,"meta":31,"style":31},"SECRET_KEY=replace-me\nDATABASE_URL=postgresql:\u002F\u002Fuser:pass@host\u002Fdbname\n",[33,1291,1292,1302],{"__ignoreMap":31},[36,1293,1294,1297,1299],{"class":38,"line":39},[36,1295,1296],{"class":53},"SECRET_KEY",[36,1298,714],{"class":141},[36,1300,1301],{"class":46},"replace-me\n",[36,1303,1304,1307,1309],{"class":38,"line":77},[36,1305,1306],{"class":53},"DATABASE_URL",[36,1308,714],{"class":141},[36,1310,1311],{"class":46},"postgresql:\u002F\u002Fuser:pass@host\u002Fdbname\n",[676,1313],{},"Then apply changes:",[26,1316,1317],{"className":28,"code":1224,"language":30,"meta":31,"style":31},[33,1318,1319,1327],{"__ignoreMap":31},[36,1320,1321,1323,1325],{"class":38,"line":39},[36,1322,43],{"class":42},[36,1324,334],{"class":46},[36,1326,337],{"class":46},[36,1328,1329,1331,1333,1335],{"class":38,"line":77},[36,1330,43],{"class":42},[36,1332,334],{"class":46},[36,1334,1243],{"class":46},[36,1336,353],{"class":46},[519,1338,1339,1342,1344,1345,1362,1364],{},[541,1340,1341],{},"Add HTTPS only after HTTP works",[676,1343],{},"First confirm:",[516,1346,1347,1353,1359],{},[519,1348,1349,1350],{},"Gunicorn responds on ",[33,1351,1352],{},"127.0.0.1:8000",[519,1354,1355,1356],{},"Nginx responds on ",[33,1357,1358],{},"localhost",[519,1360,1361],{},"your domain points to the server",[676,1363],{},"Then move to TLS setup separately.",[18,1366,1368],{"id":1367},"common-causes","Common Causes",[516,1370,1371,1384,1398,1412,1424,1430,1447,1453],{},[519,1372,1373,1376,1377,1380,1381,115],{},[541,1374,1375],{},"Wrong WSGI import path"," → Gunicorn starts or restarts with import errors → fix the module reference such as ",[33,1378,1379],{},"wsgi:app"," or ",[33,1382,1383],{},"package.module:app",[519,1385,1386,1393,1394,1397],{},[541,1387,1388,1389,1392],{},"Nginx ",[33,1390,1391],{},"proxy_pass"," does not match Gunicorn bind target"," → Nginx returns ",[33,1395,1396],{},"502 Bad Gateway"," or connection refused → make both use the same host\u002Fport or socket path.",[519,1399,1400,1403,1404,1407,1408,1411],{},[541,1401,1402],{},"Incorrect virtual environment path in systemd"," → Gunicorn binary or Python packages cannot be found → correct ",[33,1405,1406],{},"Environment=\"PATH=...\""," and the absolute ",[33,1409,1410],{},"ExecStart"," path.",[519,1413,1414,1417,1418,1380,1421,115],{},[541,1415,1416],{},"Missing environment variables under systemd"," → app works manually but fails as a service → add ",[33,1419,1420],{},"Environment=",[33,1422,1423],{},"EnvironmentFile=",[519,1425,1426,1429],{},[541,1427,1428],{},"Default Nginx site conflicts with the Flask config"," → requests hit the wrong server block → disable conflicting default configs.",[519,1431,1432,1435,1436,1439,1440,1443,1444,115],{},[541,1433,1434],{},"Static files not mapped in Nginx"," → CSS, JS, or images return ",[33,1437,1438],{},"404"," → add a ",[33,1441,1442],{},"location \u002Fstatic\u002F"," block with ",[33,1445,1446],{},"alias",[519,1448,1449,1452],{},[541,1450,1451],{},"Permissions are too restrictive"," → Gunicorn or Nginx cannot read project files or connect to a socket → fix ownership and mode for the service user.",[519,1454,1455,1458,1459,1462,1463,115],{},[541,1456,1457],{},"Firewall or cloud security rules block traffic"," → app works locally but not externally → allow inbound ",[33,1460,1461],{},"80"," and ",[33,1464,1465],{},"443",[18,1467,1469],{"id":1468},"debugging-section","Debugging Section",[14,1471,1472],{},"Check Gunicorn service state:",[26,1474,1476],{"className":28,"code":1475,"language":30,"meta":31,"style":31},"sudo systemctl status flaskapp --no-pager -l\n",[33,1477,1478],{"__ignoreMap":31},[36,1479,1480,1482,1484,1486,1488,1491],{"class":38,"line":39},[36,1481,43],{"class":42},[36,1483,334],{"class":46},[36,1485,945],{"class":46},[36,1487,948],{"class":46},[36,1489,1490],{"class":64}," --no-pager",[36,1492,1493],{"class":64}," -l\n",[14,1495,1496],{},"Read recent Gunicorn logs:",[26,1498,1500],{"className":28,"code":1499,"language":30,"meta":31,"style":31},"sudo journalctl -u flaskapp -n 100 --no-pager\n",[33,1501,1502],{"__ignoreMap":31},[36,1503,1504,1506,1509,1512,1514,1517,1520],{"class":38,"line":39},[36,1505,43],{"class":42},[36,1507,1508],{"class":46}," journalctl",[36,1510,1511],{"class":64}," -u",[36,1513,948],{"class":46},[36,1515,1516],{"class":64}," -n",[36,1518,1519],{"class":64}," 100",[36,1521,951],{"class":64},[14,1523,1524],{},"Follow Gunicorn logs live:",[26,1526,1528],{"className":28,"code":1527,"language":30,"meta":31,"style":31},"sudo journalctl -u flaskapp -f\n",[33,1529,1530],{"__ignoreMap":31},[36,1531,1532,1534,1536,1538,1540],{"class":38,"line":39},[36,1533,43],{"class":42},[36,1535,1508],{"class":46},[36,1537,1511],{"class":64},[36,1539,948],{"class":46},[36,1541,1542],{"class":64}," -f\n",[14,1544,1545],{},"Validate Nginx syntax:",[26,1547,1549],{"className":28,"code":1548,"language":30,"meta":31,"style":31},"sudo nginx -t\n",[33,1550,1551],{"__ignoreMap":31},[36,1552,1553,1555,1557],{"class":38,"line":39},[36,1554,43],{"class":42},[36,1556,471],{"class":46},[36,1558,1070],{"class":64},[14,1560,1561],{},"Check Nginx service status:",[26,1563,1565],{"className":28,"code":1564,"language":30,"meta":31,"style":31},"sudo systemctl status nginx --no-pager\n",[33,1566,1567],{"__ignoreMap":31},[36,1568,1569,1571,1573,1575,1577],{"class":38,"line":39},[36,1570,43],{"class":42},[36,1572,334],{"class":46},[36,1574,945],{"class":46},[36,1576,471],{"class":46},[36,1578,951],{"class":64},[14,1580,1581],{},"Read the Nginx error log:",[26,1583,1585],{"className":28,"code":1584,"language":30,"meta":31,"style":31},"sudo tail -n 100 \u002Fvar\u002Flog\u002Fnginx\u002Ferror.log\n",[33,1586,1587],{"__ignoreMap":31},[36,1588,1589,1591,1594,1596,1598],{"class":38,"line":39},[36,1590,43],{"class":42},[36,1592,1593],{"class":46}," tail",[36,1595,1516],{"class":64},[36,1597,1519],{"class":64},[36,1599,1600],{"class":46}," \u002Fvar\u002Flog\u002Fnginx\u002Ferror.log\n",[14,1602,1603],{},"Read the Nginx access log:",[26,1605,1607],{"className":28,"code":1606,"language":30,"meta":31,"style":31},"sudo tail -n 100 \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log\n",[33,1608,1609],{"__ignoreMap":31},[36,1610,1611,1613,1615,1617,1619],{"class":38,"line":39},[36,1612,43],{"class":42},[36,1614,1593],{"class":46},[36,1616,1516],{"class":64},[36,1618,1519],{"class":64},[36,1620,1621],{"class":46}," \u002Fvar\u002Flog\u002Fnginx\u002Faccess.log\n",[14,1623,1624],{},"Verify Gunicorn is listening:",[26,1626,1628],{"className":28,"code":1627,"language":30,"meta":31,"style":31},"sudo ss -ltnp | grep 8000\n",[33,1629,1630],{"__ignoreMap":31},[36,1631,1632,1634,1637,1640,1643,1646],{"class":38,"line":39},[36,1633,43],{"class":42},[36,1635,1636],{"class":46}," ss",[36,1638,1639],{"class":64}," -ltnp",[36,1641,1642],{"class":141}," |",[36,1644,1645],{"class":42}," grep",[36,1647,1648],{"class":64}," 8000\n",[14,1650,1651],{},"Test the app without Nginx:",[26,1653,1654],{"className":28,"code":816,"language":30,"meta":31,"style":31},[33,1655,1656],{"__ignoreMap":31},[36,1657,1658,1660,1662],{"class":38,"line":39},[36,1659,491],{"class":42},[36,1661,494],{"class":64},[36,1663,497],{"class":46},[14,1665,1666],{},"Test through Nginx locally:",[26,1668,1669],{"className":28,"code":1106,"language":30,"meta":31,"style":31},[33,1670,1671],{"__ignoreMap":31},[36,1672,1673,1675,1677],{"class":38,"line":39},[36,1674,491],{"class":42},[36,1676,494],{"class":64},[36,1678,507],{"class":46},[14,1680,1681],{},"Inspect the loaded systemd unit:",[26,1683,1685],{"className":28,"code":1684,"language":30,"meta":31,"style":31},"sudo systemctl cat flaskapp\n",[33,1686,1687],{"__ignoreMap":31},[36,1688,1689,1691,1693,1696],{"class":38,"line":39},[36,1690,43],{"class":42},[36,1692,334],{"class":46},[36,1694,1695],{"class":46}," cat",[36,1697,353],{"class":46},[14,1699,1700],{},"Dump active Nginx config:",[26,1702,1704],{"className":28,"code":1703,"language":30,"meta":31,"style":31},"sudo nginx -T | less\n",[33,1705,1706],{"__ignoreMap":31},[36,1707,1708,1710,1712,1715,1717],{"class":38,"line":39},[36,1709,43],{"class":42},[36,1711,471],{"class":46},[36,1713,1714],{"class":64}," -T",[36,1716,1642],{"class":141},[36,1718,1719],{"class":42}," less\n",[14,1721,1722],{},"If using UFW, confirm ports are open:",[26,1724,1726],{"className":28,"code":1725,"language":30,"meta":31,"style":31},"sudo ufw status\n",[33,1727,1728],{"__ignoreMap":31},[36,1729,1730,1732,1735],{"class":38,"line":39},[36,1731,43],{"class":42},[36,1733,1734],{"class":46}," ufw",[36,1736,1737],{"class":46}," status\n",[14,1739,1740],{},"Check running Gunicorn processes:",[26,1742,1744],{"className":28,"code":1743,"language":30,"meta":31,"style":31},"ps aux | grep gunicorn\n",[33,1745,1746],{"__ignoreMap":31},[36,1747,1748,1751,1754,1756,1758],{"class":38,"line":39},[36,1749,1750],{"class":42},"ps",[36,1752,1753],{"class":46}," aux",[36,1755,1642],{"class":141},[36,1757,1645],{"class":42},[36,1759,132],{"class":46},[14,1761,1762],{},"If using a Unix socket instead of TCP, verify the socket path and permissions:",[26,1764,1766],{"className":28,"code":1765,"language":30,"meta":31,"style":31},"sudo ls -lah \u002Frun\u002F\nsudo ss -lx | grep gunicorn\n",[33,1767,1768,1781],{"__ignoreMap":31},[36,1769,1770,1772,1775,1778],{"class":38,"line":39},[36,1771,43],{"class":42},[36,1773,1774],{"class":46}," ls",[36,1776,1777],{"class":64}," -lah",[36,1779,1780],{"class":46}," \u002Frun\u002F\n",[36,1782,1783,1785,1787,1790,1792,1794],{"class":38,"line":77},[36,1784,43],{"class":42},[36,1786,1636],{"class":46},[36,1788,1789],{"class":64}," -lx",[36,1791,1642],{"class":141},[36,1793,1645],{"class":42},[36,1795,132],{"class":46},[14,1797,1798],{},"What to look for:",[516,1800,1801,1810,1816,1821,1831],{},[519,1802,1803,1806,1807],{},[33,1804,1805],{},"ModuleNotFoundError"," or import errors in ",[33,1808,1809],{},"journalctl",[519,1811,1812,1815],{},[33,1813,1814],{},"connect() failed (111: Connection refused)"," in Nginx error logs",[519,1817,1818,1819],{},"missing listener on ",[33,1820,1352],{},[519,1822,1823,1824,1827,1828],{},"wrong ",[33,1825,1826],{},"server_name"," or duplicate Nginx server blocks in ",[33,1829,1830],{},"nginx -T",[519,1832,1833],{},"file permission errors when Nginx or Gunicorn reads app or socket paths",[18,1835,1837],{"id":1836},"checklist","Checklist",[516,1839,1842,1851,1857,1867,1876,1885,1894,1900,1906,1912],{"className":1840},[1841],"contains-task-list",[519,1843,1846,1850],{"className":1844},[1845],"task-list-item",[1847,1848],"input",{"disabled":169,"type":1849},"checkbox"," Flask app starts under Gunicorn without import errors.",[519,1852,1854,1856],{"className":1853},[1845],[1847,1855],{"disabled":169,"type":1849}," systemd unit is enabled and stays active after restart.",[519,1858,1860,1862,1863,1866],{"className":1859},[1845],[1847,1861],{"disabled":169,"type":1849}," ",[33,1864,1865],{},"curl http:\u002F\u002F127.0.0.1:8000"," returns a valid app response.",[519,1868,1870,1862,1872,1875],{"className":1869},[1845],[1847,1871],{"disabled":169,"type":1849},[33,1873,1874],{},"nginx -t"," passes without warnings or errors.",[519,1877,1879,1862,1881,1884],{"className":1878},[1845],[1847,1880],{"disabled":169,"type":1849},[33,1882,1883],{},"curl http:\u002F\u002Flocalhost"," returns the app through Nginx.",[519,1886,1888,1890,1891,1893],{"className":1887},[1845],[1847,1889],{"disabled":169,"type":1849}," Correct domain or ",[33,1892,1826],{}," is configured for production.",[519,1895,1897,1899],{"className":1896},[1845],[1847,1898],{"disabled":169,"type":1849}," Static file paths are served by Nginx if the app uses them.",[519,1901,1903,1905],{"className":1902},[1845],[1847,1904],{"disabled":169,"type":1849}," Firewall allows HTTP and HTTPS traffic as required.",[519,1907,1909,1911],{"className":1908},[1845],[1847,1910],{"disabled":169,"type":1849}," Environment variables are loaded in the systemd service.",[519,1913,1915,1917,1918,1462,1920,115],{"className":1914},[1845],[1847,1916],{"disabled":169,"type":1849}," Logs are readable in ",[33,1919,1809],{},[33,1921,1922],{},"\u002Fvar\u002Flog\u002Fnginx\u002F",[18,1924,1926],{"id":1925},"related-guides","Related Guides",[516,1928,1929,1936,1942,1948],{},[519,1930,1931],{},[1932,1933,1935],"a",{"href":1934},"\u002Ffix-issues\u002Ffix-flask-502-bad-gateway-step-by-step-guide","Fix Flask 502 Bad Gateway (Step-by-Step Guide)",[519,1937,1938],{},[1932,1939,1941],{"href":1940},"\u002Ffix-issues\u002Fflask-static-files-not-loading-in-production","Flask Static Files Not Loading in Production",[519,1943,1944],{},[1932,1945,1947],{"href":1946},"\u002Fchecklist\u002Fflask-production-checklist-everything-you-must-do","Flask Production Checklist (Everything You Must Do)",[519,1949,1950],{},[1932,1951,1953],{"href":1952},"\u002Fdeploy\u002Fflask-systemd-plus-gunicorn-service-setup","Flask systemd + Gunicorn Service Setup",[18,1955,1957],{"id":1956},"faq","FAQ",[14,1959,1960,1963,1965,1966,1968],{},[541,1961,1962],{},"Q: Should I use a TCP port or Unix socket for Gunicorn?",[676,1964],{},"\nA: Either works. TCP on ",[33,1967,1352],{}," is simpler to debug, while a Unix socket is common for production if permissions are configured correctly.",[14,1970,1971,1978,1980,1981,1983],{},[541,1972,1973,1974,1977],{},"Q: Why does the app work with ",[33,1975,1976],{},"flask run"," but not with Gunicorn?",[676,1979],{},"\nA: ",[33,1982,1976],{}," often uses a different environment and is not the same as the production WSGI import path. Validate the exact Gunicorn module reference and systemd environment.",[14,1985,1986,1989,1991],{},[541,1987,1988],{},"Q: Do I need systemd for Gunicorn?",[676,1990],{},"\nA: For production on a typical Linux server, yes. systemd provides startup on boot, restart policies, and centralized logs.",[14,1993,1994,1997,1999],{},[541,1995,1996],{},"Q: Can Nginx serve static files directly?",[676,1998],{},"\nA: Yes. That is the standard approach in production and reduces load on Flask and Gunicorn.",[14,2001,2002,2005,2007],{},[541,2003,2004],{},"Q: When should I configure HTTPS?",[676,2006],{},"\nA: After HTTP deployment is working and the domain points to the server.",[14,2009,2010,2017,2019,2020,2023],{},[541,2011,2012,2013,2016],{},"Q: Should Gunicorn bind to ",[33,2014,2015],{},"0.0.0.0"," behind Nginx?",[676,2018],{},"\nA: Usually no. Bind Gunicorn to ",[33,2021,2022],{},"127.0.0.1"," or a Unix socket and let Nginx handle public traffic.",[14,2025,2026,2029,2031,2032,2035,2036,2039],{},[541,2027,2028],{},"Q: How many Gunicorn workers should I start with?",[676,2030],{},"\nA: Start with ",[33,2033,2034],{},"2-4"," small workers or ",[33,2037,2038],{},"2 * CPU + 1"," as a baseline, then tune based on memory usage and request patterns.",[18,2041,2043],{"id":2042},"final-takeaway","Final Takeaway",[14,2045,2046],{},"A reliable Flask production deployment uses Gunicorn for the app process, systemd for process supervision, and Nginx as the public reverse proxy. Build and validate the stack in order—Flask app, Gunicorn, systemd, then Nginx—so deployment issues are isolated quickly and fixed with less guesswork.",[2048,2049,2050],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":31,"searchDepth":77,"depth":77,"links":2052},[2053,2054,2055,2056,2057,2058,2059,2060,2061],{"id":20,"depth":77,"text":21},{"id":513,"depth":77,"text":514},{"id":533,"depth":77,"text":534},{"id":1367,"depth":77,"text":1368},{"id":1468,"depth":77,"text":1469},{"id":1836,"depth":77,"text":1837},{"id":1925,"depth":77,"text":1926},{"id":1956,"depth":77,"text":1957},{"id":2042,"depth":77,"text":2043},"Complete guide on deploy flask with nginx + gunicorn (step-by-step guide) for Flask production environments.","md",{"ogTitle":5,"ogDescription":2062,"twitterCard":2065,"robots":2066,"canonical":2067},"summary_large_image","index, follow","https:\u002F\u002Fflask-deployment.com\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide","\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide",{"title":5,"description":2062},"deploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide","L1UoR01zGtm5lLCrVRIaWXo7YTvRY0xL_XygqwiOFIM",1776805765064]