- Infrastructure
- Digital Solutions
Deploy Flask with Nginx on LXC: A Quick Guide
Published 4 min read

In this easy-to-follow tutorial, we’ll 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’ve 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 myuserusermod -aG sudo myuser3. Update the system, then install python3-pip and python3-venv
sudo apt updatesudo apt upgradesudo apt install python3-pipapt install python3-venv4. create a python virtual environment, and activate it:
python3 -m venv ~/env/myusersource ~/env/myuser/bin/activate5. Install Gunicorn
pip install gunicorn6. 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)
Another option, you can create a python file name as flask.py and add simple codes below:
from flask import Flaskapp = Flask(__name__)
@app.route("/")def home(): return "Hello, Flask!"7. Run the Flask web app and double check if it’s running.
python flask.pyand you may see similar results as below:
* Serving Flask app 'flask' * Debug mode: offWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://localhost:5555Press CTRL+C to quit8. Create a gunicorn web server gateway interface file- wsgi.py and put below code:
from flask import app
if __name__ == '__main__': app.run()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:
sudo nano /etc/systemd/system/flaskapp.service[Unit]Description=Guniron instance to serve Flask web appAfter=network.target
[Service]User=myuserGroup=www-dataWorkingDirectory=/home/myuser/FlaskWebAppDirectoryEnvironment="PATH=/home/myuser/env/myuser/bin"ExecStart=/home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:appRestart=always
[Install]WantedBy=multi-user.targetNote: The -w option at ExecStart specifies the number of processes to run; a starting value could be CPU * 2. 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 here
10. Enable auto start, start and check status:
sudo systemctl daemon-reloadsudo systemctl start flaskappsudo systemctl enable flaskappsudo systemctl status flaskapp* flaskapp.service - Guniron instance to serve Flask web app Loaded: loaded (/etc/systemd/system/flaskapp.service; enabled; preset: enabled) Active: active (running) since Wed 2024-01-24 05:36:29 UTC; 6min ago Main PID: 1114 (gunicorn) Tasks: 5 (limit: 38254) Memory: 209.5M CPU: 1.316s CGroup: /system.slice/flaskapp.service |-1114 /home/myuser/env/myuser/bin/python3 /home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:app |-1115 /home/myuser/env/myuser/bin/python3 /home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:app |-1116 /home/myuser/env/myuser/bin/python3 /home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:app |-1117 /home/myuser/env/myuser/bin/python3 /home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:app `-1118 /home/myuser/env/myuser/bin/python3 /home/myuser/env/myuser/bin/gunicorn -w 4 wsgi:app
Jan 24 05:36:29 FlaskApp systemd[1]: Started flaskapp.service - Guniron instance to serve Flask web app.Jan 24 05:36:29 FlaskApp gunicorn[1114]: [2024-01-24 05:36:29 +0000] [1114] [INFO] Starting gunicorn 21.2.0Jan 24 05:36:29 FlaskApp gunicorn[1114]: [2024-01-24 05:36:29 +0000] [1114] [INFO] Listening at: http://127.0.0.1:8000 (1114)Jan 24 05:36:29 FlaskApp gunicorn[1114]: [2024-01-24 05:36:29 +0000] [1114] [INFO] Using worker: syncJan 24 05:36:29 FlaskApp gunicorn[1115]: [2024-01-24 05:36:29 +0000] [1115] [INFO] Booting worker with pid: 1115Jan 24 05:36:29 FlaskApp gunicorn[1116]: [2024-01-24 05:36:29 +0000] [1116] [INFO] Booting worker with pid: 1116Jan 24 05:36:29 FlaskApp gunicorn[1117]: [2024-01-24 05:36:29 +0000] [1117] [INFO] Booting worker with pid: 1117Jan 24 05:36:29 FlaskApp gunicorn[1118]: [2024-01-24 05:36:29 +0000] [1118] [INFO] Booting worker with pid: 111811. Install Nginx:
sudo apt install nginx12. Add Flask Web App config file on Nginx:
sudo nano /etc/nginx/sites-enabled/flaskserver { listen 80;
location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}13. Unlink Nginx Default site then check the syntax:
sudo unlink /etc/nginx/sites-enabled/defaultsudo nginx -tHere is the output if test is successful:
nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successfulReload Nginx
sudo nginx -s reloadAt this point our Flask Web app is up and running via Nginx
14. Finally, we need to update the firewall rules on the server, remove unnecessary ports that allowed, check the firewall status:
sudo ufw allow "Nginx Full"sudo ufw delete allow <port-number>sudo ufw statusResult:
Status: active
To Action From-- ------ ----Nginx Full ALLOW AnywhereNginx Full (v6) ALLOW Anywhere (v6)Note: Please make sure you have added firewall rule for ssh port 22, otherwise you will lose remote connection:
sudo ufw allow 22

