[{"data":1,"prerenderedAt":1627},["ShallowReactive",2],{"\u002Ffix-issues\u002Fflask-environment-variables-not-loading-in-production":3},{"id":4,"title":5,"body":6,"description":1617,"extension":1618,"meta":1619,"navigation":80,"path":1623,"seo":1624,"stem":1625,"__hash__":1626},"content\u002Ffix-issues\u002Fflask-environment-variables-not-loading-in-production.md","Flask Environment Variables Not Loading in Production",{"type":7,"value":8,"toc":1606},"minimark",[9,13,17,22,249,264,268,271,275,1078,1082,1205,1209,1212,1251,1254,1286,1289,1322,1325,1364,1367,1412,1415,1444,1448,1514,1518,1545,1549,1557,1571,1579,1587,1595,1599,1602],[10,11,5],"h1",{"id":12},"flask-environment-variables-not-loading-in-production",[14,15,16],"p",{},"If your Flask app works locally but production environment variables are missing or incorrect, this guide shows you how to fix the loading path step-by-step. The goal is to make your app read the correct variables reliably under the actual process manager running production.",[18,19,21],"h2",{"id":20},"quick-fix-quick-setup","Quick Fix \u002F Quick Setup",[23,24,29],"pre",{"className":25,"code":26,"language":27,"meta":28,"style":28},"language-bash shiki shiki-themes github-light github-dark","# 1) Check what systemd is actually passing to Gunicorn\nsudo systemctl show gunicorn --property=Environment\nsudo systemctl cat gunicorn\n\n# 2) Add or correct Environment entries in the service override\nsudo systemctl edit gunicorn\n\n# Example override:\n# [Service]\n# Environment=\"FLASK_ENV=production\"\n# Environment=\"SECRET_KEY=change-me\"\n# Environment=\"DATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fdbname\"\n# EnvironmentFile=\u002Fetc\u002Fdefault\u002Fmyflaskapp\n\n# 3) If using an EnvironmentFile, verify format\nsudo grep -v '^#' \u002Fetc\u002Fdefault\u002Fmyflaskapp\n\n# 4) Reload and restart\nsudo systemctl daemon-reload\nsudo systemctl restart gunicorn\nsudo systemctl status gunicorn --no-pager\n\n# 5) Confirm inside the running service logs\nsudo journalctl -u gunicorn -n 100 --no-pager\n","bash","",[30,31,32,41,62,75,82,88,100,105,111,117,123,129,135,141,146,152,169,174,180,190,202,217,222,228],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,40],{"class":39},"sJ8bj","# 1) Check what systemd is actually passing to Gunicorn\n",[33,42,44,48,52,55,58],{"class":35,"line":43},2,[33,45,47],{"class":46},"sScJk","sudo",[33,49,51],{"class":50},"sZZnC"," systemctl",[33,53,54],{"class":50}," show",[33,56,57],{"class":50}," gunicorn",[33,59,61],{"class":60},"sj4cs"," --property=Environment\n",[33,63,65,67,69,72],{"class":35,"line":64},3,[33,66,47],{"class":46},[33,68,51],{"class":50},[33,70,71],{"class":50}," cat",[33,73,74],{"class":50}," gunicorn\n",[33,76,78],{"class":35,"line":77},4,[33,79,81],{"emptyLinePlaceholder":80},true,"\n",[33,83,85],{"class":35,"line":84},5,[33,86,87],{"class":39},"# 2) Add or correct Environment entries in the service override\n",[33,89,91,93,95,98],{"class":35,"line":90},6,[33,92,47],{"class":46},[33,94,51],{"class":50},[33,96,97],{"class":50}," edit",[33,99,74],{"class":50},[33,101,103],{"class":35,"line":102},7,[33,104,81],{"emptyLinePlaceholder":80},[33,106,108],{"class":35,"line":107},8,[33,109,110],{"class":39},"# Example override:\n",[33,112,114],{"class":35,"line":113},9,[33,115,116],{"class":39},"# [Service]\n",[33,118,120],{"class":35,"line":119},10,[33,121,122],{"class":39},"# Environment=\"FLASK_ENV=production\"\n",[33,124,126],{"class":35,"line":125},11,[33,127,128],{"class":39},"# Environment=\"SECRET_KEY=change-me\"\n",[33,130,132],{"class":35,"line":131},12,[33,133,134],{"class":39},"# Environment=\"DATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fdbname\"\n",[33,136,138],{"class":35,"line":137},13,[33,139,140],{"class":39},"# EnvironmentFile=\u002Fetc\u002Fdefault\u002Fmyflaskapp\n",[33,142,144],{"class":35,"line":143},14,[33,145,81],{"emptyLinePlaceholder":80},[33,147,149],{"class":35,"line":148},15,[33,150,151],{"class":39},"# 3) If using an EnvironmentFile, verify format\n",[33,153,155,157,160,163,166],{"class":35,"line":154},16,[33,156,47],{"class":46},[33,158,159],{"class":50}," grep",[33,161,162],{"class":60}," -v",[33,164,165],{"class":50}," '^#'",[33,167,168],{"class":50}," \u002Fetc\u002Fdefault\u002Fmyflaskapp\n",[33,170,172],{"class":35,"line":171},17,[33,173,81],{"emptyLinePlaceholder":80},[33,175,177],{"class":35,"line":176},18,[33,178,179],{"class":39},"# 4) Reload and restart\n",[33,181,183,185,187],{"class":35,"line":182},19,[33,184,47],{"class":46},[33,186,51],{"class":50},[33,188,189],{"class":50}," daemon-reload\n",[33,191,193,195,197,200],{"class":35,"line":192},20,[33,194,47],{"class":46},[33,196,51],{"class":50},[33,198,199],{"class":50}," restart",[33,201,74],{"class":50},[33,203,205,207,209,212,214],{"class":35,"line":204},21,[33,206,47],{"class":46},[33,208,51],{"class":50},[33,210,211],{"class":50}," status",[33,213,57],{"class":50},[33,215,216],{"class":60}," --no-pager\n",[33,218,220],{"class":35,"line":219},22,[33,221,81],{"emptyLinePlaceholder":80},[33,223,225],{"class":35,"line":224},23,[33,226,227],{"class":39},"# 5) Confirm inside the running service logs\n",[33,229,231,233,236,239,241,244,247],{"class":35,"line":230},24,[33,232,47],{"class":46},[33,234,235],{"class":50}," journalctl",[33,237,238],{"class":60}," -u",[33,240,57],{"class":50},[33,242,243],{"class":60}," -n",[33,245,246],{"class":60}," 100",[33,248,216],{"class":60},[14,250,251,252,255,256,259,260,263],{},"In production, Flask does not automatically inherit the same shell environment you use interactively. Most failures come from setting variables in ",[30,253,254],{},".bashrc",", ",[30,257,258],{},".profile",", or a local ",[30,261,262],{},".env"," file that Gunicorn or systemd never reads.",[18,265,267],{"id":266},"whats-happening","What’s Happening",[14,269,270],{},"Production Flask processes usually run under systemd, Docker, or another supervisor, not your interactive shell. Variables exported manually in a terminal, shell profile, or SSH session are usually unavailable to Gunicorn workers. Nginx does not provide application environment variables to Flask; Gunicorn or the container runtime must pass them explicitly.",[18,272,274],{"id":273},"step-by-step-guide","Step-by-Step Guide",[276,277,278,345,415,483,579,657,713,808,868,945,998,1059],"ol",{},[279,280,281,285,288,289,342,344],"li",{},[282,283,284],"strong",{},"Identify how the app is started",[286,287],"br",{},"Confirm whether Flask runs under systemd, Docker, Docker Compose, or another process manager.",[23,290,292],{"className":25,"code":291,"language":27,"meta":28,"style":28},"ps aux | grep gunicorn\nsudo systemctl status gunicorn --no-pager\nsystemctl list-units --type=service | grep -i gunicorn\n",[30,293,294,310,322],{"__ignoreMap":28},[33,295,296,299,302,306,308],{"class":35,"line":36},[33,297,298],{"class":46},"ps",[33,300,301],{"class":50}," aux",[33,303,305],{"class":304},"szBVR"," |",[33,307,159],{"class":46},[33,309,74],{"class":50},[33,311,312,314,316,318,320],{"class":35,"line":43},[33,313,47],{"class":46},[33,315,51],{"class":50},[33,317,211],{"class":50},[33,319,57],{"class":50},[33,321,216],{"class":60},[33,323,324,327,330,333,335,337,340],{"class":35,"line":64},[33,325,326],{"class":46},"systemctl",[33,328,329],{"class":50}," list-units",[33,331,332],{"class":60}," --type=service",[33,334,305],{"class":304},[33,336,159],{"class":46},[33,338,339],{"class":60}," -i",[33,341,74],{"class":50},[286,343],{},"If the app runs in Docker instead of systemd, fix the environment in container configuration, not in your shell.",[279,346,347,350,352,353,381,383,384,412,414],{},[282,348,349],{},"Print the active service definition",[286,351],{},"Inspect the live unit and all overrides.",[23,354,356],{"className":25,"code":355,"language":27,"meta":28,"style":28},"sudo systemctl cat gunicorn\nsudo systemctl show gunicorn --property=Environment,User,Group,WorkingDirectory\n",[30,357,358,368],{"__ignoreMap":28},[33,359,360,362,364,366],{"class":35,"line":36},[33,361,47],{"class":46},[33,363,51],{"class":50},[33,365,71],{"class":50},[33,367,74],{"class":50},[33,369,370,372,374,376,378],{"class":35,"line":43},[33,371,47],{"class":46},[33,373,51],{"class":50},[33,375,54],{"class":50},[33,377,57],{"class":50},[33,379,380],{"class":60}," --property=Environment,User,Group,WorkingDirectory\n",[286,382],{},"Check for:",[385,386,387,392,397,402,407],"ul",{},[279,388,389],{},[30,390,391],{},"Environment=",[279,393,394],{},[30,395,396],{},"EnvironmentFile=",[279,398,399],{},[30,400,401],{},"WorkingDirectory=",[279,403,404],{},[30,405,406],{},"User=",[279,408,409],{},[30,410,411],{},"ExecStart=",[286,413],{},"Make sure you are editing the correct service name.",[279,416,417,420,422,423,438,440,441,473,475,476,479,480,482],{},[282,418,419],{},"Put variables in the actual production startup path",[286,421],{},"For systemd-managed Gunicorn, define variables directly in the unit or in an env file.",[23,424,426],{"className":25,"code":425,"language":27,"meta":28,"style":28},"sudo systemctl edit gunicorn\n",[30,427,428],{"__ignoreMap":28},[33,429,430,432,434,436],{"class":35,"line":36},[33,431,47],{"class":46},[33,433,51],{"class":50},[33,435,97],{"class":50},[33,437,74],{"class":50},[286,439],{},"Example override:",[23,442,446],{"className":443,"code":444,"language":445,"meta":28,"style":28},"language-ini shiki shiki-themes github-light github-dark","[Service]\nEnvironment=\"FLASK_ENV=production\"\nEnvironment=\"SECRET_KEY=change-me\"\nEnvironment=\"DATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fdbname\"\nEnvironmentFile=\u002Fetc\u002Fdefault\u002Fmyflaskapp\n","ini",[30,447,448,453,458,463,468],{"__ignoreMap":28},[33,449,450],{"class":35,"line":36},[33,451,452],{},"[Service]\n",[33,454,455],{"class":35,"line":43},[33,456,457],{},"Environment=\"FLASK_ENV=production\"\n",[33,459,460],{"class":35,"line":64},[33,461,462],{},"Environment=\"SECRET_KEY=change-me\"\n",[33,464,465],{"class":35,"line":77},[33,466,467],{},"Environment=\"DATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fdbname\"\n",[33,469,470],{"class":35,"line":84},[33,471,472],{},"EnvironmentFile=\u002Fetc\u002Fdefault\u002Fmyflaskapp\n",[286,474],{},"If you already use ",[30,477,478],{},"\u002Fetc\u002Fdefault\u002Fmyflaskapp",", keep secrets there and use ",[30,481,396],{},".",[279,484,485,492,494,495,498,499,501,502,524,526,527,542,544,545],{},[282,486,487,488,491],{},"Use valid ",[30,489,490],{},"EnvironmentFile"," syntax",[286,493],{},"systemd expects plain ",[30,496,497],{},"KEY=value"," lines.",[286,500],{},"Correct:",[23,503,507],{"className":504,"code":505,"language":506,"meta":28,"style":28},"language-env shiki shiki-themes github-light github-dark","SECRET_KEY=supersecret\nDATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fappdb\nAPP_ENV_MARKER=prod-check\n","env",[30,508,509,514,519],{"__ignoreMap":28},[33,510,511],{"class":35,"line":36},[33,512,513],{},"SECRET_KEY=supersecret\n",[33,515,516],{"class":35,"line":43},[33,517,518],{},"DATABASE_URL=postgresql:\u002F\u002Fuser:pass@127.0.0.1\u002Fappdb\n",[33,520,521],{"class":35,"line":64},[33,522,523],{},"APP_ENV_MARKER=prod-check\n",[286,525],{},"Incorrect:",[385,528,529,534,539],{},[279,530,531],{},[30,532,533],{},"export SECRET_KEY=supersecret",[279,535,536],{},[30,537,538],{},"SECRET_KEY = supersecret",[279,540,541],{},"shell functions or command substitutions",[286,543],{},"Validate the file:",[23,546,548],{"className":25,"code":547,"language":27,"meta":28,"style":28},"sudo grep -n -v '^#' \u002Fetc\u002Fdefault\u002Fmyflaskapp\nsudo awk -F= 'NF\u003C2 {print NR \": bad line -> \" $0}' \u002Fetc\u002Fdefault\u002Fmyflaskapp\n",[30,549,550,564],{"__ignoreMap":28},[33,551,552,554,556,558,560,562],{"class":35,"line":36},[33,553,47],{"class":46},[33,555,159],{"class":50},[33,557,243],{"class":60},[33,559,162],{"class":60},[33,561,165],{"class":50},[33,563,168],{"class":50},[33,565,566,568,571,574,577],{"class":35,"line":43},[33,567,47],{"class":46},[33,569,570],{"class":50}," awk",[33,572,573],{"class":60}," -F=",[33,575,576],{"class":50}," 'NF\u003C2 {print NR \": bad line -> \" $0}'",[33,578,168],{"class":50},[279,580,581,584,586,587,640,642,643],{},[282,582,583],{},"Store secrets outside the project directory",[286,585],{},"Keep production secrets outside the repo.",[23,588,590],{"className":25,"code":589,"language":27,"meta":28,"style":28},"sudo mkdir -p \u002Fetc\u002Fmyflaskapp\nsudo cp \u002Fetc\u002Fdefault\u002Fmyflaskapp \u002Fetc\u002Fmyflaskapp\u002Fenv\nsudo chmod 600 \u002Fetc\u002Fmyflaskapp\u002Fenv\nls -l \u002Fetc\u002Fmyflaskapp\u002Fenv\n",[30,591,592,605,618,630],{"__ignoreMap":28},[33,593,594,596,599,602],{"class":35,"line":36},[33,595,47],{"class":46},[33,597,598],{"class":50}," mkdir",[33,600,601],{"class":60}," -p",[33,603,604],{"class":50}," \u002Fetc\u002Fmyflaskapp\n",[33,606,607,609,612,615],{"class":35,"line":43},[33,608,47],{"class":46},[33,610,611],{"class":50}," cp",[33,613,614],{"class":50}," \u002Fetc\u002Fdefault\u002Fmyflaskapp",[33,616,617],{"class":50}," \u002Fetc\u002Fmyflaskapp\u002Fenv\n",[33,619,620,622,625,628],{"class":35,"line":64},[33,621,47],{"class":46},[33,623,624],{"class":50}," chmod",[33,626,627],{"class":60}," 600",[33,629,617],{"class":50},[33,631,632,635,638],{"class":35,"line":77},[33,633,634],{"class":46},"ls",[33,636,637],{"class":60}," -l",[33,639,617],{"class":50},[286,641],{},"Update the unit if needed:",[23,644,646],{"className":443,"code":645,"language":445,"meta":28,"style":28},"[Service]\nEnvironmentFile=\u002Fetc\u002Fmyflaskapp\u002Fenv\n",[30,647,648,652],{"__ignoreMap":28},[33,649,650],{"class":35,"line":36},[33,651,452],{},[33,653,654],{"class":35,"line":43},[33,655,656],{},"EnvironmentFile=\u002Fetc\u002Fmyflaskapp\u002Fenv\n",[279,658,659,665,667,668,671,672,690,692,693,707,709,710,712],{},[282,660,661,662],{},"Verify ",[30,663,664],{},"WorkingDirectory",[286,666],{},"If your application relies on relative paths or ",[30,669,670],{},"python-dotenv",", the service working directory must match the app location.",[23,673,675],{"className":25,"code":674,"language":27,"meta":28,"style":28},"sudo systemctl show gunicorn --property=WorkingDirectory\n",[30,676,677],{"__ignoreMap":28},[33,678,679,681,683,685,687],{"class":35,"line":36},[33,680,47],{"class":46},[33,682,51],{"class":50},[33,684,54],{"class":50},[33,686,57],{"class":50},[33,688,689],{"class":60}," --property=WorkingDirectory\n",[286,691],{},"Example:",[23,694,696],{"className":443,"code":695,"language":445,"meta":28,"style":28},"[Service]\nWorkingDirectory=\u002Fsrv\u002Fmyflaskapp\n",[30,697,698,702],{"__ignoreMap":28},[33,699,700],{"class":35,"line":36},[33,701,452],{},[33,703,704],{"class":35,"line":43},[33,705,706],{},"WorkingDirectory=\u002Fsrv\u002Fmyflaskapp\n",[286,708],{},"A wrong working directory commonly causes ",[30,711,262],{}," discovery to fail silently.",[279,714,715,718,720,721,724,725,692,727,778,780,781,805,807],{},[282,716,717],{},"Check Flask config code",[286,719],{},"Make sure the application reads from ",[30,722,723],{},"os.environ"," or a validated config object.",[286,726],{},[23,728,732],{"className":729,"code":730,"language":731,"meta":28,"style":28},"language-python shiki shiki-themes github-light github-dark","import os\n\nSECRET_KEY = os.environ[\"SECRET_KEY\"]\nDATABASE_URL = os.environ[\"DATABASE_URL\"]\n","python",[30,733,734,743,747,764],{"__ignoreMap":28},[33,735,736,739],{"class":35,"line":36},[33,737,738],{"class":304},"import",[33,740,742],{"class":741},"sVt8B"," os\n",[33,744,745],{"class":35,"line":43},[33,746,81],{"emptyLinePlaceholder":80},[33,748,749,752,755,758,761],{"class":35,"line":64},[33,750,751],{"class":60},"SECRET_KEY",[33,753,754],{"class":304}," =",[33,756,757],{"class":741}," os.environ[",[33,759,760],{"class":50},"\"SECRET_KEY\"",[33,762,763],{"class":741},"]\n",[33,765,766,769,771,773,776],{"class":35,"line":77},[33,767,768],{"class":60},"DATABASE_URL",[33,770,754],{"class":304},[33,772,757],{"class":741},[33,774,775],{"class":50},"\"DATABASE_URL\"",[33,777,763],{"class":741},[286,779],{},"Avoid hidden fallbacks like:",[23,782,784],{"className":729,"code":783,"language":731,"meta":28,"style":28},"SECRET_KEY = os.environ.get(\"SECRET_KEY\", \"dev-value\")\n",[30,785,786],{"__ignoreMap":28},[33,787,788,790,792,795,797,799,802],{"class":35,"line":36},[33,789,751],{"class":60},[33,791,754],{"class":304},[33,793,794],{"class":741}," os.environ.get(",[33,796,760],{"class":50},[33,798,255],{"class":741},[33,800,801],{"class":50},"\"dev-value\"",[33,803,804],{"class":741},")\n",[286,806],{},"In production, defaults can mask broken environment loading.",[279,809,810,816,818,819,821,822,824,825,848,850,851],{},[282,811,812,813,815],{},"Handle ",[30,814,670],{}," intentionally",[286,817],{},"If you use ",[30,820,670],{},", do not assume it will load automatically in production. Prefer systemd or container-defined environment variables.",[286,823],{},"Example explicit load:",[23,826,828],{"className":729,"code":827,"language":731,"meta":28,"style":28},"from dotenv import load_dotenv\nload_dotenv()\n",[30,829,830,843],{"__ignoreMap":28},[33,831,832,835,838,840],{"class":35,"line":36},[33,833,834],{"class":304},"from",[33,836,837],{"class":741}," dotenv ",[33,839,738],{"class":304},[33,841,842],{"class":741}," load_dotenv\n",[33,844,845],{"class":35,"line":43},[33,846,847],{"class":741},"load_dotenv()\n",[286,849],{},"If production depends on this, confirm:",[385,852,853,856,862],{},[279,854,855],{},"the package is installed",[279,857,858,859,861],{},"the ",[30,860,262],{}," file exists",[279,863,864,865,867],{},"the service ",[30,866,664],{}," points to the expected project root",[279,869,870,873,875,876,911,913,914],{},[282,871,872],{},"Reload and restart after changes",[286,874],{},"For systemd:",[23,877,879],{"className":25,"code":878,"language":27,"meta":28,"style":28},"sudo systemctl daemon-reload\nsudo systemctl restart gunicorn\nsudo systemctl status gunicorn --no-pager\n",[30,880,881,889,899],{"__ignoreMap":28},[33,882,883,885,887],{"class":35,"line":36},[33,884,47],{"class":46},[33,886,51],{"class":50},[33,888,189],{"class":50},[33,890,891,893,895,897],{"class":35,"line":43},[33,892,47],{"class":46},[33,894,51],{"class":50},[33,896,199],{"class":50},[33,898,74],{"class":50},[33,900,901,903,905,907,909],{"class":35,"line":64},[33,902,47],{"class":46},[33,904,51],{"class":50},[33,906,211],{"class":50},[33,908,57],{"class":50},[33,910,216],{"class":60},[286,912],{},"For Docker Compose:",[23,915,917],{"className":25,"code":916,"language":27,"meta":28,"style":28},"docker compose config\ndocker compose up -d --force-recreate\n",[30,918,919,930],{"__ignoreMap":28},[33,920,921,924,927],{"class":35,"line":36},[33,922,923],{"class":46},"docker",[33,925,926],{"class":50}," compose",[33,928,929],{"class":50}," config\n",[33,931,932,934,936,939,942],{"class":35,"line":43},[33,933,923],{"class":46},[33,935,926],{"class":50},[33,937,938],{"class":50}," up",[33,940,941],{"class":60}," -d",[33,943,944],{"class":60}," --force-recreate\n",[279,946,947,950,952,953,961,963,964,966,967],{},[282,948,949],{},"Validate with a safe test variable",[286,951],{},"Add a non-secret marker such as:",[23,954,955],{"className":504,"code":523,"language":506,"meta":28,"style":28},[30,956,957],{"__ignoreMap":28},[33,958,959],{"class":35,"line":36},[33,960,523],{},[286,962],{},"Then restart and confirm the app can read it through logs or a temporary diagnostic endpoint.",[286,965],{},"Example temporary check:",[23,968,970],{"className":729,"code":969,"language":731,"meta":28,"style":28},"import os\nprint(\"APP_ENV_MARKER present:\", os.environ.get(\"APP_ENV_MARKER\"))\n",[30,971,972,978],{"__ignoreMap":28},[33,973,974,976],{"class":35,"line":36},[33,975,738],{"class":304},[33,977,742],{"class":741},[33,979,980,983,986,989,992,995],{"class":35,"line":43},[33,981,982],{"class":60},"print",[33,984,985],{"class":741},"(",[33,987,988],{"class":50},"\"APP_ENV_MARKER present:\"",[33,990,991],{"class":741},", os.environ.get(",[33,993,994],{"class":50},"\"APP_ENV_MARKER\"",[33,996,997],{"class":741},"))\n",[279,999,1000,1003,1005,1006,1024],{},[282,1001,1002],{},"Inspect logs for config failures",[286,1004],{},"Look for:",[385,1007,1008,1013,1018,1021],{},[279,1009,1010],{},[30,1011,1012],{},"KeyError",[279,1014,1015],{},[30,1016,1017],{},"RuntimeError",[279,1019,1020],{},"config validation errors",[279,1022,1023],{},"import errors during startup",[23,1025,1027],{"className":25,"code":1026,"language":27,"meta":28,"style":28},"sudo journalctl -u gunicorn -n 200 --no-pager\nsudo journalctl -u gunicorn -f\n",[30,1028,1029,1046],{"__ignoreMap":28},[33,1030,1031,1033,1035,1037,1039,1041,1044],{"class":35,"line":36},[33,1032,47],{"class":46},[33,1034,235],{"class":50},[33,1036,238],{"class":60},[33,1038,57],{"class":50},[33,1040,243],{"class":60},[33,1042,1043],{"class":60}," 200",[33,1045,216],{"class":60},[33,1047,1048,1050,1052,1054,1056],{"class":35,"line":43},[33,1049,47],{"class":46},[33,1051,235],{"class":50},[33,1053,238],{"class":60},[33,1055,57],{"class":50},[33,1057,1058],{"class":60}," -f\n",[279,1060,1061,1064,1066,1067],{},[282,1062,1063],{},"Remove temporary diagnostics",[286,1065],{},"After confirming correct loading:",[385,1068,1069,1072,1075],{},[279,1070,1071],{},"remove test log statements",[279,1073,1074],{},"remove temporary endpoints",[279,1076,1077],{},"keep secrets only in the approved production source of truth",[18,1079,1081],{"id":1080},"common-causes","Common Causes",[385,1083,1084,1103,1116,1131,1145,1159,1165,1187,1193,1199],{},[279,1085,1086,1096,1097,1099,1100,1102],{},[282,1087,1088,1089,255,1092,1095],{},"Variables were added to ",[30,1090,1091],{},"~\u002F.bashrc",[30,1093,1094],{},"~\u002F.profile",", or a manual shell export"," → Gunicorn never sees them → define them with ",[30,1098,391],{}," or ",[30,1101,396],{}," in the service.",[279,1104,1105,1108,1109,1112,1113,482],{},[282,1106,1107],{},"The wrong systemd unit was edited"," → changes do not affect the running app → verify the exact service name with ",[30,1110,1111],{},"systemctl status"," and ",[30,1114,1115],{},"systemctl cat",[279,1117,1118,1123,1124,1126,1127,1130],{},[282,1119,1120,1122],{},[30,1121,490],{}," syntax is invalid"," → systemd skips or misreads values → use plain ",[30,1125,497],{}," lines without ",[30,1128,1129],{},"export"," or shell syntax.",[279,1132,1133,1138,1139,1141,1142,1144],{},[282,1134,1135,1137],{},[30,1136,664],{}," is wrong"," → ",[30,1140,670],{}," or relative config loading misses the ",[30,1143,262],{}," file → set the correct project directory in the service.",[279,1146,1147,1154,1155,1158],{},[282,1148,1149,1150,1153],{},"The service was restarted without ",[30,1151,1152],{},"daemon-reload"," after unit changes"," → new variables are not applied → run ",[30,1156,1157],{},"systemctl daemon-reload"," and restart.",[279,1160,1161,1164],{},[282,1162,1163],{},"Variables are defined in a deploy script but not persisted for the service"," → values disappear after the shell exits → store them in the service or container config.",[279,1166,1167,1178,1179,1182,1183,1186],{},[282,1168,1169,1170,1173,1174,1177],{},"Docker ",[30,1171,1172],{},"env_file"," or Compose ",[30,1175,1176],{},"environment"," entries are missing or overridden"," → container starts without expected values → inspect ",[30,1180,1181],{},"docker compose config"," and container ",[30,1184,1185],{},"Env"," output.",[279,1188,1189,1192],{},[282,1190,1191],{},"Application config code uses defaults or conditional loading that masks failures"," → missing variables go unnoticed until runtime → validate required keys at startup.",[279,1194,1195,1198],{},[282,1196,1197],{},"The env file permissions are too restrictive or owned by the wrong user"," → service cannot read it → fix ownership and mode for the service user.",[279,1200,1201,1204],{},[282,1202,1203],{},"A secret contains special characters and was copied with broken quoting or whitespace"," → parsing fails or the value is truncated → simplify formatting and test with a temporary marker variable.",[18,1206,1208],{"id":1207},"debugging-section","Debugging Section",[14,1210,1211],{},"Check service status and the active unit:",[23,1213,1215],{"className":25,"code":1214,"language":27,"meta":28,"style":28},"sudo systemctl status gunicorn --no-pager\nsudo systemctl cat gunicorn\nsudo systemctl show gunicorn --property=Environment,User,Group,WorkingDirectory\n",[30,1216,1217,1229,1239],{"__ignoreMap":28},[33,1218,1219,1221,1223,1225,1227],{"class":35,"line":36},[33,1220,47],{"class":46},[33,1222,51],{"class":50},[33,1224,211],{"class":50},[33,1226,57],{"class":50},[33,1228,216],{"class":60},[33,1230,1231,1233,1235,1237],{"class":35,"line":43},[33,1232,47],{"class":46},[33,1234,51],{"class":50},[33,1236,71],{"class":50},[33,1238,74],{"class":50},[33,1240,1241,1243,1245,1247,1249],{"class":35,"line":64},[33,1242,47],{"class":46},[33,1244,51],{"class":50},[33,1246,54],{"class":50},[33,1248,57],{"class":50},[33,1250,380],{"class":60},[14,1252,1253],{},"Check logs:",[23,1255,1256],{"className":25,"code":1026,"language":27,"meta":28,"style":28},[30,1257,1258,1274],{"__ignoreMap":28},[33,1259,1260,1262,1264,1266,1268,1270,1272],{"class":35,"line":36},[33,1261,47],{"class":46},[33,1263,235],{"class":50},[33,1265,238],{"class":60},[33,1267,57],{"class":50},[33,1269,243],{"class":60},[33,1271,1043],{"class":60},[33,1273,216],{"class":60},[33,1275,1276,1278,1280,1282,1284],{"class":35,"line":43},[33,1277,47],{"class":46},[33,1279,235],{"class":50},[33,1281,238],{"class":60},[33,1283,57],{"class":50},[33,1285,1058],{"class":60},[14,1287,1288],{},"Confirm the running process and service name:",[23,1290,1292],{"className":25,"code":1291,"language":27,"meta":28,"style":28},"ps aux | grep gunicorn\nsystemctl list-units --type=service | grep -i gunicorn\n",[30,1293,1294,1306],{"__ignoreMap":28},[33,1295,1296,1298,1300,1302,1304],{"class":35,"line":36},[33,1297,298],{"class":46},[33,1299,301],{"class":50},[33,1301,305],{"class":304},[33,1303,159],{"class":46},[33,1305,74],{"class":50},[33,1307,1308,1310,1312,1314,1316,1318,1320],{"class":35,"line":43},[33,1309,326],{"class":46},[33,1311,329],{"class":50},[33,1313,332],{"class":60},[33,1315,305],{"class":304},[33,1317,159],{"class":46},[33,1319,339],{"class":60},[33,1321,74],{"class":50},[14,1323,1324],{},"Validate env file contents and syntax:",[23,1326,1328],{"className":25,"code":1327,"language":27,"meta":28,"style":28},"sudo grep -n -v '^#' \u002Fetc\u002Fdefault\u002Fmyflaskapp\nsudo awk -F= 'NF\u003C2 {print NR \": bad line -> \" $0}' \u002Fetc\u002Fdefault\u002Fmyflaskapp\nls -l \u002Fetc\u002Fdefault\u002Fmyflaskapp\n",[30,1329,1330,1344,1356],{"__ignoreMap":28},[33,1331,1332,1334,1336,1338,1340,1342],{"class":35,"line":36},[33,1333,47],{"class":46},[33,1335,159],{"class":50},[33,1337,243],{"class":60},[33,1339,162],{"class":60},[33,1341,165],{"class":50},[33,1343,168],{"class":50},[33,1345,1346,1348,1350,1352,1354],{"class":35,"line":43},[33,1347,47],{"class":46},[33,1349,570],{"class":50},[33,1351,573],{"class":60},[33,1353,576],{"class":50},[33,1355,168],{"class":50},[33,1357,1358,1360,1362],{"class":35,"line":64},[33,1359,634],{"class":46},[33,1361,637],{"class":60},[33,1363,168],{"class":50},[14,1365,1366],{},"If using Docker:",[23,1368,1370],{"className":25,"code":1369,"language":27,"meta":28,"style":28},"docker compose config\ndocker inspect \u003Ccontainer_name> | grep -A 50 '\"Env\"'\n",[30,1371,1372,1380],{"__ignoreMap":28},[33,1373,1374,1376,1378],{"class":35,"line":36},[33,1375,923],{"class":46},[33,1377,926],{"class":50},[33,1379,929],{"class":50},[33,1381,1382,1384,1387,1390,1393,1396,1399,1401,1403,1406,1409],{"class":35,"line":43},[33,1383,923],{"class":46},[33,1385,1386],{"class":50}," inspect",[33,1388,1389],{"class":304}," \u003C",[33,1391,1392],{"class":50},"container_nam",[33,1394,1395],{"class":741},"e",[33,1397,1398],{"class":304},">",[33,1400,305],{"class":304},[33,1402,159],{"class":46},[33,1404,1405],{"class":60}," -A",[33,1407,1408],{"class":60}," 50",[33,1410,1411],{"class":50}," '\"Env\"'\n",[14,1413,1414],{},"What to look for:",[385,1416,1417,1423,1429,1433,1436,1441],{},[279,1418,1419,1420,1422],{},"missing ",[30,1421,391],{}," entries",[279,1424,1425,1426,1428],{},"wrong ",[30,1427,396],{}," path",[279,1430,1425,1431],{},[30,1432,664],{},[279,1434,1435],{},"unreadable env file",[279,1437,1438,1440],{},[30,1439,1012],{}," or startup exceptions in Gunicorn logs",[279,1442,1443],{},"variables present in compose config but absent in the running container",[18,1445,1447],{"id":1446},"checklist","Checklist",[385,1449,1452,1461,1467,1479,1487,1493,1502,1508],{"className":1450},[1451],"contains-task-list",[279,1453,1456,1460],{"className":1454},[1455],"task-list-item",[1457,1458],"input",{"disabled":80,"type":1459},"checkbox"," The app is started by the runtime you expect: systemd, Docker, or Compose.",[279,1462,1464,1466],{"className":1463},[1455],[1457,1465],{"disabled":80,"type":1459}," Required variables are defined in the production startup configuration, not only in your shell profile.",[279,1468,1470,1472,1473,1475,1476,1478],{"className":1469},[1455],[1457,1471],{"disabled":80,"type":1459}," ",[30,1474,490],{}," path exists and uses valid ",[30,1477,497],{}," syntax.",[279,1480,1482,1472,1484,1486],{"className":1481},[1455],[1457,1483],{"disabled":80,"type":1459},[30,1485,664],{}," points to the correct application path.",[279,1488,1490,1492],{"className":1489},[1455],[1457,1491],{"disabled":80,"type":1459}," Gunicorn or the container has been restarted after env changes.",[279,1494,1496,1498,1499,1501],{"className":1495},[1455],[1457,1497],{"disabled":80,"type":1459}," Logs no longer show missing config or ",[30,1500,1012],{}," exceptions.",[279,1503,1505,1507],{"className":1504},[1455],[1457,1506],{"disabled":80,"type":1459}," The app can read a temporary non-secret test variable after restart.",[279,1509,1511,1513],{"className":1510},[1455],[1457,1512],{"disabled":80,"type":1459}," Secrets are stored outside the repo and with restricted permissions.",[18,1515,1517],{"id":1516},"related-guides","Related Guides",[385,1519,1520,1527,1533,1539],{},[279,1521,1522],{},[1523,1524,1526],"a",{"href":1525},"\u002Fdeploy\u002Fdeploy-flask-with-nginx-plus-gunicorn-step-by-step-guide","Deploy Flask with Nginx + Gunicorn (Step-by-Step Guide)",[279,1528,1529],{},[1523,1530,1532],{"href":1531},"\u002Fdeploy\u002Fflask-environment-variables-and-secrets-setup","Flask Environment Variables and Secrets Setup",[279,1534,1535],{},[1523,1536,1538],{"href":1537},"\u002Ffix-issues\u002Fflask-gunicorn-service-failed-to-start","Flask Gunicorn Service Failed to Start",[279,1540,1541],{},[1523,1542,1544],{"href":1543},"\u002Fchecklist\u002Fflask-production-checklist-everything-you-must-do","Flask Production Checklist (Everything You Must Do)",[18,1546,1548],{"id":1547},"faq","FAQ",[14,1550,1551,1554,1556],{},[282,1552,1553],{},"Q: Why are environment variables missing only in production?",[286,1555],{},"\nA: Production usually runs under systemd or Docker, which does not inherit your interactive shell environment.",[14,1558,1559,1565,1567,1568,1570],{},[282,1560,1561,1562,1564],{},"Q: Is ",[30,1563,262],{}," enough for Flask production?",[286,1566],{},"\nA: Not usually. Use systemd ",[30,1569,490],{}," or container environment settings for predictable production loading.",[14,1572,1573,1576,1578],{},[282,1574,1575],{},"Q: Do I need to restart Gunicorn after changing env vars?",[286,1577],{},"\nA: Yes. Restart the service or recreate the container so the new environment is applied.",[14,1580,1581,1584,1586],{},[282,1582,1583],{},"Q: Can Nginx set Flask environment variables?",[286,1585],{},"\nA: No. Nginx is a reverse proxy; the application process manager must provide env vars.",[14,1588,1589,1592,1594],{},[282,1590,1591],{},"Q: What is the safest place for production secrets?",[286,1593],{},"\nA: A protected env file outside the repo or a managed secret store, referenced by the service runtime.",[18,1596,1598],{"id":1597},"final-takeaway","Final Takeaway",[14,1600,1601],{},"This issue is usually caused by defining variables in the wrong place. Put environment variables in the same runtime that starts Gunicorn or the container, reload that runtime, and verify the active environment directly instead of assuming your shell settings apply.",[1603,1604,1605],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}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 .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":28,"searchDepth":43,"depth":43,"links":1607},[1608,1609,1610,1611,1612,1613,1614,1615,1616],{"id":20,"depth":43,"text":21},{"id":266,"depth":43,"text":267},{"id":273,"depth":43,"text":274},{"id":1080,"depth":43,"text":1081},{"id":1207,"depth":43,"text":1208},{"id":1446,"depth":43,"text":1447},{"id":1516,"depth":43,"text":1517},{"id":1547,"depth":43,"text":1548},{"id":1597,"depth":43,"text":1598},"Complete guide on flask environment variables not loading in production for Flask production environments.","md",{"ogTitle":5,"ogDescription":1617,"twitterCard":1620,"robots":1621,"canonical":1622},"summary_large_image","index, follow","https:\u002F\u002Fflask-deployment.com\u002Ffix-issues\u002Fflask-environment-variables-not-loading-in-production","\u002Ffix-issues\u002Fflask-environment-variables-not-loading-in-production",{"title":5,"description":1617},"fix-issues\u002Fflask-environment-variables-not-loading-in-production","yoqRJU52oV9_tiDy0ER7ByQe4d1UoKNC9fYfDK_leN8",1776805765932]