Inventory Management System Setup auf Debian Trixie
Datum: 2. November 2025
OS: Debian 13 (Trixie)
Zweck: Production-ready Server für Inventory Management System
📋 Table of ContentsInhaltsverzeichnis
- Initial Server Setup
 - Hostname & RDNS 
ConfigurationKonfiguration - Docker CE Installation
 - Nginx Installation & 3-Phase Setup
- Phase 1: 
BasicBasis-Config (HTTPforfür Let's Encrypt) - Phase 2: Let's Encrypt 
CertificateZertifikat - Phase 3: Production Config (SSL + 
Optimizations)Optimierungen) 
 - Phase 1: 
 - SSL/TLS 
withmit Certbot - Firewall 
ConfigurationKonfiguration - Docker Compose Production Setup
 - Monitoring & 
MaintenanceWartung - Django Management Commands
 TroubleshootingFehlerbehebung- Production Deployment 
ChecklistCheckliste 
Initial Server Setup
1. System Update & Upgrade
# UpdateAktualisiere package listsPaketlisten
sudo apt update
# UpgradeAktualisiere packagesPakete
sudo apt upgrade -y
# InstallInstalliere essentialwichtige toolsTools
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. TimezoneZeitzonen ConfigurationKonfiguration
# SetSetze timezoneZeitzone toauf Europe/Berlin (oroder asnach needed)Bedarf)
sudo timedatectl set-timezone Europe/Berlin
# VerifyVerifiziere timezoneZeitzone
timedatectl
Hostname & RDNS ConfigurationKonfiguration
1. SetHostname HostnameSetzen
# CheckÜberprüfe currentaktuellen hostnameHostname
hostnamectl status
# SetSetze newneuen hostnameHostname (e.g.z.B. "inventory-production")
sudo hostnamectl set-hostname inventory-production
# VerifyVerifiziere
hostnamectl status
# AlsoAktualisiere updateauch /etc/hosts
sudo nano /etc/hosts
ContentInhalt ofvon `/etc/hosts`:
127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
<your-public-ip> inventory-production
# Example:Beispiel:
# 192.168.1.100 inventory-production
2. RDNS (Reverse DNS) ConfigurationKonfiguration
IMPORTANT:WICHTIG: RDNS iswird configuredauf onSeite thedes DNSDNS-Providers providerkonfiguriert, side,nicht notauf ondem the server!Server!
StepsSchritte atbeim your provider:Provider:
GoGehetozuyourdeinerDNS managementDNS-Verwaltung (e.g.z.B.hoster panel)Hoster-Panel)FindFinde "Reverse DNS"oroder "PTR Records"SetSetzePTRPTR-Recordrecordfürfor yourdeine IP:- IP: 
<your-deine-public-ip> - Hostname: 
inventory-production.yourdomain.com 
- IP: 
 
Verify RDNS verifizieren (afternach 24h):
# CheckÜberprüfe reverseReverse DNS
nslookup <your-public-ip>
# oroder
dig -x <your-public-ip>
# ExpectedErwarteter output:Output:
# <your-public-ip>.in-addr.arpa. <ttl> IN PTR inventory-production.yourdomain.com.
Docker CE Installation
1. AddDocker Docker'sRepository GPG Repo KeyHinzufügen
# DownloadFüge andDockers add Docker'soffiziellen GPG keyKey hinzu
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.docker-archive-keyring.gpg
# 2. AddFüge Docker Repository
 
# Add official Docker repositoryhinzu
echo \
  "deb [arch=$(dpkg --print-architecture)amd64 signed-by=/usr/share/keyrings/docker.docker-archive-keyring.gpg] https://download.docker.com/linux/debian trixie\
  $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
2. Docker CE Installieren
# RefreshAktualisiere package lists againPaketlisten
sudo apt update
# 3. InstallInstalliere Docker on Debian 13 (Trixie)
# Install Docker and related componentsCE
sudo apt install -y docker-ce docker-ce-cli containerd.io
docker-buildx-plugin# docker-compose-pluginStarte Docker Service
sudo systemctl start docker
# Aktiviere beim Boot
sudo systemctl enable docker
# Verifiziere Installation
docker --version
4. Verify3. Docker Compose Installation
# CheckLade ifneueste DockerVersion service is activeherunter
sudo systemctlcurl is-active-L docker"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 & Configuration3-Phase Setup
1.PHASE Install1: NginxBasis Config (HTTP für Let's Encrypt)
# InstallInstalliere Nginx
sudo apt install -y nginx
# StartStarte Nginx
sudo systemctl start nginx
# EnableAktiviere onbeim bootBoot
sudo systemctl enable nginx
# VerifyVerifiziere
sudo systemctl status nginx
# Check version
nginx -v
2. Phase 1: Basic Nginx Config (for Let's Encrypt)
⚠️Datei: IMPORTANT: Start with a simple HTTP config first so Let's Encrypt can create the certificate!
Step 1: Create Nginx config
sudo nano `/etc/nginx/sites-available/inventar
Insert contentinventar` (BasicPHASE config1 for- Let'snur Encrypt)HTTP):
server {
    listen 80;
    listen [::]:80;
    server_name Your.Domain.here;
    location / {
        return 301 https://$server_name$request_uri;
    }
    # RequiredLet's forEncrypt CertbotChallenge
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    # Redirect all other requests to HTTPS
    location / {
        return 301 https://$host$request_uri;certbot;
    }
}
StepAktiviere 2: Enable config & testConfig:
# EnableTeste siteConfig
sudo nginx -t
# Aktiviere Site
sudo ln -s /etc/nginx/sites-available/inventar /etc/nginx/sites-enabled/
# TestEntferne nginxDefault configSite
sudo nginxrm -t/etc/nginx/sites-enabled/default
# RestartReload Nginx
sudo systemctl restart nginx
# Verify running
sudo systemctl statusreload nginx
SSL/TLS withmit Certbot - Phase 2 & Phase 3
1. PhaseCertbot 2: Create SSL Certificate with CertbotInstallation
⚠️ IMPORTANT: The basic Nginx config (Phase 1) must be running!
# Installiere Certbot
withsudo Nginxapt plugininstall -y certbot python3-certbot-nginx
# Verifiziere Installation
certbot --version
2. SSL Zertifikat Erstellen
# Option 1: Interaktiv (willempfohlen automaticallyfür updateersten Nginx)Setup)
sudo certbot certonly --nginx -d Your.Domain.here
# CertbotOption will2: thenStandalone automatically:(wenn Nginx noch nicht läuft)
sudo certbot certonly --standalone -d Your.Domain.here
# 1.Folge Validateden the certificate (HTTP Challenge via Port 80)
# 2. Download Let's Encrypt Certificate
# 3. Automatically update Nginx config (HTTP → HTTPS Redirect)
# Follow prompts:Prompts:
# - EnterGib emailE-Mail forfür renewalsRenewal-Benachrichtigungen ein
# - Accept Let's EncryptAkzeptiere Terms (Y)
# - Optional:Antworte Shareauf emailFragen withzur EFF (Y/N)
# Verify certificate was created
sudo certbot certificatesE-Mail-Teilung
3. PhaseCertbot 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: Adjust Production Nginx Config (mit SSL + Optimierungen)
AfterDatei: Certbot, the certificates are in place - now adjust & optimize:
sudo nano `/etc/nginx/sites-available/inventarinventar` (Production Config (optimized for Inventory System)Version):
# HTTP:Upstream ACMEBackend Challenge(Django +API)
upstream backend {
    server 127.0.0.1:8000;
}
# HTTP → HTTPS Redirect to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name Your.Domain.here;
    location / {
        return 301 https://$server_name$request_uri;
    }
    # ACMELet's Encrypt Challenge (Certbot)
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    # Redirect everything else to HTTPS
    location / {
        return 301 https://$host$request_uri;certbot;
    }
}
# HTTPS:HTTPS Main- ApplicationHaupt-Server (Production-Optimiert)
server {
    listen 443 ssl;ssl http2 on;http2;
    server_name Your.Domain.here;
    # SSL/TLSSSL Zertifikate (Certbot-managed files)verwaltet)
    ssl_certificate /etc/letsencrypt/live/Your.Domain.here/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/Your.Domain.here/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    # Security: HSTS (1 year)Jahr)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    # Performance: gzipGzip compressionKompression
    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;
    # Serve media files directly from host (user uploads)
    location /media/ {
        alias /opt/inventar/media/;
        try_files $uri =404;
        expires 1d;
        add_header Cache-Control "public";Logging
    access_log off;/var/log/nginx/inventar_access.log;
    }error_log /var/log/nginx/inventar_error.log;
    # ServeServiere staticStatic filesFiles directlydirekt fromvom hostHost (MAXIMUMMAXIMALE PERFORMANCE)
    location /static/ {
        alias /opt/inventar/static/;
        try_files $uri =404;
        expires 1y;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
    # Serviere Media Files direkt vom Host (User Uploads)
    location /media/ {
        alias /opt/inventar/media/;
        try_files $uri =404;
        expires 1d;
        add_header Cache-Control "public";
        access_log off;
    }
    # Reverse proxyProxy forzum the app (frontend container at 127.0.0.1:8080)Backend
    location / {
        proxy_pass http://127.0.0.1:8080;8000;
        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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        client_max_body_size 70m;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
    # KeepaliveAPI andBackend
    limitslocation /api/ {
        proxy_pass http://127.0.0.1:8000;
        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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        client_max_body_size 70m;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
    # Admin Panel
    location /admin/ {
        proxy_pass http://127.0.0.1:8000;
        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;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        client_max_body_size 70m;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}
TestAktiviere configProduction & restart Nginx:Config:
# TestTeste theNginx configurationConfig
sudo nginx -t
# Reload Nginx
with new config
sudo systemctl reload nginx
# VerifyVerifiziere it'sNginx workingproxyt sudo systemctl status nginx
4. Enable Production Config & Test
# Test new nginx config
sudo nginx -t
# If OK, reload
sudo systemctl reload nginx
# Verify SSL certificate
echo | openssl s_client -servername Your.Domain.here -connect Your.Domain.here:443 2>/dev/null | openssl x509 -noout -dates
# Test HTTP Redirect to HTTPS
curl -I http://Your.Domain.here
# Should show: HTTP/1.1 301 Moved Permanently
# Location: https://Your.Domain.here/
# Test HTTPSkorrekt
curl -I https://Your.Domain.here
# Should show: HTTP/2 200
5. Configure Certbot Auto-Renewal
# Enable auto-renewal timer
sudo systemctl enable certbot.timer
# Start timer
sudo systemctl start certbot.timer
# Check status
sudo systemctl status certbot.timer
# Test renewal (dry-run - no actual renewal!)
sudo certbot renew --dry-run
# View renewal logs
sudo journalctl -u certbot.timer -f
Firewall ConfigurationKonfiguration
1. UFW (Uncomplicated Firewall) Setup
Only open these 4 ports - everything else remains blocked:
# EnableAktiviere UFW
sudo ufw enable
# AllowErlaube SSH (IMPORTANT:WICHTIG BEFORE- enablingbevor firewall!Firewall aktiviert wird!)
sudo ufw allow 22/tcp
# AllowErlaube HTTP (for Let's Encrypt)
sudo ufw allow 80/tcp
# AllowErlaube HTTPS
sudo ufw allow 443/tcp
# AllowErlaube SMTP für ausgehende E-Mails (outboundfalls email)konfiguriert)
sudo ufw allow 587/tcp
# VerifyÜberprüfe all rulesStatus
sudo ufw status verbose
# ShowZeige addedhinzugefügte rules onlyRegeln
sudo ufw show added
⚠️ IMPORTANT:WICHTIG Only- theseNur diese 4 portsPorts aresind allowed.erlaubt:
- ✅ 22/tcp - SSH (
5432,Remote8000,Access) - ✅ 
remain80/tcpblocked!- 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
0. Create Directory Structure
Create the required directory structure with correct permissions:
# Create main application directory
sudo mkdir -p /opt/inventar
# Create subdirectories for static and media files
sudo mkdir -p /opt/inventar/static
sudo mkdir -p /opt/inventar/media
# Set permissions (www-data for web content, docker user for app files)
sudo chmod 777 /opt/inventar
sudo chown root:www-data /opt/inventar/static
sudo chown root:www-data /opt/inventar/media
sudo chmod 755 /opt/inventar/static
sudo chmod 755 /opt/inventar/media
# Verify structure
ls -la /opt/inventar/
Expected result:
root@inv:/opt/inventar# ls -l
total 0
drwxr-xr-x  2 root www-data  4096 Nov  2 12:00 static
drwxr-xr-x  2 root www-data  4096 Nov  2 12:00 media
1. Create Docker Compose FileDatei erstellen
File: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
    # Keine Ports nach außen, nur Compose-Netz
    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"
    # PostgreSQL 18 Performance Optimization
    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
    # Frontend nur lokal am Host erreichbar (für Host-Nginx Reverse Proxy)
    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
# Optional: Falls du später zu Docker Volumes wechseln willst
  # media_data:
  #   name: inventory_media_data
  # static_data:
  #   name: inventory_static_data
networks:
  inventory_network:
    driver: bridge
2. LoadDocker Images laden
⚠️ WICHTIG: Docker Images  ⚠️ Themüssen Docker images must be loaded into Docker beforevor Docker Compose isgestartet started:werden geladen werden:IMPORTANT:WICHTIG - Docker Images Download onauf Request!Anfrage!
TheDie Docker imagesImages (backend.tar, db-postgres.tar, redis.tar, frontend.tar) arewerden providedauf onAnfrage request.bereitgestellt. YouDu mustmusst uploadsie themins to theVerzeichnis `/opt/inventar/` directoryhochladen, beforebevor executingdu thedie followingfolgenden commands.Befehle ausführst.
cd /opt/inventar
# LoadLade Docker imagesImages fromaus tarTAR filesDateien
docker load < backend.tar
docker load < db-postgres.tar
docker load < redis.tar
docker load < frontend.tar
# VerifyVerifiziere imagesImages werewurden loadedgeladen
docker images | grep inventory-system
3. 
Create Environment FileDatei erstellenFile:Datei: `/opt/inventar/.env.production`
⚠️ IMPORTANT - Email Configuration:
The system supports two email modes:
SMTP (Production): Real emails via SMTP server (if valid credentials are provided)
Console (Fallback): Emails are logged to console output (if credentials are empty/invalid)
If you DON'T need email configuration:
Simply omit the SMTP lines or leave them empty. The frontend will show a warning and password reset will be disabled. You can configure email later anytimeNIEMALS in theGit Admincommitten!)Interface!
# Erstelle .env.production mit sensiblen Daten
nano .env.production
# Production environment variablesUmgebungsvariablen - PostgreSQL Version
ENVIRONMENT=production
DEBUG=False
# Django Security & ConfigurationKonfiguration
SECRET_KEY=<GENERATE_STRONG_64_CHAR_KEYGENERIERE_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 UserBenutzer (wird bei erstem Start verwendet)
ADMIN_USERNAME=admin
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=<STRONG_PASSWORDSTARKES_PASSWORT>
# PostgreSQL 18 DatabaseDatenbank
POSTGRES_DB=inventory_db
POSTGRES_USER=inventory_user
POSTGRES_PASSWORD=<STRONG_DATABASE_PASSWORDSTARKES_DATENBANK_PASSWORT>
POSTGRES_HOST=db
POSTGRES_PORT=5432
# Connection String für Django
DATABASE_URL=postgresql://inventory_user:<STRONG_DATABASE_PASSWORDSTARKES_DATENBANK_PASSWORT>@db:5432/inventory_db
# SMTP ConfigurationKonfiguration (OPTIONALE-Mail - leave empty if not needed)Versand)
# System automaticallyunterstützt fallszwei backE-Mail toModi:
console# backend1. ifSMTP emptyBackend (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_PASSWORDSMTP_PASSWORT>
DEFAULT_FROM_EMAIL=noreply@yourdomain.com
⚠️ SICHERHEIT - Wichtig:
- SECRET_KEY: Generiere mit: 
python3 -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())" - Starke Passwörter verwenden (mindestens 16 Zeichen, Groß/Klein/Zahlen/Symbole)
 - NIEMALS in Git committen - .gitignore hat `.env.production`
 - Permissions setzen: 
chmod 600 .env.production - Backup der `.env.production` an sicherem Ort aufbewahren!
 
4. Start Docker Compose starten
cd /opt/inventar
# StartStarte servicesServices (imagesImages alreadysind loadedbereits via docker load)load geladen)
docker compose -f docker-compose.prod.yml up -d
# CheckÜberprüfe statusStatus
docker compose -f docker-compose.prod.yml ps
# ViewZeige logsLogs (allalle services)Services)
docker compose -f docker-compose.prod.yml logs -f
# ViewZeige logsLogs perpro serviceService
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
# ExecuteFühre bashBash inim backendBackend containerContainer aus (forzum debugging)Debuggen)
docker compose -f docker-compose.prod.yml exec backend bash
# CollectSammle staticStatic filesFiles (onlynur ifwenn notnicht doneautomatisch automatically)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 & MaintenanceWartung
1. Log Monitoring
# Nginx accessAccess logsLogs
sudo tail -f /var/log/nginx/itemp_access.inventar_access.log
# Nginx errorError logsLogs
sudo tail -f /var/log/nginx/itemp_error.inventar_error.log
# Docker logsLogs (allalle services)Services)
cd /opt/inventar
docker compose -f docker-compose.prod.yml logs -f
# Docker logsLogs perpro serviceService
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
# CheckÜberprüfe disk usageFestplattennutzung
df -h
# CheckÜberprüfe Docker usageNutzung
docker system df
# CleanRäume upungenutzten unusedDocker resourcesauf
docker system prune -a
3. RegularRegelmäßige MaintenanceWartung
# UpdateAktualisiere system packagesSystempakete
sudo apt update && sudo apt upgrade -y
# CheckÜberprüfe forauf security updatesSicherheits-Updates
sudo apt list --upgradable
# CleanRäume packagePackage cacheCache auf
sudo apt autoclean
sudo apt autoremove
4. Certificate ExpiryZertifikats-Ablauf Monitoring
# CheckÜberprüfe certificate expiryZertifikats-Ablauf
echo | openssl s_client -servername Your.Domain.here -connect Your.Domain.here:443 2>/dev/null | openssl x509 -noout -dates
# Certbot willsendet send email alertsEmail-Alerts 30 daysTage beforevor expiryAblauf
🔧 Django Management Commands
AllAlle availableverfügbaren managementManagement commandsCommands forfür systemSystemadministration administrationund and maintenance:Wartung:
📊 DatabaseDatenbank & Monitoring
# CheckPrüfe databaseDatenbankgesundheit healthund anderkenne detect Decimal anomaliesDecimal-Anomalien
docker compose -f docker-compose.prod.yml exec backend python manage.py check_database_health
# OptimizeOptimiere database tablesDatenbank-Tabellen (OPTIMIZE/VACUUM)
docker compose -f docker-compose.prod.yml exec backend python manage.py optimize_database
# RebuildBaue databaseDatenbank-Indizes indexesneu auf
docker compose -f docker-compose.prod.yml exec backend python manage.py rebuild_indexes
# CreateErstelle database backupDatenbank-Backup
docker compose -f docker-compose.prod.yml exec backend python manage.py backup_database
🧹 Cleanup & MaintenanceWartung
# DeleteLösche unusedungenutzten entriesEinträge (categories,Kategorien, locationsLocations withoutohne items)Items)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_database --dry-run
# CleanBereinige oldalte django-simple-history recordsEinträge (keepbehalte onlynur 4 perpro item)Item)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_django_history
# CleanBereinige history entriesHistory-Einträge (keepbehalte onlynur lastdie letzten 4 perpro item)Item)
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_history
# DeleteLösche oldalte log filesLog-Dateien
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_logs
# FindFinde andund deletelösche orphanedverwaiste imageBild- andund QR code filesQR-Code-Dateien
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_orphaned_files
# CleanBereinige expiredabgelaufene user sessionsUser-Sessions
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_sessions
# CleanBereinige expiredabgelaufene JWT tokensJWT-Tokens
docker compose -f docker-compose.prod.yml exec backend python manage.py cleanup_tokens
# DeleteLösche allalle cache entriesCache-Einträge
docker compose -f docker-compose.prod.yml exec backend python manage.py clear_cache
📦 DataDaten & Import/Export
# FastSchneller CSV bulk importBulk-Import (withoutohne per-itemItem overhead)Overhead)
docker compose -f docker-compose.prod.yml exec backend python manage.py bulk_import_items --csv /path/to/file.csv
# GenerateGeneriere dummy Dummy-CSV forfür bulkBulk-Import import testingTest
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_dummy_items_csv
# ExportExportiere allalle dataDaten asals CSV oroder JSON
docker compose -f docker-compose.prod.yml exec backend python manage.py export_data --format json
🧪 Test DataTestdaten
# CreateErstelle realisticrealistische test dataTestdaten
docker compose -f docker-compose.prod.yml exec backend python manage.py create_test_data
# CreateErstelle 50 test itemsTest-Items
docker compose -f docker-compose.prod.yml exec backend python manage.py create_test_items
# DeleteLösche test dataTestdaten
docker compose -f docker-compose.prod.yml exec backend python manage.py clear_test_data
# CreateErstelle initialinitiale historyHistory-Einträge entriesfür foralle all itemsItems
docker compose -f docker-compose.prod.yml exec backend python manage.py populate_history
📷 QR Codes
# GenerateGeneriere missingfehlende QR codesQR-Codes
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_qr_codes
# ParallelParallele QRQR-Code code generationGenerierung (faster)schneller)
docker compose -f docker-compose.prod.yml exec backend python manage.py generate_qr_parallel
# RegenerateRegeneriere allalle QR codesQR-Codes
docker compose -f docker-compose.prod.yml exec backend python manage.py regenerate_qrcodes
📸 Media & Performance
# OptimizeOptimiere allalle item imagesItem-Bilder (400x400px, WebP, square)quadratisch)
docker compose -f docker-compose.prod.yml exec backend python manage.py optimize_images
📋 ViewLogs Logsanzeigen
# ViewZeige lastletzte error/warningError/Warning-Logs logsmit with optionsOptionen
docker compose -f docker-compose.prod.yml exec backend python manage.py view_logs --lines 50 --level error
# Options:Optionen:
#   --lines N       : NumberAnzahl ofder linesZeilen (default:Standard: 100)
#   --level all|error|warning : Filter levelFilter-Level (default:Standard: all)
📝 TroubleshootingFehlerbehebung
Problem: Backend Showszeigt ErrorsFehler
cd /opt/inventar
# CheckÜberprüfe logsLogs
docker compose -f docker-compose.prod.yml logs -f backend
# ExecuteFühre bashBash inim backendBackend forContainer debuggingaus (zum Debuggen)
docker compose -f docker-compose.prod.yml exec backend bash
# WithinIm containerContainer - check:überprüfe:
ls -la /app/
python manage.py shell
python manage.py check
Problem: Nginx showszeigt 502 Bad Gateway
# CheckÜberprüfe backendBackend
curl http://localhost:8000
# TestTeste Nginx configConfig
sudo nginx -t
# CheckÜberprüfe Nginx logsLogs
sudo tail -f /var/log/nginx/itemp_error.inventar_error.log
Problem: PostgreSQL doesstartet not startnicht (Healthcheck failing)schlägt fehl)
# CheckÜberprüfe PostgreSQL logsLogs
cd /opt/inventar
docker compose -f docker-compose.prod.yml logs db
# VerifyVerifiziere environment variablesUmgebungsvariablen
docker compose -f docker-compose.prod.yml config | grep POSTGRES
# TryVersuche restartingNeustart
docker compose -f docker-compose.prod.yml down
docker compose -f docker-compose.prod.yml up -d
Problem: Static/Media FilesDateien returngeben 404 zurück
# VerifyVerifiziere HostHost-Verzeichnisse Directories existexistieren
ls -la /opt/inventar/static/
ls -la /opt/inventar/media/
# CheckÜberprüfe permissionsBerechtigungen
sudo chown -R 1000:1000 /opt/inventar/static/
sudo chown -R 1000:1000 /opt/inventar/media/
# VerifyVerifiziere dockerDocker volumeVolume mountsMounts
cd /opt/inventar
docker compose -f docker-compose.prod.yml exec backend ls -la /app/static/
LastLetztes Update: 2. November 2, 2025
Status: ✅ Production-Ready
🚀 Production Deployment ChecklistCheckliste
🔧 Nginx 3-Phase Setup (CRITICAL)KRITISCH)
- ☐ PHASE 1: 
BasicBasis Nginxwithmit HTTP (Port 80)- ☐ Nginx 
installedinstalliert - ☐ 
BasicBasis-ConfigconfigmitwithDomaindomain createderstellt (/etc/nginx/sites-available/inventar) - ☐ Config 
enabled:aktiviert:sudo ln -s sites-available/inventar sites-enabled/ - ☐ Nginx reloaded: 
sudo systemctl reload nginx - ☐ HTTP 
working:funktioniert:curl -I http://Your.Domain.here - ☐ Firewall 
portsPorts 80 & 443:sudo ufw allow 80/tcp; sudo ufw allow 443/tcp 
 - ☐ Nginx 
 - ☐ PHASE 2: Let's Encrypt 
CertificateZertifikat- ☐ Certbot 
installedinstalliert - ☐ 
CertificateZertifikatcreated:erstellt:sudo certbot --nginx -d Your.Domain.here - ☐ 
CertificateZertifikatverified:verifiziert:sudo certbot certificates - ☐ 
PathsPfadepresent:vorhanden:/etc/letsencrypt/live/Your.Domain.here/ 
 - ☐ Certbot 
 - ☐ PHASE 3: Production Nginx Config
  
- ☐ 
OldAlteconfigConfigbacked up:gesichert:sudo cp sites-available/inventar sites-available/inventar.bak - ☐ Production 
configConfiginsertedeingefügt (withmit SSL, Gzip, Security Headers) - ☐ Config 
tested:getestet:sudo nginx -t - ☐ Nginx reloaded: 
sudo systemctl reload nginx - ☐ HTTPS 
working:funktioniert:curl -I https://Your.Domain.here - ☐ HTTP 
redirectRedirectworking:funktioniert:curl -I http://Your.Domain.here - ☐ 
SSLSSL-Gradegrade check:Check: https://www.ssllabs.com/ssltest/ 
 - ☐ 
 
Pre-Vor-Deployment (Host Setup)
- ☐ Debian Trixie 
installedinstalliert &fullyvollständigupdatedaktualisiert - ☐ Hostname 
setgesetzt (hostnamectl) - ☐ RDNS 
configuredbeimatProviderproviderkonfiguriert - ☐ SSH 
accessZugangconfiguredfürforNon-Rootnon-rootUseruserkonfiguriert - ☐ UFW Firewall 
enabledaktiviert (Ports 22, 80, 443) - ☐ Docker CE 
installedinstalliert (docker --version) - ☐ Docker Compose 
installedinstalliert (docker-compose --version) 
Docker Setup
- ☐ 
/opt/inventar/directoryVerzeichniscreatederstellt - ☐ 
docker-compose.prod.ymlplacedplatziert - ☐ 
.env.productioncreatedmitwithSecretssecretserstellt (NICHT in Git!) - ☐ 
.gitignoreupdatedaktualisiert (.env.production,media/,static/) - ☐ 
Static/Media/opt/inventar/static/directoriesundcreated/opt/inventar/media/Verzeichnisse erstellt - ☐ Docker 
permissionsBerechtigungenconfiguredkonfiguriert 
Nginx Setup
- ☐ 
/etc/nginx/sites-available/inventarConfig 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 
imagesImagesloaded:gepullt (docker)loadcompose< *.tarpull - ☐ Docker Compose 
started:gestartet (docker compose)-f docker-compose.prod.ymlup -d - ☐ Services 
running:laufen (docker compose)-f docker-compose.prod.ymlps - ☐ Django Migrations durchgeführt (
docker compose exec backend python manage.py migrate) - ☐ Static 
filesFilescollected:collected (docker compose)-f docker-compose.prod.ymlexec backend python manage.py collectstatic --noinput - ☐ Superuser erstellt (
docker compose exec backend python manage.py createsuperuser) - ☐ Backend 
healthHealth-Checkcheck:erfolgreich (curl http://127.0.0.1:8000/api/health/ 
Final Verification
☐ All services running stably:docker compose -f docker-compose.prod.yml ps☐ Logs show no errors:)docker compose -f docker-compose.prod.yml logs- ☐ Website 
accessibleerreichbar (HTTPS):https://Your.Domain.here ☐ HTTP redirects to HTTPS☐ SSL Certificate valid:curl -I https://Your.Domain.here☐ API working:curl https://Your.Domain.here/)api/books
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
 - ☐ 
AdminAPIloginEndpointsworkingerreichbar - ☐ Login/Auth funktioniert
 - ☐ Uploads funktionieren
 - ☐ Performance zufriedenstellend
 - ☐ SSL Zertifikat gültig
 
📌 ImportantWichtiger NoticeHinweis
Docker Images zum Download onauf Request:Anfrage:
TheDie Docker containerContainer imagesImages (backend.tar, db-postgres.tar, redis.tar, frontend.tar) aresind requirederforderlich forfür operatingden theBetrieb des Inventory Management System.Systems. TheseDiese imagesImages arewerden providedauf onAnfrage requestbereitgestellt andund mustmüssen bevor uploadeddem toStarten thedes `Systems in das Verzeichnis /opt/inventar/ `directoryhochgeladen before starting the system.werden.
PleaseBitte contactkontaktieren supportSie orden yourSupport administratoroder toIhren obtainAdministrator, theum necessarydie images.notwendigen Images zu erhalten.
Letztes Update: 2. November 2025
Status: ✅ Production-Ready