Flask Deploying on Linux Server

Deploying Flask on a Linux server (like a VPS from DigitalOcean, Linode, or AWS EC2) gives you full control over your environment. The production stack uses Nginx as the web server and Gunicorn as the WSGI server, with your Flask app running between them.

The Production Stack

Internet
   │
   ▼
Nginx  (port 80/443)
   │   ── handles static files directly
   │   ── handles SSL/HTTPS
   │   ── passes dynamic requests to Gunicorn
   ▼
Gunicorn  (port 8000, internal only)
   │   ── manages multiple worker processes
   │   ── passes requests to Flask
   ▼
Flask Application
   │   ── processes the request
   │   ── returns the response
   ▼
Gunicorn → Nginx → Browser

Step 1: Set Up the Server

# SSH into your server
ssh root@your-server-ip

# Update the system
apt update && apt upgrade -y

# Install required packages
apt install python3 python3-pip python3-venv nginx git -y

Step 2: Upload Your App

# Clone from GitHub (recommended)
git clone https://github.com/yourusername/yourapp.git /var/www/yourapp

# Or copy files with scp from your computer
scp -r ./myapp root@your-server-ip:/var/www/yourapp

Step 3: Set Up the Virtual Environment

cd /var/www/yourapp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn

Step 4: Create the .env File

nano /var/www/yourapp/.env

Add your environment variables:

SECRET_KEY=your-super-secret-production-key
DATABASE_URL=postgresql://user:password@localhost/myapp
FLASK_ENV=production

Set permissions so only the server user can read it:

chmod 600 /var/www/yourapp/.env

Step 5: Run Database Migrations

cd /var/www/yourapp
source venv/bin/activate
flask db upgrade

Step 6: Test Gunicorn Manually

gunicorn --bind 0.0.0.0:8000 run:app

Visit http://your-server-ip:8000 to confirm the app runs. Press Ctrl+C to stop.

Step 7: Create a Systemd Service

A systemd service starts Gunicorn automatically when the server boots and restarts it if it crashes:

nano /etc/systemd/system/yourapp.service
[Unit]
Description=Gunicorn instance for Flask app
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/yourapp
Environment="PATH=/var/www/yourapp/venv/bin"
EnvironmentFile=/var/www/yourapp/.env
ExecStart=/var/www/yourapp/venv/bin/gunicorn \
          --workers 3 \
          --bind unix:/var/www/yourapp/yourapp.sock \
          run:app

[Install]
WantedBy=multi-user.target
# Enable and start the service
systemctl daemon-reload
systemctl enable yourapp
systemctl start yourapp
systemctl status yourapp

Step 8: Configure Nginx

nano /etc/nginx/sites-available/yourapp
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location /static/ {
        alias /var/www/yourapp/app/static/;
        expires 30d;
    }

    location / {
        proxy_pass http://unix:/var/www/yourapp/yourapp.sock;
        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;
    }
}
# Enable the site
ln -s /etc/nginx/sites-available/yourapp /etc/nginx/sites-enabled/
nginx -t         # test configuration syntax
systemctl restart nginx

Step 9: Enable HTTPS with Certbot

apt install certbot python3-certbot-nginx -y
certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot installs a free SSL certificate from Let's Encrypt and configures Nginx to use it automatically. Certificates renew automatically every 90 days.

Deployment Update Workflow

# Pull latest code
cd /var/www/yourapp
git pull origin main

# Activate venv and install new dependencies
source venv/bin/activate
pip install -r requirements.txt

# Run migrations if models changed
flask db upgrade

# Restart Gunicorn to load new code
systemctl restart yourapp

Summary

A production Linux deployment uses Nginx to handle incoming traffic and serve static files, Gunicorn to run multiple Flask worker processes, and systemd to keep Gunicorn running across reboots. Nginx passes dynamic requests to Gunicorn through a Unix socket. Certbot adds free HTTPS in one command. This stack handles thousands of concurrent users and is the standard deployment pattern for Flask applications worldwide.

Leave a Comment

Your email address will not be published. Required fields are marked *