Skip to main content

Produktive Inventar App Installation

Inventar App Installation - Debian 12 Server

Phase 1: System vorbereiten
sudo apt update && sudo apt upgrade -y
sudo apt install nginx mariadb-server python3 python3-pip python3-venv certbot python3-certbot-nginx redis-server -y
sudo mysql_secure_installation
Phase 2: Datenbank einrichten

MySQL als root-Benutzer anmelden und Datenbank erstellen:

sudo mysql -u root -p
Datenbank, Benutzer und alle Tabellen erstellen:

(Ersetzen Sie 'IhrStarkesDbPasswort' durch ein sicheres Passwort, das Sie sich notieren).

CREATE DATABASE inventar;
CREATE USER 'inventar_user'@'localhost' IDENTIFIED BY 'IhrStarkesDbPasswort';
GRANT ALL PRIVILEGES ON inventar.* TO 'inventar_user'@'localhost';
FLUSH PRIVILEGES;
USE inventar;

CREATE TABLE users (
id INTEGER NOT NULL AUTO_INCREMENT,
username VARCHAR(80) NOT NULL,
password_hash VARCHAR(128) NOT NULL,
role VARCHAR(20) NOT NULL,
is_2fa_enabled BOOLEAN,
totp_secret VARCHAR(32),
PRIMARY KEY (id),
UNIQUE (username)
);
CREATE TABLE categories (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
prefix VARCHAR(3) NOT NULL,
parent_id INTEGER,
PRIMARY KEY (id),
UNIQUE (prefix),
FOREIGN KEY(parent_id) REFERENCES categories (id)
);
CREATE TABLE items (
id INTEGER NOT NULL AUTO_INCREMENT,
item_uid VARCHAR(50) NOT NULL,
name VARCHAR(120) NOT NULL,
quantity INTEGER NOT NULL,
location VARCHAR(120),
brand VARCHAR(80),
color VARCHAR(50),
size VARCHAR(50),
`condition` VARCHAR(50),
price FLOAT,
shipping_size VARCHAR(50),
notes TEXT,
image_file VARCHAR(120),
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE (item_uid)
);
CREATE TABLE logs (
id INTEGER NOT NULL AUTO_INCREMENT,
user_id INTEGER NOT NULL,
item_id INTEGER,
action VARCHAR(100) NOT NULL,
details TEXT,
timestamp DATETIME NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id),
FOREIGN KEY(item_id) REFERENCES items (id)
);
CREATE TABLE item_categories (
item_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
PRIMARY KEY (item_id, category_id),
FOREIGN KEY(item_id) REFERENCES items (id),
FOREIGN KEY(category_id) REFERENCES categories (id)
);

EXIT;
Phase 3: Projektverzeichnis und App-Struktur

Projekt aus dem Download entpacken oder von Git klonen. Dadurch wird die korrekte Ordnerstruktur erstellt:

# Beispiel: Entpacken des Downloads
# unzip inventar-app.zip
# mv inventar-app inventar_projekt
cd inventar_projekt

# Python-Umgebung erstellen
python3 -m venv venv
source venv/bin/activate

# Alle Abhängigkeiten über setup.py installieren
pip install -e .
pip install gunicorn
Phase 4: Anwendungsdateien anpassen

Wichtig: Passen Sie das Datenbank-Passwort in der Konfigurationsdatei an Ihr gewähltes Passwort an.

nano src/inventar/config.py
# in src/inventar/config.py
class Config:
# ...
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://inventar_user:IhrStarkesDbPasswort@localhost/inventar'
# ...
Phase 5: Admin-Benutzer erstellen

Erstellen Sie im Hauptverzeichnis (`inventar_projekt`) eine temporäre Datei nano create_admin.py:

from inventar import create_app, db
from inventar.models import User

# Erstellt eine App-Instanz, um den Kontext zu haben
app = create_app()

# Ihr Admin-Benutzername und Passwort
username = 'admin'
password = 'IhrStarkesAdminPasswort' # Ändern!

with app.app_context():
user = User.query.filter_by(username=username).first()
if user:
user.set_password(password)
user.role = 'admin'
print(f"Benutzer '{username}' aktualisiert und zum Admin gemacht.")
else:
user = User(username=username, role='admin')
user.set_password(password)
db.session.add(user)
print(f"Benutzer '{username}' als Admin neu erstellt.")

db.session.commit()
print("Änderungen gespeichert.")
Admin-Benutzer erstellen und Skript löschen:
# Virtuelle Umgebung muss aktiviert sein
source venv/bin/activate

# Script ausführen
python create_admin.py

# Script aus Sicherheitsgründen löschen
rm create_admin.py
Phase 5.1 Separaten User für die APP erstellen und Rechte vergeben:
# Falls der User noch nicht existiert:
sudo useradd -r -s /bin/false -d /opt/inventar_projekt inventaruser

# Falls der User bereits existiert, Home-Verzeichnis nachträglich setzen:
sudo usermod -d /opt/inventar_projekt inventaruser

# Besitzer und Gruppe für das Projektverzeichnis setzen
sudo chown -R inventaruser:www-data /opt/inventar_projekt

# Berechtigungen setzen
sudo chmod -R 755 /opt/inventar_projekt

# Spezielle Berechtigungen für Python-Files (falls nötig)
sudo chmod -R 644 /opt/inventar_projekt/*.py

# Ausführbare Berechtigung für das venv/bin Verzeichnis
sudo chmod -R 755 /opt/inventar_projekt/venv/bin

# /tmp sollte normalerweise die richtigen Rechte haben, aber falls nötig:
sudo chmod 755 /tmp
Phase 6: Nginx-Konfiguration

Erstellen Sie die Nginx-Konfiguration:

sudo nano /etc/nginx/sites-available/inventar
server {
listen 80;
server_name Ihre.Domain.hier;

location / {
# Temporäre Antwort, nur für Certbot
return 200 'Nginx is working';
}

# Notwendig für Certbot
location /.well-known/acme-challenge/ {
root /var/www/html;
}
}

Site aktivieren:

sudo ln -s /etc/nginx/sites-available/inventar /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Phase 7: Let's Encrypt SSL-Zertifikat erstellen
sudo certbot --nginx -d Ihre.Domain.hier

Certbot wird Ihre Nginx-Datei automatisch für SSL anpassen. Bearbeiten Sie sie danach erneut.

sudo nano /etc/nginx/sites-available/inventar

Ersetzen Sie den Inhalt mit der finalen Konfiguration:

server {
server_name Ihre.Domain.hier;

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

location / {
# Diese Header sind wichtig, damit Ihre Flask-App
# die korrekte IP-Adresse des Clients und das Protokoll (https) kennt.
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;
# Leitet die Anfrage an den Gunicorn-Socket im /tmp Verzeichnis weiter.
proxy_pass http://unix:/tmp/inventar.sock;
}

location /static {
# Liefert statische Dateien (CSS, JS, Bilder) direkt aus.
# Der Pfad muss auf den 'static'-Ordner in Ihrer Anwendungsstruktur zeigen.
alias /opt/inventar_projekt/src/inventar/static;
# Weist den Browser an, diese Dateien für 7 Tage zu cachen.
expires 7d;
}


listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/Ihre.Domain.hier/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/Ihre.Domain.hier/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
}

server {
if ($host = Ihre.Domain.hier) {
return 301 https://$host$request_uri;
} # managed by Certbot

listen 80;
server_name Ihre.Domain.hier;
return 404; # managed by Certbot
}
Phase 8: Systemd Service einrichten
sudo nano /etc/systemd/system/inventar-app.service
[Unit]
Description=Gunicorn instance to serve Inventar App
After=network.target

[Service]
User=inventaruser
Group=www-data
WorkingDirectory=/opt/inventar_projekt
Environment="PATH=/opt/inventar_projekt/venv/bin:/usr/bin:/bin"
# Socket mit korrekten Berechtigungen erstellen
ExecStart=/opt/inventar_projekt/venv/bin/gunicorn --workers 3 --bind unix:/tmp/inventar.sock --umask 0 wsgi:app
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Service aktivieren:

sudo systemctl daemon-reload
sudo systemctl start inventar-app
sudo systemctl enable inventar-app
Phase 9: Finale Schritte
# Service-Status überprüfen
sudo systemctl status inventar-app.service
sudo systemctl status nginx

# Nginx-Konfiguration testen und neu laden
sudo nginx -t
sudo systemctl reload nginx
Wichtige Hinweise:
  • Domain: Stellen Sie sicher, dass Ihre Domain auf die IP-Adresse Ihres Servers zeigt.
  • Firewall: Öffnen Sie die Ports 80 (HTTP) und 443 (HTTPS).
  • Backup: Sichern Sie regelmäßig Ihre Datenbank und den `src/inventar/static/uploads`-Ordner.

Troubleshooting:

# Gunicorn/App Logs anzeigen
sudo journalctl -u inventar-app.service -f

# Nginx Logs anzeigen
sudo tail -f /var/log/nginx/error.log