So stellen Sie eine Django-App auf einem VPS mit Gunicorn und nginx bereit
Um eine Django-App auf einem VPS bereitzustellen, führen Sie sie mit einem Produktionsserver aus, platzieren Sie einen Reverse Proxy davor, binden Sie eine Datenbank an und konfigurieren Sie HTTPS. Dieser Leitfaden nutzt Ubuntu 24.04 LTS, Django 5.2, PostgreSQL, Gunicorn, systemd und nginx. Passen Sie Pfade und Modulnamen an Ihr Projekt an.
Sie benötigen einen VPS mit SSH- und sudo-Zugriff, eine darauf zeigende Domain, ein funktionierendes Django-Repository und eine Abhängigkeitssperre oder gepinnte requirements.txt. Das Beispiel verwendet example.com, /srv/myapp und myproject.wsgi:application als Platzhalter. Es deckt eine WSGI-Anwendung ab; nutzen Sie ein ASGI-Setup, falls Ihre App dies erfordert. Referenzen geprüft am 9. September 2026.
1. Server und Anwendungs-User vorbereiten
Installieren Sie die Basispakete auf dem neuen Ubuntu-Server:
sudo apt update
sudo apt install -y python3-venv python3-dev build-essential libpq-dev postgresql nginx git
sudo adduser --system --group --home /srv/myapp django
sudo install -d -o django -g django /srv/myappDer django-User führt die Anwendung ohne Root-Rechte aus. Behalten Sie den administrativen SSH-Zugriff über Ihren regulären Account. Erlauben Sie Ihre SSH-Verbindung in der Firewall, bevor Sie Firewall-Regeln aktivieren, und gestatten Sie eingehenden HTTP- und HTTPS-Verkehr. Halten Sie PostgreSQL nur dort erreichbar, wo die App es benötigt.
2. PostgreSQL-Zugangsdaten anlegen
Erstellen Sie eine Datenbankrolle mit einem Passwort Ihrer Wahl bei der Abfrage, dann erstellen Sie deren Datenbank:
sudo -u postgres createuser --pwprompt myapp
sudo -u postgres createdb --owner=myapp myappDie Anwendung verbindet sich mit 127.0.0.1, das unter der üblichen Ubuntu-PostgreSQL-Einrichtung Passwort-Authentifizierung nutzt. Prüfen Sie Ihre pg_hba.conf, falls die Verbindung fehlschlägt. Machen Sie den Datenbankport nicht öffentlich erreichbar, um ein lokales Authentifizierungsproblem zu lösen.
3. Anwendung und Abhängigkeiten installieren
Ersetzen Sie die Beispiel-Repository-URL. Für ein privates Repository sorgen Sie für Lesezugriff, ohne ein Token in die URL oder committed Dateien zu legen.
sudo -u django git clone https://github.com/your-org/your-app.git /srv/myapp/app
sudo -u django python3 -m venv /srv/myapp/venv
sudo -u django /srv/myapp/venv/bin/pip install -r /srv/myapp/app/requirements.txtIhre Anforderungen müssen die Django-Version, Gunicorn und den PostgreSQL-Treiber enthalten, den Ihr Projekt nutzt. Verwenden Sie den bestehenden Paketmanager des Projekts, falls er ein anderes Lockfile hat. Bestätigen Sie, dass das Settings-Modul und der WSGI-Importpfad zu Ihrem Repository passen.
4. Produktionseinstellungen explizit laden
Erstellen Sie /etc/myapp.env mit Ihrem Editor. Speichern Sie echte Werte dort, nicht in Git. Dieses Beispiel geht davon aus, dass Ihre Settings diese Namen lesen:
DJANGO_SECRET_KEY='replace-with-a-long-random-secret'
DJANGO_ALLOWED_HOSTS='example.com'
DJANGO_CSRF_TRUSTED_ORIGINS='https://example.com'
DB_NAME='myapp'
DB_USER='myapp'
DB_PASSWORD='replace-with-the-password-you-set'
DB_HOST='127.0.0.1'
DB_PORT='5432'Nutzen Sie einfache Anführungszeichen-Werte, die sowohl mit einer Shell als auch mit der Environment-File-Syntax von systemd kompatibel sind. Schützen Sie die Datei:
sudo chown root:django /etc/myapp.env
sudo chmod 640 /etc/myapp.envIn den Produktionseinstellungen konfigurieren Sie die passenden Lesezugriffe. Dieser Ausschnitt setzt voraus, dass BASE_DIR bereits existiert:
import os
DEBUG = False
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
ALLOWED_HOSTS = os.environ['DJANGO_ALLOWED_HOSTS'].split(',')
CSRF_TRUSTED_ORIGINS = os.environ['DJANGO_CSRF_TRUSTED_ORIGINS'].split(',')
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ['DB_NAME'],
'USER': os.environ['DB_USER'],
'PASSWORD': os.environ['DB_PASSWORD'],
'HOST': os.environ['DB_HOST'],
'PORT': os.environ['DB_PORT'],
}
}
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'Halten Sie hochgeladene Medien getrennt von gesammelten statischen Assets. Wählen Sie dauerhaften Speicher, eine Backup-Richtlinie und Zugriffskontrollen, die zu den hochgeladenen Inhalten passen. Siehe Djangos Bereitstellungs-Checkliste.
5. Settings prüfen und Datenbank vorbereiten
Führen Sie Management-Befehle als App-User mit derselben Umgebung wie der Service aus:
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py check --deploy'
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py migrate --noinput'
sudo -u django bash -c 'set -a; . /etc/myapp.env; set +a; cd /srv/myapp/app; /srv/myapp/venv/bin/python manage.py collectstatic --noinput'Prüfen Sie die Bereitstellungs-Warnungen. HTTPS-bezogene Settings kommen nachdem der Proxy ein funktionierendes Zertifikat hat. Für eine bestehende Produktionsdatenbank erstellen und testen Sie ein Backup, bevor Sie Schema-Änderungen anwenden. Führen Sie Migrationen einmal im Rahmen des Releases aus, nicht in jedem Gunicorn-Worker.
6. Gunicorn unter systemd betreiben
Erstellen Sie /etc/systemd/system/myapp.service:
[Unit]
Description=Django application
After=network.target postgresql.service
[Service]
User=django
Group=django
WorkingDirectory=/srv/myapp/app
EnvironmentFile=/etc/myapp.env
ExecStart=/srv/myapp/venv/bin/gunicorn myproject.wsgi:application --bind 127.0.0.1:8001 --workers 2 --access-logfile - --error-logfile -
Restart=on-failure
RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.targetDer Wert mit zwei Workern ist ein initiales Beispiel, keine Dimensionierungsformel. Messen Sie Speicher, Datenbankverbindungen und Antwortzeiten, bevor Sie ihn erhöhen. Gunicorn bindet an Loopback, damit Besucher die App über nginx erreichen.
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp --no-pager
curl -I -H 'Host: example.com' http://127.0.0.1:8001/Nutzen Sie journalctl -u myapp für Prozessfehler. Ein Importfehler deutet meist auf den Modulpfad, das Arbeitsverzeichnis oder die Abhängigkeitsinstallation hin. Siehe Djangos WSGI-Leitfaden und Gunicorn.
7. nginx davorschalten
Erstellen Sie /etc/nginx/sites-available/myapp:
server {
listen 80;
server_name example.com;
location /static/ {
alias /srv/myapp/app/staticfiles/;
}
location / {
proxy_pass http://127.0.0.1:8001;
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;
}
}Aktivieren Sie den neuen Website einmal, testen Sie die Konfiguration und laden Sie neu:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp
sudo nginx -t
sudo systemctl reload nginxStellen Sie sicher, dass nginx die gesammelten statischen Dateien lesen und deren Elternverzeichnisse durchlaufen kann. Halten Sie jede Standard-Website-Konfiguration konsistent mit Ihren anderen gehosteten Domains; entfernen Sie nicht verwandte Sites nicht. Der nginx-Leitfaden erklärt Reverse-Proxy- und statische-Datei-Konfiguration.
8. HTTPS hinzufügen und Django erneut prüfen
Installieren Sie ein Zertifikat mit Ihrem gewählten ACME-Client und dessen aktuellen Anweisungen. Mit Certbot für nginx installiert lautet die Zertifikatanforderung für dieses Beispiel:
sudo certbot --nginx -d example.com
sudo certbot renew --dry-runNutzen Sie die Certbot-Anweisungen für die Installation auf Ihrem OS. Verifizieren Sie Domain-DNS, HTTP-Erreichbarkeit und Erneuerung, bevor Sie TLS als abgeschlossen betrachten.
Sobald HTTPS funktioniert, setzen Sie diese Django-Optionen:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = TrueVertrauen Sie dem Forwarded-Protokoll-Header nur, weil nginx ihn kontrolliert und Gunicorn nicht direkt exponiert ist. Starten Sie den Service neu, führen Sie check --deploy erneut aus und testen Sie Login und eine Formularübergabe über HTTPS. Prüfen Sie HSTS separat, nachdem Sie HTTPS auf jedem betroffenen Host verifiziert haben.
9. Zukünftige Releases wiederholbar machen
Für jedes Release wählen Sie eine geprüfte Revision, installieren deren gesperrte Abhängigkeiten, wenden kompatible Migrationen an, sammeln statische Dateien und starten den Service neu. Testen Sie die Live-Anwendung und beobachten Sie Fehler nach der Änderung.
Behalten Sie die vorherige Revision verfügbar, aber bedenken Sie, dass ein Code-Rollback eine Datenbank-Migration nicht rückgängig machen mag. Dokumentieren Sie den Wiederherstellungspfad für Schema-Änderungen und testen Sie das Wiederherstellen von Daten in eine separate Datenbank.
Falls die App Celery nutzt, geben Sie ihm eine separate Service-Definition, Befehl und Broker-Konfiguration. Führen Sie den Worker nicht als Hintergrund-Shell-Befehl innerhalb des Gunicorn-Services aus.
Wann man verwaltetes Hosting wählen sollte
Ein VPS ist sinnvoll, wenn Sie Serverkontrolle wollen und ihn warten können. Wenn Sie mehr Host-Operationen abgeben möchten, vergleichen Sie Python-App-Hosting Optionen. Auf Lizard kann die Anwendung Managed Postgres und einen separaten Worker nutzen, während Sie Kontrolle über Code und Konfiguration behalten.
Die Bereitstellungsdokumentation deckt diesen Weg ab. Sie benötigen weiterhin korrekte Django-Settings, einen Release-Prozess und einen verifizierten Datenwiederherstellungsplan.
FAQ
Warum erhalte ich einen 502-Fehler? Prüfen Sie, ob Gunicorn läuft und auf 127.0.0.1:8001 lauscht, dann inspizieren Sie dessen Logs und nginx' Error-Log. Ein Reverse Proxy kann einen Prozess, der nicht startet, nicht reparieren.
Warum fehlen statische Dateien? Prüfen Sie STATIC_ROOT, die Ausgabe von collectstatic, nginx' Alias-Pfad und Dateiberechtigungen. Hochgeladene Medien erfordern ein separates Setup.
Kann ich statt PostgreSQL SQLite nutzen? Manche Anwendungen können das, aber bewerten Sie Parallelität, Persistenz und Backup-Anforderungen. Ändern Sie die Datenbank-Engine nicht ohne Test Ihrer Anwendungslast.
Reicht ein erfolgreicher Bereitstellungs-Prüfen? Nein. Testen Sie einen echten Nutzerfluss, Datenbankschreibzugriffe, Dateizugriff und Wiederherstellung. Konfigurationsprüfungen erfassen nur einen Teil des Produktionsverhaltens.
Mit AI entwickeln. Mit Lizard ausliefern.
Du brauchst kein Plattform-Team, um live zu gehen. Deine ganze Cloud ist nur einen CLI-Befehl entfernt.
- Workspaces
- —
- Dienste
- —
- Add-ons
- —
- Bereitstellungen
- —