Deploy Flask Web App- Set up Apache as a reverse proxy to Gunicorn

Deploying a Flask app to a Fedora Linux server involves several steps to ensure your app runs smoothly and securely. Here’s a step-by-step guide:

Step-by-Step Guide to Deploy a Flask App to Fedora Linux Server

  1. Set Up Your Fedora Server: Ensure your server is up-to-date and has Python installed. You can update your server and install Python with the following commands: sudo dnf update sudo dnf install python3 python3-venv
  2. Create a Virtual Environment: Set up a virtual environment to manage your project’s dependencies: python3 -m venv myenv source myenv/bin/activate
  3. Install Flask and Gunicorn: Install Flask and Gunicorn within your virtual environment: pip install Flask gunicorn
  4. Create Your Flask App: Develop your Flask application and save it in a directory (e.g., myapp). Here’s a simple example (app.py):
    from flask import

    Flask app = Flask(__name__)

    @app.route('/')
    def home():
    return "Hello, World!"

    if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000)
  5. Test Your Flask App Locally: Before deploying, test your app locally to ensure it works: python app.py Access your app at http://localhost:5000.
  6. Set Up Gunicorn: Configure Gunicorn to serve your Flask app:

    gunicorn --bind 127.0.0.1:5000 app:app

    Replace app:app with module_name:class_name if your app is structured differently.
    module_name is the python file which will act as the entry point for the web app in this example it is app.py so the module_name is app
    class_name : is the class that references a flask instance . In this example you can see
    Flask app = Flask(__name__) ” , so the class_name is app .
  7. Deploy Your App: Transfer your Flask app to the server and run it with Gunicorn:
    if your source code is checked in to git , then use the following , else copy the source files to a directory on a server . The following is the example with git .
    git clone https://your_repository_url.git
    cd your_repository_directory
    #activate virtual environment
    source myenv/bin/activate
    # run the app to verify if gunicorn is serving the web app by doing the following :
    sudo gunicorn --bind 127.0.0.1:5000 app:app
    Open your web browser and navigate to http://localhost:5000. to see your Flask app running on the Fedora server.

Now in production deployments we need to ensure that the app is accessible through a url , so we can do that by setting up a reverse proxy . This setup uses Apache as a reverse proxy and Gunicorn as the WSGI server to serve your Flask app. The steps are described below :

Using Apache as a Reverse Proxy to Gunicorn in Fedora Linux(same applies for other distros too)

Create a system d service

Create a system d service for gunicorn so that it runs continuously in the back ground listening to the port of your web app .
For example Create a systemd service file for Gunicorn, for example, /etc/systemd/system/myapp.service

Example systemd Service File for Gunicorn:

```ini
[Unit]
Description=Gunicorn instance to serve my Flask app
After=network.target

[Service]
User=flaskuser
Group=flaskgroup
WorkingDirectory=/var/www/myproject
Environment="PATH=/var/www/myproject/myenv/bin"
ExecStart=/var/www/myproject/myenv/bin/gunicorn --workers 3 --bind 127.0.0.1:5000 app:app

[Install]
WantedBy=multi-user.target
```
Reload systemd and Start the Gunicorn Service:
sudo systemctl daemon-reload
sudo systemctl start myapp.service
sudo systemctl enable myapp.service

Configure Reverse Proxy in Apache web server

  1. Install Apache2: If you haven’t installed Apache2 yet, you can do so with the following command:
    bash sudo apt install apache2
  2. Enable Necessary Apache Modules: Enable the required Apache modules for proxying HTTP requests.
    sudo a2enmod proxy
    sudo a2enmod proxy_http
    sudo a2enmod headers
    sudo a2enmod deflate
  3. Create a Virtual Host Configuration: Create or edit your Apache virtual host configuration file. For example, create a configuration file named myapp.conf in the /etc/apache2/sites-available/ directory.
    sudo vi /etc/apache2/sites-available/myapp.conf
    Add the following configuration . Let us say we use port 8035 which inturn routes the traffic to port 8000 where the gunicorn serves the web app
    <VirtualHost *:8035>
    ServerName myhobby.com
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/
    ErrorLog ${APACHE_LOG_DIR}/myapp_error.log CustomLog ${APACHE_LOG_DIR}/myapp_access.log combined
    </VirtualHost>
    This configuration will forward requests from myhobby.com to the Gunicorn server running on http://127.0.0.1:8000.
  4. Enable the Site Configuration: Enable your new site configuration and disable the default site configuration if necessary.
    sudo a2ensite myapp.conf
    sudo a2dissite 000-default.conf (if we are using port 80 used by default conf)
  5. Restart Apache: Restart Apache to apply the new configuration.
    sudo systemctl restart apache2
  6. Reload Apache: Restart Apache to apply the new configuration.
    sudo systemctl restart httpd
  7. Verify the app : Ensure your Flask app is running by opening a browser session with url
    http://localhost : 8035/. This should display a web page with hello world.

By setting up Apache as a reverse proxy to Gunicorn, Apache will handle incoming HTTP requests, pass them to Gunicorn, and then return the responses to the clients. This setup allows you to leverage Apache’s robust features while efficiently serving your Flask application with Gunicorn.