{"id":7080,"date":"2024-01-24T17:13:20","date_gmt":"2024-01-24T11:13:20","guid":{"rendered":"https:\/\/10.100.1.199\/?p=7080"},"modified":"2024-01-24T22:34:15","modified_gmt":"2024-01-24T16:34:15","slug":"flask-app-with-nginx","status":"publish","type":"post","link":"https:\/\/saq-digital.com\/kk\/flask-app-with-nginx\/","title":{"rendered":"Deploy Flask with Nginx on LXC: A Quick Guide"},"content":{"rendered":"<p>In this easy-to-follow tutorial, we\u2019ll guide you through deploying a Flask web app using Nginx on an LXC Container. This container is smoothly running on ProxMox, with Ubuntu 23.04 as the chosen LXC version. We\u2019ve opted for LXC because of its lightweight nature and its impressive capability to serve our web app efficiently, even with limited server resources.<\/p>\n\n\n\n<p>1. Create a new LXC container on the ProxMox, and use Ubuntu 23.04 Standard for the container version.<\/p>\n\n\n\n<p>2. As soon as the LXC is up and running, we need to add new user:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-556df0310c3bf2ee6b3ab4f6ae097d7b\"><code>adduser myuser\nusermod -aG sudo myuser<\/code><\/pre>\n\n\n\n<p>3. Update the system, then install python3-pip and python3-venv<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-57cd70d05e23f4214605c66aef107ef8\"><code>sudo apt update\nsudo apt upgrade\nsudo apt install python3-pip\napt install python3-venv<\/code><\/pre>\n\n\n\n<p>4. create a python virtual environment, and activate it:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-75927f94d343d0dfb56a7e997f69be94\"><code>python3 -m venv ~\/env\/myuser\nsource ~\/env\/myuser\/bin\/activate  <\/code><\/pre>\n\n\n\n<p>5. Install Gunicorn<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-c333f7eb21df38c55f0c73d34e3e7524\"><code>pip install gunicorn<\/code><\/pre>\n\n\n\n<p>6. At this point I assume your Flask Web App is already created and ready to be deployed on the LXC server. Either use git clone or upload the code into server directly. Then install all dependencies of Flask web app from requirements.txt (pip3 install -r requirements.txt)<\/p>\n\n\n\n<p>Another option, you can create a python file name as flask.py and add simple codes below: <\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-7d18cf446433ce10a4e8c5ae6df2ffde\"><code>from flask import Flask\napp = Flask(__name__)\n\n@app.route(\"\/\")\ndef home():\n    return \"Hello, Flask!\"<\/code><\/pre>\n\n\n\n<p>7. Run the Flask web app and double check if it&#8217;s running. <\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-a17b368529bffd1d13cd68ab53d68e40\"><code>python flask.py <\/code><\/pre>\n\n\n\n<p>and you may see similar results as below:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-a01d059195b99a0df8a60ccd63e42706\"><code>* Serving Flask app 'flask'\n * Debug mode: off\nWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.\n * Running on http:\/\/localhost:5555\nPress CTRL+C to quit<\/code><\/pre>\n\n\n\n<p>8. Create a gunicorn web server gateway interface file- wsgi.py and put below code:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-6da443087d4359ce54779b50fc400324\"><code>from flask import app \n\nif __name__ == '__main__':\n        app.run()<\/code><\/pre>\n\n\n\n<p>9. We need a system service to serve the Gunicorn without manual interaction, idea is to make sure the web app is automatically up and running each time the server powers up. Create a flaskapp.service file and save it with below codes:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-9bebf4b6e66c0ed37352eac9e4972bfe\"><code>sudo nano \/etc\/systemd\/system\/flaskapp.service<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-8496005ffe4edfc0fa0cfad3b3769b88\"><code>&#91;Unit]\nDescription=Guniron instance to serve Flask web app\nAfter=network.target\n\n&#91;Service]\nUser=myuser\nGroup=www-data\nWorkingDirectory=\/home\/myuser\/FlaskWebAppDirectory\nEnvironment=\"PATH=\/home\/myuser\/env\/myuser\/bin\"\nExecStart=\/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app \nRestart=always\n\n&#91;Install]\nWantedBy=multi-user.target<\/code><\/pre>\n\n\n\n<p>Note: The\u00a0<code>-w<\/code>\u00a0option at ExecStart specifies the number of processes to run; a starting value could be\u00a0<code>CPU\u00a0*\u00a02<\/code>. The default is only 1 worker, which is probably not what you want for the default worker type. For more please check out Flask Official documentation <a href=\"https:\/\/flask.palletsprojects.com\/en\/3.0.x\/deploying\/gunicorn\/\" target=\"_blank\" rel=\"noopener\" title=\"\">\u0431\u0430\u0441\u044b\u04a3\u044b\u0437<\/a><\/p>\n\n\n\n<p>10. Enable auto start, start and check status:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-bc9ec5a0eeaaed5cfcd51ab2c18d5a16\"><code>sudo systemctl daemon-reload\nsudo systemctl start flaskapp\nsudo systemctl enable flaskapp\nsudo systemctl status flaskapp<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-4a591314c15cb9e26226351590ec1dda\"><code>* flaskapp.service - Guniron instance to serve Flask web app\n     Loaded: loaded (\/etc\/systemd\/system\/flaskapp.service; enabled; preset: enabled)\n     Active: active (running) since Wed 2024-01-24 05:36:29 UTC; 6min ago\n   Main PID: 1114 (gunicorn)\n      Tasks: 5 (limit: 38254)\n     Memory: 209.5M\n        CPU: 1.316s\n     CGroup: \/system.slice\/flaskapp.service\n             |-1114 \/home\/myuser\/env\/myuser\/bin\/python3 \/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app\n             |-1115 \/home\/myuser\/env\/myuser\/bin\/python3 \/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app\n             |-1116 \/home\/myuser\/env\/myuser\/bin\/python3 \/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app\n             |-1117 \/home\/myuser\/env\/myuser\/bin\/python3 \/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app\n             `-1118 \/home\/myuser\/env\/myuser\/bin\/python3 \/home\/myuser\/env\/myuser\/bin\/gunicorn -w 4 wsgi:app\n\nJan 24 05:36:29 FlaskApp systemd&#91;1]: Started flaskapp.service - Guniron instance to serve Flask web app.\nJan 24 05:36:29 FlaskApp gunicorn&#91;1114]: &#91;2024-01-24 05:36:29 +0000] &#91;1114] &#91;INFO] Starting gunicorn 21.2.0\nJan 24 05:36:29 FlaskApp gunicorn&#91;1114]: &#91;2024-01-24 05:36:29 +0000] &#91;1114] &#91;INFO] Listening at: http:\/\/127.0.0.1:8000 (1114)\nJan 24 05:36:29 FlaskApp gunicorn&#91;1114]: &#91;2024-01-24 05:36:29 +0000] &#91;1114] &#91;INFO] Using worker: sync\nJan 24 05:36:29 FlaskApp gunicorn&#91;1115]: &#91;2024-01-24 05:36:29 +0000] &#91;1115] &#91;INFO] Booting worker with pid: 1115\nJan 24 05:36:29 FlaskApp gunicorn&#91;1116]: &#91;2024-01-24 05:36:29 +0000] &#91;1116] &#91;INFO] Booting worker with pid: 1116\nJan 24 05:36:29 FlaskApp gunicorn&#91;1117]: &#91;2024-01-24 05:36:29 +0000] &#91;1117] &#91;INFO] Booting worker with pid: 1117\nJan 24 05:36:29 FlaskApp gunicorn&#91;1118]: &#91;2024-01-24 05:36:29 +0000] &#91;1118] &#91;INFO] Booting worker with pid: 1118<\/code><\/pre>\n\n\n\n<p>11. Install Nginx:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-dfaa835c808f2aa2df135a770ca3bcfc\"><code>sudo apt install nginx<\/code><\/pre>\n\n\n\n<p>12. Add Flask Web App config file on Nginx:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-6b383d7698c5305dab52f3d3157040ff\"><code>sudo nano \/etc\/nginx\/sites-enabled\/flask<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-44f65c580e091e9a630be23721c1965c\"><code>server {\n        listen 80;\n\n        location \/ {\n                proxy_pass http:\/\/127.0.0.1:8000;\n                proxy_set_header Host $host;\n                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        }\n}<\/code><\/pre>\n\n\n\n<p>13. Unlink Nginx Default site then check the syntax:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-801cf5a462c5b2648b0367e787922909\"><code>sudo unlink \/etc\/nginx\/sites-enabled\/default\nsudo nginx -t<\/code><\/pre>\n\n\n\n<p>Here is the output if test is successful:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-45df53ba399d9924b98eaf865cf0bc0d\"><code>nginx: the configuration file \/etc\/nginx\/nginx.conf syntax is ok\nnginx: configuration file \/etc\/nginx\/nginx.conf test is successful\n<\/code><\/pre>\n\n\n\n<p>Reload Nginx<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-a890294bc68d09a87b98fa0dee773073\"><code>sudo nginx -s reload<\/code><\/pre>\n\n\n\n<p>At this point our Flask Web app is up and running via Nginx<\/p>\n\n\n\n<p>14. Finally, we need to update the firewall rules on the server, remove unnecessary ports that allowed, check the firewall status:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-49ec05557f7477feeee4fa30722468cd\"><code>sudo ufw allow \"Nginx Full\"\nsudo ufw delete allow &lt;port-number&gt;\nsudo ufw status<\/code><\/pre>\n\n\n\n<p>Result:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-8ec438579c932f23df7a3555ea34c889\"><code>Status: active\n\nTo                         Action      From\n--                         ------      ----\nNginx Full                 ALLOW       Anywhere\nNginx Full (v6)            ALLOW       Anywhere (v6)<\/code><\/pre>\n\n\n\n<p>Note: Please make sure you have added firewall rule for ssh port 22, otherwise you will lose remote connection:<\/p>\n\n\n\n<pre class=\"wp-block-code has-palette-color-6-color has-palette-color-4-background-color has-text-color has-background has-link-color wp-elements-407b005af2abffc59bb5c56d372fb308\"><code>sudo ufw allow 22<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>In this easy-to-follow tutorial, we\u2019ll guide you through deploying a Flask web app using Nginx on an LXC Container. This container is smoothly running on ProxMox, with Ubuntu 23.04 as the chosen LXC version. We\u2019ve opted for LXC because of its lightweight nature and its impressive capability to serve our web app efficiently, even with [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[128,105,158],"tags":[159,163,161,164,162,160],"class_list":["post-7080","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-proxmox","category-servers","category-web-app","tag-flask","tag-gunicorn","tag-lxc","tag-nginx","tag-python","tag-webapp"],"blocksy_meta":{"has_hero_section":"default","styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"aioseo_notices":[],"featured_image_urls_v2":{"full":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox.jpg",1920,1280,false],"thumbnail":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-150x150.jpg",150,150,true],"medium":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-300x200.jpg",300,200,true],"medium_large":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-768x512.jpg",768,512,true],"large":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-1024x683.jpg",1024,683,true],"1536x1536":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-1536x1024.jpg",1536,1024,true],"2048x2048":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox.jpg",1920,1280,false],"trp-custom-language-flag":["https:\/\/saq-digital.com\/wp-content\/uploads\/2024\/01\/saq-flask-web-app-nginx-ProxMox-18x12.jpg",18,12,true]},"post_excerpt_stackable_v2":"<p>In this easy-to-follow tutorial, we\u2019ll guide you through deploying a Flask web app using Nginx on an LXC Container. This container is smoothly running on ProxMox, with Ubuntu 23.04 as the chosen LXC version. We\u2019ve opted for LXC because of its lightweight nature and its impressive capability to serve our web app efficiently, even with limited server resources. 1. Create a new LXC container on the ProxMox, and use Ubuntu 23.04 Standard for the container version. 2. As soon as the LXC is up and running, we need to add new user: adduser myuser usermod -aG sudo myuser 3. Update&hellip;<\/p>\n","category_list_v2":"<a href=\"https:\/\/saq-digital.com\/kk\/category\/infrastructure\/virtualization\/proxmox\/\" rel=\"category tag\">ProxMox<\/a>, <a href=\"https:\/\/saq-digital.com\/kk\/category\/infrastructure\/servers\/\" rel=\"category tag\">Servers<\/a>, <a href=\"https:\/\/saq-digital.com\/kk\/category\/digital-solutions\/web-app\/\" rel=\"category tag\">Web App<\/a>","author_info_v2":{"name":"SAQ","url":"https:\/\/saq-digital.com\/kk\/author\/serik-akim\/"},"comments_num_v2":"0 comments","brizy_media":[],"_links":{"self":[{"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/posts\/7080","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/comments?post=7080"}],"version-history":[{"count":5,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/posts\/7080\/revisions"}],"predecessor-version":[{"id":7090,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/posts\/7080\/revisions\/7090"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/media\/7092"}],"wp:attachment":[{"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/media?parent=7080"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/categories?post=7080"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/saq-digital.com\/kk\/wp-json\/wp\/v2\/tags?post=7080"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}