杰瑞科技汇

CentOS下Nginx如何部署Python应用?

Of course! This is a very common and powerful stack for building web applications and services. Here is a comprehensive guide covering the setup, configuration, and best practices for using Nginx as a reverse proxy for Python applications on CentOS.

CentOS下Nginx如何部署Python应用?-图1
(图片来源网络,侵删)

We will cover two popular Python scenarios:

  1. A Simple WSGI App (using Gunicorn as the application server).
  2. A FastAPI App (a modern, high-performance framework).

Overview: The Role of Each Component

  • CentOS: The operating system. It provides a stable and secure foundation.
  • Nginx (Engine-X): A high-performance, reverse proxy web server. It will:
    • Listen for public HTTP/HTTPS traffic on ports 80 and 443.
    • Serve static files (CSS, JavaScript, images) directly and very quickly.
    • Act as a reverse proxy, forwarding dynamic requests (for your Python app) to the application server.
    • Handle SSL/TLS certificate termination for HTTPS.
    • Provide load balancing and caching.
  • Python Application: Your web application code (e.g., a Flask or FastAPI app). It cannot directly listen on a public port and is not optimized for serving static files.
  • Application Server (e.g., Gunicorn, Uvicorn): A piece of software that runs your Python application code, listens on a local network port (e.g., 127.0.0.1:8000), and communicates with Nginx.

Part 1: System Preparation and Installation

First, let's set up a fresh CentOS server and install the necessary dependencies.

Update Your System

sudo dnf update -y

Install EPEL Repository

The Extra Packages for Enterprise Linux (EPEL) repository contains many useful packages not included in the default CentOS repos.

sudo dnf install -y epel-release

Install Nginx

sudo dnf install -y nginx

Start and enable Nginx to run on boot:

CentOS下Nginx如何部署Python应用?-图2
(图片来源网络,侵删)
sudo systemctl start nginx
sudo systemctl enable nginx

Check its status:

sudo systemctl status nginx

You can now test your Nginx installation by navigating to your server's IP address in a web browser. You should see the "Welcome to Nginx!" page.

Install Python and a Virtual Environment Tool

It's a best practice to use Python virtual environments to isolate project dependencies.

sudo dnf install -y python3 python3-pip

Install virtualenv, a popular tool for creating isolated environments.

sudo pip3 install virtualenv

Install FirewallD

Ensure your firewall is configured to allow HTTP and HTTPS traffic.

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Part 2: Creating a Sample Python Application

Let's create a simple "Hello World" application to demonstrate the setup. We'll use a generic WSGI interface, which works for Flask, Django, and other frameworks.

Create Project Directory

mkdir ~/my_python_app
cd ~/my_python_app

Set Up a Virtual Environment

virtualenv venv
source venv/bin/activate

Your shell prompt should now change to show (venv).

Install an Application Server (Gunicorn)

Gunicorn is a robust WSGI HTTP Server for UNIX. It's a great choice for running Python web apps.

pip install gunicorn

Create the Python App File

Create a file named app.py:

nano app.py

Paste the following code into the file. This is a minimal WSGI application.

def application(environ, start_response):
    """A simple WSGI application."""
    status = '200 OK'
    output = b'Hello from Python and Nginx!\n'
    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output]

Save and exit (Ctrl+X, then Y, then Enter).

Test the Application Locally

Before involving Nginx, let's test if Gunicorn can run our app.

# Run Gunicorn, binding it to port 8000 on localhost
gunicorn --bind 127.0.0.1:8000 app:application

You should see output from Gunicorn indicating it's running. Visit http://YOUR_SERVER_IP:8000 in your browser. You should see "Hello from Python and Nginx!". To stop Gunicorn, press Ctrl+C.


Part 3: Configuring Nginx as a Reverse Proxy

Now, we'll tell Nginx how to forward requests to our Gunicorn application.

Create a Nginx Configuration File

It's best practice to create a new configuration file for your app instead of modifying the default one.

sudo nano /etc/nginx/conf.d/my_python_app.conf

Add the Following Configuration

Paste this configuration into the file. The comments explain each part.

server {
    listen 80;
    server_name YOUR_SERVER_IP; # Or your domain name if you have one
    # Path to your project's static files
    # It's good practice to serve static files directly with Nginx
    location /static/ {
        alias /home/your_username/my_python_app/static/;
        expires 30d; # Cache static files for 30 days
    }
    # This is the main block for proxying requests to the app
    location / {
        # Pass the request to the Gunicorn server
        proxy_pass http://127.0.0.1:8000;
        # Set headers to properly pass the client information to the app
        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;
    }
}

Important: Replace your_username with your actual CentOS username.

Test and Reload Nginx

Test your Nginx configuration for syntax errors:

sudo nginx -t

If it reports syntax is ok and test is successful, reload Nginx to apply the changes:

sudo systemctl reload nginx

Run the Application Server

Now, start Gunicorn in the background. We'll use nohup to keep it running even after you log out of the SSH session.

# Make sure you are in your project directory and venv is active
cd ~/my_python_app
source venv/bin/activate
nohup gunicorn --bind 127.0.0.1:8000 app:application > /dev/null 2>&1 &

You can now visit http://YOUR_SERVER_IP in your browser. Nginx will receive the request and forward it to Gunicorn, which will return the "Hello from Python and Nginx!" message.


Part 4: Managing the Application with Systemd (Recommended)

Running your app with nohup is not ideal. The modern way to manage services on CentOS is with systemd. It will automatically start your app on boot and restart it if it crashes.

Create a systemd Service File

sudo nano /etc/systemd/system/my_python_app.service

Add the Following Service Definition

[Unit]
Description=Gunicorn instance to serve my_python_app
After=network.target
[Service]
User=your_username
Group=your_username
WorkingDirectory=/home/your_username/my_python_app
Environment="PATH=/home/your_username/my_python_app/venv/bin"
ExecStart=/home/your_username/my_python_app/venv/bin/gunicorn --bind 127.0.0.1:8000 app:application
[Install]
WantedBy=multi-user.target

Important:

  • Replace your_username with your actual username.
  • WorkingDirectory must be your project's root directory.
  • Environment points to the gunicorn executable inside your virtual environment.
  • ExecStart is the exact command to run your app.

Manage the Service

Now you can use standard systemctl commands to manage your application.

  • Start the service:
    sudo systemctl start my_python_app
  • Enable the service to start on boot:
    sudo systemctl enable my_python_app
  • Check the status of the service:
    sudo systemctl status my_python_app
  • View application logs:
    journalctl -u my_python_app -f
  • Restart the service:
    sudo systemctl restart my_python_app

Part 5: Example with FastAPI

The process is almost identical for a modern framework like FastAPI.

Create a FastAPI App

In your project directory (~/my_python_app), create main.py:

nano main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
    return {"Hello": "World from FastAPI!"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

Install Uvicorn

FastAPI works best with an ASGI server like Uvicorn.

pip install "uvicorn[standard]"

Update the systemd Service

Edit /etc/systemd/system/my_python_app.service and change the ExecStart line:

# ...
ExecStart=/home/your_username/my_python_app/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 --reload
# ...
  • main:app tells Uvicorn to look for an object named app in the file main.py.
  • --reload is great for development as it automatically restarts the server when you change the code. You should remove it for production.

Restart the Service

sudo systemctl daemon-reload
sudo systemctl restart my_python_app

Now, when you visit http://YOUR_SERVER_IP/docs, you will see the interactive API documentation provided by FastAPI. Nginx is still proxying all requests to Uvicorn.

分享:
扫描分享到社交APP
上一篇
下一篇