Prepare Your Ubuntu Server (Work)
1. Update the System
Start by updating the system packages:
Run:
sudo apt update && sudo apt upgrade -y
Install Python and Dependencies
If you don’t already have Python 3 installed, you can install it along with pip:
Run:
sudo apt install python3 python3-pip python3-venv -y
Install Git (if you’re using version control)
Run:
sudo apt install git -y
2. Clone Your Flask Application
If you have your Flask app stored in a Git repository, clone it to your server:
Run:
sudo mkdir /var/flask/
cd /var/flask/
sudo git clone https://github.com/hatted/quizzizz02.git flask-quiz-app
Output:
Cloning into 'flask-quiz-app'...
remote: Enumerating objects: 101, done.
remote: Counting objects: 100% (101/101), done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 101 (delta 39), reused 101 (delta 39), pack-reused 0 (from 0)
Receiving objects: 100% (101/101), 695.59 KiB | 4.55 MiB/s, done.
Resolving deltas: 100% (39/39), done.
If you’re transferring files manually, you can use scp (Secure Copy) or any other method to move your files into the /var/www/ directory.
3. Set Up a Virtual Environment
Navigate to your app directory: Run:
cd /var/flask/flask-quiz-app
Create a virtual environment for your app:
Run:
sudo python3 -m venv venv
Activate the virtual environment:
Run:
source venv/bin/activate
4. Install the Requirements
Make sure your requirements.txt file is in the project directory. Then, install all the dependencies:
Run:
pip install -r requirements.txt
If you haven’t generated a requirements.txt file, you can do so using the following command:
Run:
pip freeze > requirements.txt
Test your app locally:
python app.py
or if you’re using Flask’s built-in runner:
flask run
Test web by another terminal:
Run:
curl http://127.0.0.1:5000
Output:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>quizz - quizz</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<h1></h1>
<!-- Bootstrap JS and dependencies (Popper.js, Bootstrap JS) -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="/static/js/bootstrap.bundle.min.js"></script>
</body>
Quit app.
Run:
Ctrl+C
5. Configure the Database (SQLite)
If your app uses SQLite, you don’t need to worry about setting up a server; SQLite will automatically create the database file. Just make sure the database is placed in a directory that your Flask app can access.
6. Install Gunicorn
Install Gunicorn in your virtual environment to serve the Flask app:
Run:
pip install gunicorn
Test Gunicorn by running your app:
Run:
gunicorn -w 4 -b 0.0.0.0:8080 run:app
This will run the app with 4 worker processes (-w 4) [recommend (2 * number_of_cores) + 1] and bind it to port 8080 (-b 0.0.0.0:8080).
run:app is the run.py file that contains your Flask app instance. EG.
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
Visit http://your-server-ip:8080 to confirm it works.
7. Install Nginx
Nginx will act as a reverse proxy server, forwarding requests to Gunicorn. Install Nginx:
Run:
sudo apt install nginx -y
Output:
[...]
Enabling conf security.
Enabling conf serve-cgi-bin.
Enabling site 000-default.
[...]
Once installed, you can start Nginx:
Run:
sudo systemctl start nginx
Make sure Nginx is enabled to start on boot:
Run:
sudo systemctl enable nginx
8. Configure Nginx as Reverse Proxy
Create a new Nginx configuration file for your app:
Run:
sudo vi /etc/nginx/sites-available/flask-quiz-app
📓 [!NOTE] Use your server’s domain or IP address
Add the following configuration to proxy requests to Gunicorn:
server {
listen 80;
server_name **your_domain_or_ip**;
# Use your server's domain or IP address
location / {
proxy_pass http://127.0.0.1:5000;
# Gunicorn will be running on port 5000
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Optional: Handle static files (e.g., images, CSS)
#location /static/ {
# alias /var/www/flask-quiz-app/static/;
#}
}
Enable the site by creating a symbolic link to the sites-enabled directory:
Run:
sudo ln -s /etc/nginx/sites-available/flask-quiz-app /etc/nginx/sites-enabled
Then, check the Nginx configuration for syntax errors:
Run:
sudo nginx -t
Output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
If everything is okay, restart Nginx to apply the changes:
Run:
sudo systemctl restart nginx
9. Set Up Gunicorn as a Service
To make sure Gunicorn runs as a service and starts on boot, create a systemd service file.
Create the Gunicorn service file:
Run:
sudo vi /etc/systemd/system/flask-quiz-app.service
Add the following content:
[Unit]
Description=Flask Quiz App
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/flask/flask-quiz-app
Environment="PATH=/var/flask/flask-quiz-app/venv/bin"
ExecStart=/var/flask/flask-quiz-app/venv/bin/gunicorn -w 4 -b 127.0.0.1:8080 run:app
ExecStart=/var/flask/flask-quiz-app/venv/bin/gunicorn -w 4 -b unix:flask-quiz-app.sock run:app
[Install]
WantedBy=multi-user.target
Reload systemd to recognize the new service:
Run:
sudo systemctl daemon-reload
Start and enable the Gunicorn service:
Run:
sudo systemctl start flask-quiz-app
sudo systemctl enable flask-quiz-app
sudo systemctl restart flask-quiz-app
Restart server
reboot
You can check the status of the Gunicorn service:
Run:
sudo systemctl status flask-quiz-app
9.1 restart after reboot
cd /var/flask/flask_uid/
source venv/bin/activate
gunicorn -w 4 -b 0.0.0.0:8080 run:app
open http://your-server-ip:8080 to confirm it works. then open http://your_domain_or_ip to confirm it works.
10. Adjust Firewall Settings (if necessary)
If you’re using ufw (Uncomplicated Firewall), allow traffic on HTTP port (80):
Run:
sudo ufw allow 'Nginx Full'
sudo ufw enable
11. Access Your App
Your Flask app should now be accessible through your server’s IP or domain name. Open a browser and go to:
http://your_domain_or_ip
Summary of the Steps:
- Update and install system dependencies.
- Clone your Flask app to the server.
- Set up a virtual environment and install dependencies.
- Install Gunicorn to serve your Flask app.
- Configure Nginx as a reverse proxy.
- Set up Gunicorn to run as a service using systemd.
- Allow traffic through the firewall.
- Access your app in the browser.
extra
Install and Configure Supervisor
Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems. Supervisor can handle auto-reloading Gunicorn if it crashes or if the Linode is rebooted unexpectedly.
Install Supervisor:
Run:
sudo apt install supervisor
Create a Supervisor script. Replace any instances of flask_app with the name of the application:
Run:
sudo nano /etc/supervisor/conf.d/flask_app.conf
Output:
File: /etc/supervisor/conf.d/flask_app.conf
[program:flask_app]
directory=/home/flask_app_project
command=gunicorn3 --workers=3 flask_app:app
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/flask_app/flask_app.err.log
stdout_logfile=/var/log/flask_app/flask_app.out.log
Create the log directories and files listed in the flask_app.conf file. Make sure to replace flask_app if it was modified in the Supervisor script above:
Run:
sudo mkdir /var/log/flask_app
sudo touch /var/log/flask_app/flask_app.out.log
sudo touch /var/log/flask_app/flask_app.err.log
Reload Supervisor to apply the changes:
Run:
sudo supervisorctl reload
Output:
Restarted supervisord
The application should now be accessible again through the IP address of the Linode. If you are unable to access the application or receive a bad gateway error, Gunicorn is likely not running. Check the log files to further investigate the issue.
Run:
cat /var/log/flask_app/flask_app.err.log
cat /var/log/flask_app/flask_app.out.log
Output:
The Flask application is now deployed to the production environment and available to anyone for viewing. You can follow a similar workflow to deploy any Flask application to a Linode.
set hostname
Run:
sudo hostnamectl set-hostname domain.com
hostname -f
install Let’s Encrypt
Run:
sudo apt-get install snapd
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo apt-get install certbot
sudo apt-get install python3-certbot
sudo apt-get install python3-certbot-apache
