Skip to main content

Inventory Management System Setup auf Debian Trixie

Datum: 2. November 2025
OS: Debian 13 (Trixie)
Zweck: Production-ready Server für Inventory Management System


📋 Inhaltsverzeichnis

  1. Initial Server Setup
  2. Hostname & RDNS Konfiguration
  3. Docker CE Installation
  4. Nginx Installation & 3-Phase Setup
    • Phase 1: Basis-Config (HTTP für Let's Encrypt)
    • Phase 2: Let's Encrypt Zertifikat
    • Phase 3: Production Config (SSL + Optimierungen)
  5. SSL/TLS mit Certbot
  6. Firewall Konfiguration
  7. Docker Compose Production Setup
  8. Monitoring & Wartung
  9. Django Management Commands
  10. Fehlerbehebung
  11. Production Deployment Checkliste

Initial Server Setup

1. System Update & Upgrade


# Aktualisiere Paketlisten
sudo apt update

# Aktualisiere Pakete
sudo apt upgrade -y

# Installiere wichtige Tools
sudo apt install -y \
    curl \
    wget \
    git \
    vim \
    htop \
    net-tools \
    ufw \
    sudo \
    apt-transport-https \
    ca-certificates \
    gnupg \
    lsb-release \
    certbot \
    python3-certbot-nginx

2. Zeitzonen Konfiguration


# Setze Zeitzone auf Europe/Berlin (oder nach Bedarf)
sudo timedatectl set-timezone Europe/Berlin

# Verifiziere Zeitzone
timedatectl

Hostname & RDNS Konfiguration

1. Hostname Setzen


# Überprüfe aktuellen Hostname
hostnamectl status

# Setze neuen Hostname (z.B. "inventory-production")
sudo hostnamectl set-hostname inventory-production

# Verifiziere
hostnamectl status

# Aktualisiere auch /etc/hosts
sudo nano /etc/hosts

Inhalt von `/etc/hosts`:


127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
<your-public-ip> inventory-production

# Beispiel:
# 192.168.1.100 inventory-production

2. RDNS (Reverse DNS) Konfiguration

WICHTIG: RDNS wird auf Seite des DNS-Providers konfiguriert, nicht auf dem Server!

Schritte beim Provider:

  1. Gehe zu deiner DNS-Verwaltung (z.B. Hoster-Panel)
  2. Finde "Reverse DNS" oder "PTR Records"
  3. Setze PTR-Record für deine IP:
    • IP: <deine-public-ip>
    • Hostname: inventory-production.yourdomain.com

RDNS verifizieren (nach 24h):


# Überprüfe Reverse DNS
nslookup <your-public-ip>
# oder
dig -x <your-public-ip>

# Erwarteter Output:
# <your-public-ip>.in-addr.arpa. <ttl> IN PTR inventory-production.yourdomain.com.

Docker CE Installation

1. Docker Repository Hinzufügen


# Füge Dockers offiziellen GPG Key hinzu
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Füge Docker Repository hinzu
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

2. Docker CE Installieren


# Aktualisiere Paketlisten
sudo apt update

# Installiere Docker CE
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Starte Docker Service
sudo systemctl start docker

# Aktiviere beim Boot
sudo systemctl enable docker

# Verifiziere Installation
docker --version

3. Docker Compose Installation


# Lade neueste Version herunter
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Mache ausführbar
sudo chmod +x /usr/local/bin/docker-compose

# Verifiziere Installation
docker-compose --version

Nginx Installation & 3-Phase Setup

PHASE 1: Basis Config (HTTP für Let's Encrypt)


# Installiere Nginx
sudo apt install -y nginx

# Starte Nginx
sudo systemctl start nginx

# Aktiviere beim Boot
sudo systemctl enable nginx

# Verifiziere
sudo systemctl status nginx

Datei: `/etc/nginx/sites-available/inventar` (PHASE 1 - nur HTTP):


server {
    listen 80;
    listen [::]:80;
    server_name Your.Domain.here;

    location / {
        return 301 https://$server_name$request_uri;
    }

    # Let's Encrypt Challenge
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

Aktiviere Config:


# Teste Config
sudo nginx -t

# Aktiviere Site
sudo ln -s /etc/nginx/sites-available/inventar /etc/nginx/sites-enabled/

# Entferne Default Site
sudo rm /etc/nginx/sites-enabled/default

# Reload Nginx
sudo systemctl reload nginx

SSL/TLS mit Certbot

1. Certbot Installation


# Installiere Certbot
sudo apt install -y certbot python3-certbot-nginx

# Verifiziere Installation
certbot --version

2. SSL Zertifikat Erstellen


# Option 1: Interaktiv (empfohlen für ersten Setup)
sudo certbot certonly --nginx -d Your.Domain.here

# Option 2: Standalone (wenn Nginx noch nicht läuft)
sudo certbot certonly --standalone -d Your.Domain.here

# Folge den Prompts:
# - Gib E-Mail für Renewal-Benachrichtigungen ein
# - Akzeptiere Terms
# - Antworte auf Fragen zur E-Mail-Teilung

3. Certbot Auto-Renewal Konfigurieren


# Aktiviere Auto-Renewal Timer
sudo systemctl enable certbot.timer

# Starte Timer
sudo systemctl start certbot.timer

# Überprüfe Status
sudo systemctl status certbot.timer

# Teste Renewal (Dry-run, kein echtes Renewal)
sudo certbot renew --dry-run

PHASE 3: Production Nginx Config (mit SSL + Optimierungen)

Datei: `/etc/nginx/sites-available/inventar` (Production Version):


# Optimierte Host Nginx Konfiguration für Inventory System
# Production Konfiguration für Your.Domain.here

# HTTP: ACME Challenge + Redirect zu HTTPS
server {
    listen 80;
    server_name Your.Domain.here;

    # ACME Challenge (Certbot)
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    # Alles andere zu HTTPS umleiten
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS: Hauptanwendung
server {
    listen 443 ssl;
    http2 on;
    server_name Your.Domain.here;

    # SSL/TLS (Certbot-verwaltete Dateien)
    ssl_certificate /etc/letsencrypt/live/Your.Domain.here/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/Your.Domain.here/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    # Sicherheit: HSTS (1 Jahr)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Performance: gzip Komprimierung
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_min_length 1024;
    gzip_comp_level 6;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

    # Media Dateien direkt vom Host servieren (Benutzer Uploads)
    location /media/ {
        alias /opt/inventar/media/;
        try_files $uri =404;
        expires 1d;
        add_header Cache-Control "public";
        access_log off;
    }

    # Static Dateien direkt vom Host servieren (MAXIMALE PERFORMANCE)
    location /static/ {
        alias /opt/inventar/static/;
        try_files $uri =404;
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }

    # Reverse Proxy für die App (Frontend Container auf 127.0.0.1:8080)
    location / {
        proxy_pass http://127.0.0.1:8080;
        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 https;

        # Keepalive und Limits
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        client_max_body_size 70m;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

Aktiviere Production Config:


# Teste Nginx Config
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

# Verifiziere Nginx proxyt korrekt
curl -I https://Your.Domain.here

Firewall Konfiguration

1. UFW (Uncomplicated Firewall) Setup


# Aktiviere UFW
sudo ufw enable

# Erlaube SSH (WICHTIG - bevor Firewall aktiviert wird!)
sudo ufw allow 22/tcp

# Erlaube HTTP
sudo ufw allow 80/tcp

# Erlaube HTTPS
sudo ufw allow 443/tcp

# Erlaube SMTP für ausgehende E-Mails (falls konfiguriert)
sudo ufw allow 587/tcp

# Überprüfe Status
sudo ufw status verbose

# Zeige hinzugefügte Regeln
sudo ufw show added

⚠️ WICHTIG - Nur diese 4 Ports sind erlaubt:

  • ✅ 22/tcp - SSH (Remote Access)
  • ✅ 80/tcp - HTTP (Let's Encrypt Validierung)
  • ✅ 443/tcp - HTTPS (Production Traffic)
  • ✅ 587/tcp - SMTP (Ausgehende E-Mails nur)
  • ❌ Alle anderen Ports sind BLOCKIERT!

Docker Compose Production Setup

1. Docker Compose Datei erstellen

Datei: `/opt/inventar/docker-compose.prod.yml`


# Production Docker Compose - PostgreSQL + Host Nginx + Redis
# Version 1.2 - Redis Caching Added
# Verwendung: docker compose up -d

services:
  db:
    image: inventory-system-db-postgres:1.2
    container_name: inventory_db
    restart: unless-stopped
    env_file:
      - .env.production
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - inventory_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U inventory_user -d inventory_db"]
      interval: 10s
      timeout: 5s
      retries: 5
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    command: >
      postgres
      -c shared_buffers=256MB
      -c max_connections=200
      -c effective_cache_size=1GB
      -c maintenance_work_mem=64MB
      -c checkpoint_completion_target=0.9
      -c wal_buffers=16MB
      -c default_statistics_target=100
      -c random_page_cost=1.1
      -c effective_io_concurrency=200
      -c work_mem=2MB
      -c min_wal_size=1GB
      -c max_wal_size=4GB
      -c max_worker_processes=4
      -c max_parallel_workers_per_gather=2
      -c max_parallel_workers=4
      -c shared_preload_libraries='pg_stat_statements'

  redis:
    image: inventory-system-redis:1.2
    container_name: inventory_redis
    restart: unless-stopped
    volumes:
      - redis_data:/data
    networks:
      - inventory_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  backend:
    image: inventory-system-backend:1.2.6
    container_name: inventory_backend
    restart: unless-stopped
    env_file: 
      - .env.production
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./media:/app/media
      - ./static:/app/static
    networks:
      - inventory_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  frontend:
    image: inventory-system-frontend:1.2
    container_name: inventory_frontend
    restart: unless-stopped
    depends_on:
      - backend
    ports:
      - "127.0.0.1:8080:80"
    networks:
      - inventory_network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  postgres_data:
    name: inventory_postgres_data
  redis_data:
    name: inventory_redis_data

networks:
  inventory_network:
    driver: bridge

2. Docker Images laden

⚠️ WICHTIG: Docker Images müssen vor Docker Compose gestartet werden geladen werden:

⚠️ WICHTIG - Docker Images Download auf Anfrage!
Die Docker Images (backend.tar, db-postgres.tar, redis.tar, frontend.tar) werden auf Anfrage bereitgestellt. Du musst sie ins Verzeichnis `/opt/inventar/` hochladen, bevor du die folgenden Befehle ausführst.


cd /opt/inventar

# Lade Docker Images aus TAR Dateien
docker load < backend.tar
docker load < db-postgres.tar
docker load < redis.tar
docker load < frontend.tar

# Verifiziere Images wurden geladen
docker images | grep inventory-system

3. Environment Datei erstellen

Datei: `.env.production` (NIEMALS in Git committen!)


# Erstelle .env.production mit sensiblen Daten
nano .env.production

# Production Umgebungsvariablen - PostgreSQL Version
ENVIRONMENT=production
DEBUG=False

# Django Security & Konfiguration
SECRET_KEY=<GENERIERE_STARKEN_64_ZEICHEN_KEY>
ALLOWED_HOSTS=Your.Domain.here,<YOUR_IP>,localhost,127.0.0.1
DOMAIN=Your.Domain.here
FRONTEND_URL=https://Your.Domain.here

# Admin Benutzer (wird bei erstem Start verwendet)
ADMIN_USERNAME=admin
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=<STARKES_PASSWORT>

# PostgreSQL 18 Datenbank
POSTGRES_DB=inventory_db
POSTGRES_USER=inventory_user
POSTGRES_PASSWORD=<STARKES_DATENBANK_PASSWORT>
POSTGRES_HOST=db
POSTGRES_PORT=5432

# Connection String für Django
DATABASE_URL=postgresql://inventory_user:<STARKES_DATENBANK_PASSWORT>@db:5432/inventory_db

# SMTP Konfiguration (E-Mail Versand)
# System unterstützt zwei E-Mail Modi:
# 1. SMTP Backend (Production): Real emails via SMTP server (wenn gültige Credentials vorhanden)
# 2. Console Backend (Fallback): Emails werden geloggt (wenn Credentials leer/ungültig)
# 
# Wenn du KEINE E-Mail brauchst: Lass diese Zeilen einfach leer oder kommentiert
# System fällt automatisch auf Console Backend zurück
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.yourdomain.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=noreply@yourdomain.com
EMAIL_HOST_PASSWORD=<SMTP_PASSWORT>
DEFAULT_FROM_EMAIL=noreply@yourdomain.com

⚠️ SICHERHEIT - Wichtig:

  1. SECRET_KEY generieren: Nutze einen zufälligen String (64+ Zeichen):
    
    # Option 1: Mit openssl (keine Python Installation nötig!)
    openssl rand -base64 64
    
    # Option 2: Mit Python (falls installiert)
    python3 -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
    
  2. Starke Passwörter verwenden (mindestens 16 Zeichen, Groß/Klein/Zahlen/Symbole)
    
    # Zufälliges Passwort generieren:
    openssl rand -base64 24
    
  3. NIEMALS in Git committen - .gitignore hat `.env.production`
  4. Permissions setzen: chmod 600 .env.production
  5. Backup der `.env.production` an sicherem Ort aufbewahren!

4. Docker Compose starten


cd /opt/inventar

# Starte Services (Images sind bereits via docker load geladen)
docker compose -f docker-compose.prod.yml up -d

# Überprüfe Status
docker compose -f docker-compose.prod.yml ps

# Zeige Logs (alle Services)
docker compose -f docker-compose.prod.yml logs -f

# Zeige Logs pro Service
docker compose -f docker-compose.prod.yml logs -f frontend
docker compose -f docker-compose.prod.yml logs -f backend
docker compose -f docker-compose.prod.yml logs -f db

# Führe Bash im Backend Container aus (zum Debuggen)
docker compose -f docker-compose.prod.yml exec backend bash

# Sammle Static Files (nur wenn nicht automatisch gemacht)
docker compose -f docker-compose.prod.yml exec backend python manage.py collectstatic --noinput

Docker Ressourcen bereinigen (bei Bedarf)


# Stoppe alle Services und lösche Volumes
docker compose -f docker-compose.prod.yml down -v

# Lösche alle ungenutzten Images
docker image prune -a -f

# Vollständiger System Cleanup (alle Container, Images, Volumes, Networks)
docker system prune -a -f --volumes

Monitoring & Wartung

1. Log Monitoring


# Nginx Access Logs
sudo tail -f /var/log/nginx/inventar_access.log

# Nginx Error Logs
sudo tail -f /var/log/nginx/inventar_error.log

# Docker Logs (alle Services)
cd /opt/inventar
docker compose -f docker-compose.prod.yml logs -f

# Docker Logs pro Service
docker compose -f docker-compose.prod.yml logs -f backend
docker compose -f docker-compose.prod.yml logs -f frontend
docker compose -f docker-compose.prod.yml logs -f db

2. Disk Space Monitoring


# Überprüfe Festplattennutzung
df -h

# Überprüfe Docker Nutzung
docker system df

# Räume ungenutzten Docker auf
docker system prune -a

3. Regelmäßige Wartung


# Aktualisiere Systempakete
sudo apt update && sudo apt upgrade -y

# Überprüfe auf Sicherheits-Updates
sudo apt list --upgradable

# Räume Package Cache auf
sudo apt autoclean
sudo apt autoremove

4. Zertifikats-Ablauf Monitoring


# Überprüfe Zertifikats-Ablauf
echo | openssl s_client -servername Your.Domain.here -connect Your.Domain.here:443 2>/dev/null | openssl x509 -noout -dates

# Certbot sendet Email-Alerts 30 Tage vor Ablauf

🔧 Django Management Commands

Alle verfügbaren Management Commands für Systemadministration und Wartung:

📊 Datenbank & Monitoring


# Prüfe Datenbankgesundheit und erkenne Decimal-Anomalien
docker compose -f docker-compose.prod.yml exec backend python manage.py check_database_health

# Optimiere Datenbank-Tabellen (OPTIMIZE/VACUUM)
docker compose -f docker-compose.prod.yml exec backend python manage.py optimize_database

# Baue Datenbank-Indizes neu auf
docker compose -f docker-compose.prod.yml exec backend python manage.py rebuild_indexes

# Erstelle Datenbank-Backup
docker compose -f docker-compose.prod.yml exec backend python manage.py backup_database

🧹 Cleanup & Wartung


# Lösche ungenutzten Einträge (Kategorien, Locations ohne Items)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_database --dry-run

# Bereinige alte django-simple-history Einträge (behalte nur 4 pro Item)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_django_history

# Bereinige History-Einträge (behalte nur die letzten 4 pro Item)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_history

# Lösche alte Log-Dateien
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_logs

# Finde und lösche verwaiste Bild- und QR-Code-Dateien
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_orphaned_files

# Bereinige abgelaufene User-Sessions
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_sessions

# Bereinige abgelaufene JWT-Tokens
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_tokens

# Lösche alle Cache-Einträge
docker compose -f docker-compose.prod.yml exec backend python manage.py clear_cache

📦 Daten & Import/Export


# Schneller CSV Bulk-Import (ohne per-Item Overhead)
docker compose -f docker-compose.prod.yml exec backend python manage.py bulk_import_items --csv /path/to/file.csv

# Generiere Dummy-CSV für Bulk-Import Test
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_dummy_items_csv

# Exportiere alle Daten als CSV oder JSON
docker compose -f docker-compose.prod.yml exec backend python manage.py export_data --format json

🧪 Testdaten


# Erstelle realistische Testdaten
docker compose -f docker-compose.prod.yml exec backend python manage.py create_test_data

# Erstelle 50 Test-Items
docker compose -f docker-compose.prod.yml exec backend python manage.py create_test_items

# Lösche Testdaten
docker compose -f docker-compose.prod.yml exec backend python manage.py clear_test_data

# Erstelle initiale History-Einträge für alle Items
docker compose -f docker-compose.prod.yml exec backend python manage.py populate_history

📷 QR Codes


# Generiere fehlende QR-Codes
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_qr_codes

# Parallele QR-Code Generierung (schneller)
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_qr_parallel

# Regeneriere alle QR-Codes
docker compose -f docker-compose.prod.yml exec backend python manage.py regenerate_qrcodes

📸 Media & Performance


# Optimiere alle Item-Bilder (400x400px, WebP, quadratisch)
docker compose -f docker-compose.prod.yml exec backend python manage.py optimize_images

📋 Logs anzeigen


# Zeige letzte Error/Warning-Logs mit Optionen
docker compose -f docker-compose.prod.yml exec backend python manage.py view_logs --lines 50 --level error

# Optionen:
#   --lines N       : Anzahl der Zeilen (Standard: 100)
#   --level all|error|warning : Filter-Level (Standard: all)

📝 Fehlerbehebung

Problem: Backend zeigt Fehler


cd /opt/inventar

# Überprüfe Logs
docker compose -f docker-compose.prod.yml logs -f backend

# Führe Bash im Backend Container aus (zum Debuggen)
docker compose -f docker-compose.prod.yml exec backend bash

# Im Container - überprüfe:
ls -la /app/
python manage.py shell
python manage.py check

Problem: Nginx zeigt 502 Bad Gateway


# Überprüfe Backend
curl http://localhost:8000

# Teste Nginx Config
sudo nginx -t

# Überprüfe Nginx Logs
sudo tail -f /var/log/nginx/inventar_error.log

Problem: PostgreSQL startet nicht (Healthcheck schlägt fehl)


# Überprüfe PostgreSQL Logs
cd /opt/inventar
docker compose -f docker-compose.prod.yml logs db

# Verifiziere Umgebungsvariablen
docker compose -f docker-compose.prod.yml config | grep POSTGRES

# Versuche Neustart
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml up -d

Problem: Static/Media Dateien geben 404 zurück


# Verifiziere Host-Verzeichnisse existieren
ls -la /opt/inventar/static/
ls -la /opt/inventar/media/

# Überprüfe Berechtigungen
sudo chown -R 1000:1000 /opt/inventar/static/
sudo chown -R 1000:1000 /opt/inventar/media/

# Verifiziere Docker Volume Mounts
cd /opt/inventar
docker compose -f docker-compose.prod.yml exec backend ls -la /app/static/

Letztes Update: 2. November 2025
Status: ✅ Production-Ready

🚀 Production Deployment Checkliste

🔧 Nginx 3-Phase Setup (KRITISCH)

  • PHASE 1: Basis Nginx mit HTTP (Port 80)
    • ☐ Nginx installiert
    • ☐ Basis-Config mit Domain erstellt (/etc/nginx/sites-available/inventar)
    • ☐ Config aktiviert: sudo ln -s sites-available/inventar sites-enabled/
    • ☐ Nginx reloaded: sudo systemctl reload nginx
    • ☐ HTTP funktioniert: curl -I http://Your.Domain.here
    • ☐ Firewall Ports 80 & 443: sudo ufw allow 80/tcp; sudo ufw allow 443/tcp
  • PHASE 2: Let's Encrypt Zertifikat
    • ☐ Certbot installiert
    • ☐ Zertifikat erstellt: sudo certbot --nginx -d Your.Domain.here
    • ☐ Zertifikat verifiziert: sudo certbot certificates
    • ☐ Pfade vorhanden: /etc/letsencrypt/live/Your.Domain.here/
  • PHASE 3: Production Nginx Config
    • ☐ Alte Config gesichert: sudo cp sites-available/inventar sites-available/inventar.bak
    • ☐ Production Config eingefügt (mit SSL, Gzip, Security Headers)
    • ☐ Config getestet: sudo nginx -t
    • ☐ Nginx reloaded: sudo systemctl reload nginx
    • ☐ HTTPS funktioniert: curl -I https://Your.Domain.here
    • ☐ HTTP Redirect funktioniert: curl -I http://Your.Domain.here
    • ☐ SSL-Grade Check: https://www.ssllabs.com/ssltest/

Vor-Deployment (Host Setup)

  • ☐ Debian Trixie installiert & vollständig aktualisiert
  • ☐ Hostname gesetzt (hostnamectl)
  • ☐ RDNS beim Provider konfiguriert
  • ☐ SSH Zugang für Non-Root User konfiguriert
  • ☐ UFW Firewall aktiviert (Ports 22, 80, 443)
  • ☐ Docker CE installiert (docker --version)
  • ☐ Docker Compose installiert (docker-compose --version)

Docker Setup

  • /opt/inventar/ Verzeichnis erstellt
  • docker-compose.prod.yml platziert
  • .env.production mit Secrets erstellt (NICHT in Git!)
  • .gitignore aktualisiert (.env.production, media/, static/)
  • /opt/inventar/static/ und /opt/inventar/media/ Verzeichnisse erstellt
  • ☐ Docker Berechtigungen konfiguriert

Nginx Setup

  • /etc/nginx/sites-available/inventar Config erstellt
  • ☐ SSL Zertifikat mit Certbot erstellt
  • ☐ Nginx Config getestet (sudo nginx -t)
  • ☐ Site aktiviert (sudo ln -s sites-available/inventar sites-enabled/)
  • ☐ Nginx reloaded (sudo systemctl reload nginx)

SSL/TLS Setup

  • ☐ Certbot installiert
  • ☐ SSL Zertifikat für Domain erstellt
  • ☐ Auto-Renewal aktiviert (sudo systemctl enable certbot.timer)
  • ☐ Zertifikat Details überprüft (sudo certbot certificates)
  • ☐ Renewal Test durchgeführt (sudo certbot renew --dry-run)

Initial Deployment

  • ☐ Docker Images gepullt (docker compose pull)
  • ☐ Docker Compose gestartet (docker compose up -d)
  • ☐ Services laufen (docker compose ps)
  • ☐ Django Migrations durchgeführt (docker compose exec backend python manage.py migrate)
  • ☐ Static Files collected (docker compose exec backend python manage.py collectstatic --noinput)
  • ☐ Superuser erstellt (docker compose exec backend python manage.py createsuperuser)
  • ☐ Backend Health-Check erfolgreich (curl http://127.0.0.1:8000/api/health/)
  • ☐ Website erreichbar (curl https://Your.Domain.here/)

Monitoring & Wartung Setup

  • ☐ Log-Monitoring konfiguriert (docker compose logs -f)
  • ☐ Disk-Space Alerts einrichten (df -h)
  • ☐ Zertifikat Expiry Alerts einrichten (via Certbot Email)
  • ☐ Backup Strategy definiert
  • ☐ Monitoring Dashboard (optional) aufgesetzt

Security Hardening

  • ☐ UFW Firewall konfiguriert
  • ☐ SSH Key-based Auth nur (Password-Auth disabled)
  • ☐ Fail2Ban installiert (optional)
  • ☐ HTTPS erzwungen (HTTP → HTTPS redirect)
  • ☐ Security Headers überprüft
  • ☐ HSTS aktiviert

Post-Deployment Verifizierung

  • ☐ Alle Services laufen stabil
  • ☐ Logs zeigen keine Fehler
  • ☐ Frontend responsive
  • ☐ API Endpoints erreichbar
  • ☐ Login/Auth funktioniert
  • ☐ Uploads funktionieren
  • ☐ Performance zufriedenstellend
  • ☐ SSL Zertifikat gültig

📌 Wichtiger Hinweis

Docker Images zum Download auf Anfrage:

Die Docker Container Images (backend.tar, db-postgres.tar, redis.tar, frontend.tar) sind erforderlich für den Betrieb des Inventory Management Systems. Diese Images werden auf Anfrage bereitgestellt und müssen vor dem Starten des Systems in das Verzeichnis /opt/inventar/ hochgeladen werden.

Bitte kontaktieren Sie den Support oder Ihren Administrator, um die notwendigen Images zu erhalten.


Letztes Update: 2. November 2025
Status: ✅ Production-Ready