杰瑞科技汇

Python、Nginx、Django 如何协同工作?

Of course! This is a classic and powerful stack for building web applications. Let's break down what each component does, why you use them together, and then walk through a complete setup.

Python、Nginx、Django 如何协同工作?-图1
(图片来源网络,侵删)

The Big Picture: Why This Stack?

Think of building a web application as running a restaurant.

  • Python/Django: This is the head chef and the kitchen. Django is a "batteries-included" framework for Python. It handles the core logic: taking orders (requests), figuring out what the customer wants (URL routing), preparing the food (business logic, database interactions), and plating it (rendering HTML). It's incredibly efficient at what it does, but it's not designed to handle hundreds of customers waiting at the door.
  • Nginx (pronounced "Engine-X"): This is the Maître d' and the host. Its primary job is to manage incoming traffic (customers). It stands at the door, greets everyone, and takes their orders. It's fantastic at serving static content quickly (like handing out menus, wine lists, and desserts). It can also handle SSL/TLS encryption (taking payments securely) and load balancing (sending customers to different sections of the restaurant).
  • uWSGI or Gunicorn: This is the expediter between the Maître d' and the kitchen. Nginx can't talk directly to Django. The uWSGI/Gunicorn server acts as a bridge. Nginx receives the request, passes it to the uWSGI/Gunicorn server, which then wakes up a "worker" (a chef) in the Django kitchen to do the work. Once the chef is done, the response goes back through the expediter to the Maître d', who then gives it to the customer.

This separation of concerns is key:

  • Nginx handles the high-performance, static tasks and acts as a reverse proxy.
  • uWSGI/Gunicorn manages the Python processes.
  • Django focuses on the application logic.

This architecture is highly scalable, secure, and performant.


Core Concepts

  • Reverse Proxy: Nginx is a reverse proxy for Django. This means that from the outside world, all traffic goes to Nginx. Nginx then decides what to do with it. For dynamic content (like a request from a logged-in user), it forwards the request to the Django/uWSGI server. For static content (like CSS, JS, images), it serves them directly without bothering Django. This is much faster.
  • Static Files: These are files that don't change often: CSS, JavaScript, images, fonts. By default, Django serves them, which is inefficient for production. Nginx is optimized to serve these files extremely quickly.
  • uWSGI vs. Gunicorn: Both are application servers that run your Django code and communicate with Nginx.
    • Gunicorn: Simpler, easier to set up, and very popular. A great starting point.
    • uWSGI: More feature-rich and configurable (better for complex deployments, multiple Python versions, etc.). Can be more complex to configure.

For this guide, we'll use Gunicorn as it's the most common and straightforward choice.

Python、Nginx、Django 如何协同工作?-图2
(图片来源网络,侵删)

Step-by-Step Setup Guide (Linux/macOS)

This guide assumes you have a fresh server with Python and pip installed.

Step 1: Project Setup

Let's create a sample Django project.

# 1. Create a virtual environment (highly recommended)
python3 -m venv myprojectenv
source myprojectenv/bin/activate
# 2. Install Django and Gunicorn
pip install django gunicorn
# 3. Create a new Django project
django-admin startproject myproject
cd myproject
# 4. Create a simple app to have something to serve
python manage.py startapp hello

Step 2: Configure Django

We need to tell Django where to find its static files.

  1. Edit myproject/settings.py: Add your new app to INSTALLED_APPS:

    Python、Nginx、Django 如何协同工作?-图3
    (图片来源网络,侵删)
    # myproject/settings.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'hello',  # Add your new app here
    ]
  2. Define STATIC_ROOT: This tells Django to collect all static files into one directory for Nginx to serve.

    # myproject/settings.py
    # ... at the bottom of the file
    STATIC_URL = 'static/'
    STATIC_ROOT = BASE_DIR / 'staticfiles' # Add this line
  3. Create a view in hello/views.py:

    # hello/views.py
    from django.http import HttpResponse
    def home(request):
        return HttpResponse("Hello from Django! Nginx is serving me.")
  4. Create a URL in myproject/urls.py:

    # myproject/urls.py
    from django.contrib import admin
    from django.urls import path, include # Add include
    from hello.views import home # Add home view
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', home, name='home'), # Add a root URL
    ]
  5. Collect static files:

    python manage.py collectstatic

    This will create a staticfiles directory in your project root.

Step 3: Test Gunicorn

Before involving Nginx, let's make sure Gunicorn can run our project.

# The command format is: gunicorn <project_name>.wsgi:application
gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
  • myproject.wsgi:application tells Gunicorn to look for the application variable inside the myproject/wsgi.py file.
  • --bind 0.0.0.0:8000 makes the server accessible on your machine's IP address on port 8000.

You should see output indicating it's running. If you visit http://<your_server_ip>:8000 in your browser, you should see "Hello from Django! Nginx is serving me." Press Ctrl+C to stop it.

Step 4: Configure Nginx

Now, let's set up Nginx to act as a reverse proxy.

  1. Create an Nginx configuration file for your project.

    sudo nano /etc/nginx/sites-available/myproject
  2. Add the following configuration:

    server {
        listen 80;
        server_name your_domain.com www.your_domain.com; # Replace with your domain or IP
        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/user/myproject; # <-- IMPORTANT: Change this to your project's absolute path
        }
        location / {
            include proxy_params;
            proxy_pass http://unix:/run/gunicorn.sock; # <-- We will use a socket file
        }
    }
    • listen 80;: Listens for standard HTTP traffic.
    • server_name: Your domain name.
    • location /static/: Tells Nginx to look for files in the /static/ URL path and serve them from the root you defined. This is where your collected static files are.
    • location /: This is the catch-all for all other requests. It includes standard proxy settings and passes the request to Gunicorn. We're using a Unix socket (/run/gunicorn.sock) which is more efficient than a network port (localhost:8000) on the same machine.
  3. Enable the site:

    # Create a symbolic link from sites-available to sites-enabled
    sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
    # Test the Nginx configuration for syntax errors
    sudo nginx -t
    # If the test is successful, reload Nginx to apply the changes
    sudo systemctl reload nginx

Step 5: Create a Gunicorn Systemd Service

We want Gunicorn to start automatically when the server boots and to run in the background. A systemd service is the best way to do this.

  1. Create the service file:

    sudo nano /etc/systemd/system/gunicorn.service
  2. Add the following configuration: Crucially, change User and Group to your Linux username, and WorkingDirectory to your project's path.

    [Unit]
    Description=gunicorn daemon
    After=network.target
    [Service]
    User=your_linux_username # <-- CHANGE THIS
    Group=www-data
    WorkingDirectory=/home/user/myproject # <-- CHANGE THIS
    ExecStart=/home/user/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
    [Install]
    WantedBy=multi-user.target
    • User: The user that will run the Gunicorn process.
    • Group: www-data is the standard group for web content on Debian/Ubuntu and gives Nginx permission to communicate with Gunicorn via the socket file.
    • WorkingDirectory: The directory where your project code lives.
    • ExecStart: The full command to start Gunicorn.
      • We use the virtual environment's gunicorn.
      • --workers 3: A good starting point for worker processes. A common formula is 2 * CPU_CORES + 1.
      • --bind unix:/run/gunicorn.sock: Binds to the same socket file our Nginx config is looking for.
  3. Start and enable the service:

    # Reload systemd to read the new service file
    sudo systemctl daemon-reload
    # Start the Gunicorn service
    sudo systemctl start gunicorn
    # Enable it to start on boot
    sudo systemctl enable gunicorn
    # Check its status
    sudo systemctl status gunicorn

    You should see active (running).

Step 6: The Final Result

Your stack is now fully configured!

  1. Nginx is listening on port 80.
  2. When a request comes in for a dynamic page (e.g., ), Nginx forwards it to the Gunicorn socket.
  3. Gunicorn passes the request to a Django worker process.
  4. Django processes the request and sends the response back through Gunicorn to Nginx.
  5. Nginx sends the final response to the user's browser.
  6. When a request comes in for a static file (e.g., /static/css/style.css), Nginx serves it directly without ever talking to Django.

If you visit http://your_domain.com in your browser, you should see your Django application running, served by Nginx

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