1069 lines
29 KiB
Bash
1069 lines
29 KiB
Bash
#!/bin/bash
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Docker-Setup-Skript für MYP (Manage Your Printers) System
|
|
=========================================================
|
|
|
|
Automatisierte Installation und Deployment des 3D-Drucker-Management-Systems
|
|
für Mercedes-Benz TBA Marienfelde mit Docker-Containerisierung.
|
|
|
|
Funktionen:
|
|
- System-Update (apt update/upgrade)
|
|
- Docker & Docker Compose Installation (proprietäre Debian-Version)
|
|
- Automatische Bereinigung bestehender Container/Images
|
|
- Multi-Port-Deployment (HTTP:80, HTTPS:443, DEV:5000)
|
|
- Vollständige Neuaufsetzung bei jeder Ausführung
|
|
|
|
Autor: Till Tomczak - Mercedes-Benz TBA Marienfelde
|
|
Datum: 2025-06-20
|
|
"""
|
|
|
|
set -e # Exit bei Fehlern
|
|
set -u # Exit bei undefinierten Variablen
|
|
|
|
# ===== KONFIGURATION =====
|
|
|
|
SCRIPT_NAME="MYP Docker Setup"
|
|
PROJECT_NAME="myp-system"
|
|
LOG_FILE="/tmp/myp-docker-setup.log"
|
|
DOCKER_COMPOSE_VERSION="2.21.0"
|
|
|
|
# Kiosk-Modus Konfiguration
|
|
KIOSK_URL="http://localhost:80"
|
|
DESKTOP_PATH="/home/$SUDO_USER/Desktop"
|
|
AUTOSTART_PATH="/home/$SUDO_USER/.config/autostart"
|
|
|
|
# Farben für Output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
PURPLE='\033[0;35m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# ===== LOGGING-FUNKTIONEN =====
|
|
|
|
log() {
|
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
info() {
|
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO: $1${NC}" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
header() {
|
|
echo -e "\n${PURPLE}================================${NC}"
|
|
echo -e "${PURPLE}$1${NC}"
|
|
echo -e "${PURPLE}================================${NC}\n"
|
|
}
|
|
|
|
# ===== SYSTEM-PRÜFUNGEN =====
|
|
|
|
check_system() {
|
|
header "System-Prüfungen"
|
|
|
|
# Root-Rechte prüfen
|
|
if [[ $EUID -ne 0 ]]; then
|
|
error "Dieses Skript muss als root ausgeführt werden!"
|
|
error "Bitte verwenden: sudo $0"
|
|
exit 1
|
|
fi
|
|
|
|
# Debian/Ubuntu prüfen
|
|
if ! command -v apt &> /dev/null; then
|
|
error "Dieses System scheint kein Debian/Ubuntu zu sein (apt nicht gefunden)"
|
|
exit 1
|
|
fi
|
|
|
|
# Architektur prüfen
|
|
ARCH=$(dpkg --print-architecture)
|
|
log "System-Architektur: $ARCH"
|
|
|
|
# Verfügbarer Speicher
|
|
DISK_SPACE=$(df -h / | awk 'NR==2{print $4}')
|
|
log "Verfügbarer Speicherplatz: $DISK_SPACE"
|
|
|
|
log "✅ System-Prüfungen erfolgreich"
|
|
}
|
|
|
|
# ===== DOCKER BEREINIGUNG =====
|
|
|
|
cleanup_docker() {
|
|
header "Docker-Bereinigung"
|
|
|
|
info "Stoppe und entferne bestehende MYP-Container..."
|
|
|
|
# Alle MYP-Container stoppen
|
|
if docker ps -a --format "table {{.Names}}" | grep -q "${PROJECT_NAME}"; then
|
|
docker ps -a --format "table {{.Names}}" | grep "${PROJECT_NAME}" | xargs -r docker stop
|
|
docker ps -a --format "table {{.Names}}" | grep "${PROJECT_NAME}" | xargs -r docker rm
|
|
log "Bestehende MYP-Container entfernt"
|
|
else
|
|
info "Keine bestehenden MYP-Container gefunden"
|
|
fi
|
|
|
|
# MYP-Images entfernen
|
|
if docker images --format "table {{.Repository}}" | grep -q "${PROJECT_NAME}"; then
|
|
docker images --format "table {{.Repository}}" | grep "${PROJECT_NAME}" | xargs -r docker rmi -f
|
|
log "Bestehende MYP-Images entfernt"
|
|
else
|
|
info "Keine bestehenden MYP-Images gefunden"
|
|
fi
|
|
|
|
# Docker-Netzwerke bereinigen
|
|
if docker network ls --format "table {{.Name}}" | grep -q "${PROJECT_NAME}"; then
|
|
docker network ls --format "table {{.Name}}" | grep "${PROJECT_NAME}" | xargs -r docker network rm
|
|
log "Bestehende MYP-Netzwerke entfernt"
|
|
fi
|
|
|
|
# Volumes bereinigen (optional - auskommentiert um Daten zu behalten)
|
|
# if docker volume ls --format "table {{.Name}}" | grep -q "${PROJECT_NAME}"; then
|
|
# docker volume ls --format "table {{.Name}}" | grep "${PROJECT_NAME}" | xargs -r docker volume rm
|
|
# log "Bestehende MYP-Volumes entfernt"
|
|
# fi
|
|
|
|
# System-weite Docker-Bereinigung
|
|
info "Führe Docker-System-Bereinigung durch..."
|
|
docker system prune -f --volumes 2>/dev/null || true
|
|
|
|
log "✅ Docker-Bereinigung abgeschlossen"
|
|
}
|
|
|
|
# ===== SYSTEM UPDATE =====
|
|
|
|
update_system() {
|
|
header "System-Update"
|
|
|
|
log "Aktualisiere Paket-Listen..."
|
|
apt update -qq
|
|
|
|
log "Führe System-Upgrade durch..."
|
|
DEBIAN_FRONTEND=noninteractive apt upgrade -y -qq
|
|
|
|
log "Installiere erforderliche Basis-Pakete..."
|
|
DEBIAN_FRONTEND=noninteractive apt install -y -qq \
|
|
curl \
|
|
wget \
|
|
gnupg \
|
|
lsb-release \
|
|
ca-certificates \
|
|
software-properties-common \
|
|
apt-transport-https \
|
|
chromium-browser \
|
|
xorg \
|
|
openbox \
|
|
unclutter \
|
|
xdotool \
|
|
wmctrl
|
|
|
|
log "✅ System-Update abgeschlossen"
|
|
}
|
|
|
|
# ===== DOCKER INSTALLATION =====
|
|
|
|
install_docker() {
|
|
header "Docker Installation"
|
|
|
|
# Prüfe ob Docker bereits installiert ist
|
|
if command -v docker &> /dev/null; then
|
|
DOCKER_VERSION=$(docker --version)
|
|
warn "Docker ist bereits installiert: $DOCKER_VERSION"
|
|
info "Entferne bestehende Docker-Installation für Neuinstallation..."
|
|
|
|
# Alte Docker-Pakete entfernen
|
|
apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
|
|
fi
|
|
|
|
log "Füge Docker GPG-Schlüssel hinzu..."
|
|
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
|
|
|
log "Füge Docker-Repository hinzu..."
|
|
echo "deb [arch=$ARCH signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
|
|
log "Aktualisiere Paket-Listen für Docker..."
|
|
apt update -qq
|
|
|
|
log "Installiere Docker CE (Community Edition)..."
|
|
DEBIAN_FRONTEND=noninteractive apt install -y -qq \
|
|
docker-ce \
|
|
docker-ce-cli \
|
|
containerd.io \
|
|
docker-buildx-plugin
|
|
|
|
# Docker-Service starten und aktivieren
|
|
systemctl start docker
|
|
systemctl enable docker
|
|
|
|
# Docker-Gruppe für aktuellen Benutzer
|
|
if [ -n "${SUDO_USER:-}" ]; then
|
|
usermod -aG docker $SUDO_USER
|
|
log "Benutzer $SUDO_USER zur Docker-Gruppe hinzugefügt"
|
|
fi
|
|
|
|
# Docker-Version prüfen
|
|
DOCKER_VERSION=$(docker --version)
|
|
log "✅ Docker erfolgreich installiert: $DOCKER_VERSION"
|
|
}
|
|
|
|
# ===== DOCKER COMPOSE INSTALLATION =====
|
|
|
|
install_docker_compose() {
|
|
header "Docker Compose Installation"
|
|
|
|
# Prüfe ob Docker Compose bereits installiert ist
|
|
if command -v docker-compose &> /dev/null; then
|
|
COMPOSE_VERSION=$(docker-compose --version)
|
|
warn "Docker Compose ist bereits installiert: $COMPOSE_VERSION"
|
|
fi
|
|
|
|
log "Lade Docker Compose herunter..."
|
|
curl -L "https://github.com/docker/compose/releases/download/v$DOCKER_COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
|
|
|
log "Setze Ausführungsrechte für Docker Compose..."
|
|
chmod +x /usr/local/bin/docker-compose
|
|
|
|
# Symbolischer Link für bessere Kompatibilität
|
|
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
|
|
|
|
# Docker Compose-Version prüfen
|
|
COMPOSE_VERSION=$(docker-compose --version)
|
|
log "✅ Docker Compose erfolgreich installiert: $COMPOSE_VERSION"
|
|
}
|
|
|
|
# ===== DOCKER-DATEIEN ERSTELLEN =====
|
|
|
|
create_docker_files() {
|
|
header "Docker-Dateien erstellen"
|
|
|
|
# Hauptverzeichnis für Docker-Dateien
|
|
DOCKER_DIR="./docker"
|
|
mkdir -p "$DOCKER_DIR"
|
|
|
|
info "Erstelle Dockerfile..."
|
|
cat > "$DOCKER_DIR/Dockerfile" << 'EOF'
|
|
# Multi-Stage Dockerfile für MYP (Manage Your Printers) System
|
|
# Mercedes-Benz TBA Marienfelde - 3D-Drucker-Management
|
|
|
|
# ===== STAGE 1: Python Dependencies Builder =====
|
|
FROM python:3.11-slim-bullseye as python-builder
|
|
|
|
LABEL maintainer="Till Tomczak <till.tomczak@mercedes-benz.com>"
|
|
LABEL description="MYP - 3D Printer Management System for Mercedes-Benz"
|
|
LABEL version="1.0"
|
|
|
|
# Build-Dependencies installieren
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
gcc \
|
|
python3-dev \
|
|
libffi-dev \
|
|
libssl-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Python-Dependencies in virtuelle Umgebung installieren
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Requirements kopieren und installieren
|
|
COPY backend/requirements.txt /tmp/requirements.txt
|
|
RUN pip install --upgrade pip wheel setuptools && \
|
|
pip install --no-cache-dir -r /tmp/requirements.txt
|
|
|
|
# ===== STAGE 2: Node.js Builder für Frontend-Assets =====
|
|
FROM node:18-slim as node-builder
|
|
|
|
# Frontend-Dependencies und Build
|
|
WORKDIR /app
|
|
COPY backend/package*.json ./
|
|
RUN npm ci --only=production && npm cache clean --force
|
|
|
|
# TailwindCSS Build
|
|
COPY backend/static ./static/
|
|
COPY backend/templates ./templates/
|
|
RUN npm run build:css 2>/dev/null || echo "CSS Build übersprungen"
|
|
|
|
# ===== STAGE 3: Production Runtime =====
|
|
FROM python:3.11-slim-bullseye as production
|
|
|
|
# Umgebungsvariablen
|
|
ENV PYTHONUNBUFFERED=1
|
|
ENV PYTHONDONTWRITEBYTECODE=1
|
|
ENV FLASK_ENV=production
|
|
ENV MYP_ENV=production
|
|
ENV PYTHONPATH=/app
|
|
|
|
# System-Dependencies für Production
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl \
|
|
ping \
|
|
iputils-ping \
|
|
sqlite3 \
|
|
supervisor \
|
|
nginx \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Arbeitsverzeichnis erstellen
|
|
WORKDIR /app
|
|
|
|
# Python virtuelle Umgebung kopieren
|
|
COPY --from=python-builder /opt/venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Frontend-Assets kopieren
|
|
COPY --from=node-builder /app/static/css/ /app/static/css/
|
|
|
|
# Anwendungs-Code kopieren
|
|
COPY backend/ /app/
|
|
|
|
# Verzeichnisse für Logs, Uploads, etc. erstellen
|
|
RUN mkdir -p /app/logs /app/uploads /app/static/uploads /app/instance && \
|
|
chmod -R 755 /app/logs /app/uploads /app/static/uploads /app/instance
|
|
|
|
# SSL-Zertifikate-Verzeichnis erstellen
|
|
RUN mkdir -p /app/ssl && chmod 755 /app/ssl
|
|
|
|
# Nginx-Konfiguration
|
|
COPY docker/nginx.conf /etc/nginx/sites-available/default
|
|
|
|
# Supervisor-Konfiguration
|
|
COPY docker/supervisord.conf /etc/supervisor/conf.d/myp.conf
|
|
|
|
# Benutzer für Security erstellen
|
|
RUN useradd --create-home --shell /bin/bash myp && \
|
|
chown -R myp:myp /app && \
|
|
usermod -aG www-data myp
|
|
|
|
# Ports exposieren
|
|
EXPOSE 80 443 5000
|
|
|
|
# Health Check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
|
CMD curl -f http://localhost:5000/health || exit 1
|
|
|
|
# Startup-Skript
|
|
COPY docker/docker-entrypoint.sh /usr/local/bin/
|
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
|
|
|
# Als myp-Benutzer ausführen
|
|
USER myp
|
|
|
|
# Entry Point
|
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
|
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/myp.conf"]
|
|
EOF
|
|
|
|
info "Erstelle Docker Compose..."
|
|
cat > "$DOCKER_DIR/docker-compose.yml" << 'EOF'
|
|
# Docker Compose für MYP (Manage Your Printers) System
|
|
# Mercedes-Benz TBA Marienfelde - Multi-Port-Deployment
|
|
|
|
version: '3.8'
|
|
|
|
services:
|
|
# ===== MYP HTTP Service (Port 80) =====
|
|
myp-http:
|
|
build:
|
|
context: ..
|
|
dockerfile: docker/Dockerfile
|
|
target: production
|
|
container_name: myp-system-http
|
|
hostname: myp-http
|
|
restart: unless-stopped
|
|
environment:
|
|
- FLASK_ENV=production
|
|
- MYP_ENV=production
|
|
- MYP_PORT=80
|
|
- MYP_HOST=0.0.0.0
|
|
- MYP_SSL=false
|
|
ports:
|
|
- "80:80"
|
|
volumes:
|
|
- myp-data:/app/instance
|
|
- myp-logs:/app/logs
|
|
- myp-uploads:/app/uploads
|
|
- myp-ssl:/app/ssl
|
|
networks:
|
|
- myp-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
|
|
# ===== MYP HTTPS Service (Port 443) =====
|
|
myp-https:
|
|
build:
|
|
context: ..
|
|
dockerfile: docker/Dockerfile
|
|
target: production
|
|
container_name: myp-system-https
|
|
hostname: myp-https
|
|
restart: unless-stopped
|
|
environment:
|
|
- FLASK_ENV=production
|
|
- MYP_ENV=production
|
|
- MYP_PORT=443
|
|
- MYP_HOST=0.0.0.0
|
|
- MYP_SSL=true
|
|
ports:
|
|
- "443:443"
|
|
volumes:
|
|
- myp-data:/app/instance
|
|
- myp-logs:/app/logs
|
|
- myp-uploads:/app/uploads
|
|
- myp-ssl:/app/ssl
|
|
networks:
|
|
- myp-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-k", "-f", "https://localhost:443/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
|
|
# ===== MYP Development Service (Port 5000) =====
|
|
myp-dev:
|
|
build:
|
|
context: ..
|
|
dockerfile: docker/Dockerfile
|
|
target: production
|
|
container_name: myp-system-dev
|
|
hostname: myp-dev
|
|
restart: unless-stopped
|
|
environment:
|
|
- FLASK_ENV=development
|
|
- MYP_ENV=development
|
|
- MYP_PORT=5000
|
|
- MYP_HOST=0.0.0.0
|
|
- MYP_SSL=false
|
|
- MYP_DEBUG=true
|
|
ports:
|
|
- "5000:5000"
|
|
volumes:
|
|
- myp-data:/app/instance
|
|
- myp-logs:/app/logs
|
|
- myp-uploads:/app/uploads
|
|
- myp-ssl:/app/ssl
|
|
# Development: Code-Mounting für Live-Reload
|
|
- ../backend:/app:ro
|
|
networks:
|
|
- myp-network
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 60s
|
|
|
|
# ===== VOLUMES =====
|
|
volumes:
|
|
myp-data:
|
|
driver: local
|
|
name: myp-system-data
|
|
myp-logs:
|
|
driver: local
|
|
name: myp-system-logs
|
|
myp-uploads:
|
|
driver: local
|
|
name: myp-system-uploads
|
|
myp-ssl:
|
|
driver: local
|
|
name: myp-system-ssl
|
|
|
|
# ===== NETWORKS =====
|
|
networks:
|
|
myp-network:
|
|
driver: bridge
|
|
name: myp-system-network
|
|
ipam:
|
|
config:
|
|
- subnet: 172.20.0.0/16
|
|
EOF
|
|
|
|
info "Erstelle Nginx-Konfiguration..."
|
|
cat > "$DOCKER_DIR/nginx.conf" << 'EOF'
|
|
# Nginx-Konfiguration für MYP System
|
|
# Mercedes-Benz TBA Marienfelde
|
|
|
|
server {
|
|
listen 80 default_server;
|
|
listen [::]:80 default_server;
|
|
|
|
server_name _;
|
|
client_max_body_size 100M;
|
|
|
|
# Security Headers
|
|
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 "strict-origin-when-cross-origin" always;
|
|
|
|
# Static Files
|
|
location /static/ {
|
|
alias /app/static/;
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
# Uploads
|
|
location /uploads/ {
|
|
alias /app/uploads/;
|
|
expires 1h;
|
|
}
|
|
|
|
# Health Check
|
|
location /health {
|
|
proxy_pass http://127.0.0.1:5000/health;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
# Application
|
|
location / {
|
|
proxy_pass http://127.0.0.1:5000;
|
|
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;
|
|
proxy_connect_timeout 60s;
|
|
proxy_send_timeout 60s;
|
|
proxy_read_timeout 60s;
|
|
}
|
|
}
|
|
|
|
# HTTPS Configuration (wenn SSL aktiviert)
|
|
server {
|
|
listen 443 ssl http2 default_server;
|
|
listen [::]:443 ssl http2 default_server;
|
|
|
|
server_name _;
|
|
|
|
# SSL Configuration
|
|
ssl_certificate /app/ssl/server.crt;
|
|
ssl_certificate_key /app/ssl/server.key;
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
|
ssl_prefer_server_ciphers off;
|
|
|
|
# Rest wie HTTP
|
|
client_max_body_size 100M;
|
|
|
|
location /static/ {
|
|
alias /app/static/;
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
}
|
|
|
|
location /uploads/ {
|
|
alias /app/uploads/;
|
|
expires 1h;
|
|
}
|
|
|
|
location /health {
|
|
proxy_pass http://127.0.0.1:5000/health;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location / {
|
|
proxy_pass http://127.0.0.1:5000;
|
|
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;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
info "Erstelle Supervisor-Konfiguration..."
|
|
cat > "$DOCKER_DIR/supervisord.conf" << 'EOF'
|
|
[supervisord]
|
|
nodaemon=true
|
|
user=root
|
|
logfile=/app/logs/supervisord.log
|
|
pidfile=/tmp/supervisord.pid
|
|
|
|
[program:myp-app]
|
|
command=/opt/venv/bin/python app.py --host=%(ENV_MYP_HOST)s --port=%(ENV_MYP_PORT)s
|
|
directory=/app
|
|
user=myp
|
|
autostart=true
|
|
autorestart=true
|
|
redirect_stderr=true
|
|
stdout_logfile=/app/logs/myp-app.log
|
|
stdout_logfile_maxbytes=10MB
|
|
stdout_logfile_backups=3
|
|
|
|
[program:nginx]
|
|
command=/usr/sbin/nginx -g "daemon off;"
|
|
autostart=true
|
|
autorestart=true
|
|
redirect_stderr=true
|
|
stdout_logfile=/app/logs/nginx.log
|
|
stdout_logfile_maxbytes=10MB
|
|
stdout_logfile_backups=3
|
|
EOF
|
|
|
|
info "Erstelle Docker-Entrypoint..."
|
|
cat > "$DOCKER_DIR/docker-entrypoint.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# Docker Entrypoint für MYP System
|
|
|
|
set -e
|
|
|
|
echo "🚀 MYP System startet in Docker-Container..."
|
|
|
|
# SSL-Zertifikate generieren falls nicht vorhanden
|
|
if [ "${MYP_SSL:-false}" = "true" ] && [ ! -f /app/ssl/server.crt ]; then
|
|
echo "🔐 Generiere SSL-Zertifikate..."
|
|
mkdir -p /app/ssl
|
|
openssl req -x509 -newkey rsa:4096 -keyout /app/ssl/server.key -out /app/ssl/server.crt -days 365 -nodes -subj "/C=DE/ST=Berlin/L=Berlin/O=Mercedes-Benz/OU=TBA-Marienfelde/CN=myp-system"
|
|
chmod 600 /app/ssl/server.key
|
|
chmod 644 /app/ssl/server.crt
|
|
fi
|
|
|
|
# Datenbank initialisieren
|
|
echo "🗄️ Initialisiere Datenbank..."
|
|
cd /app
|
|
python -c "from models import init_database; init_database()" || echo "Datenbank bereits initialisiert"
|
|
|
|
# Log-Verzeichnisse erstellen
|
|
mkdir -p /app/logs/app /app/logs/admin /app/logs/scheduler /app/logs/hardware_integration
|
|
|
|
# Umgebung anzeigen
|
|
echo "📊 Container-Informationen:"
|
|
echo " 🏷️ Container: $(hostname)"
|
|
echo " 🌐 Port: ${MYP_PORT:-5000}"
|
|
echo " 🔒 SSL: ${MYP_SSL:-false}"
|
|
echo " 🛠️ Umgebung: ${MYP_ENV:-production}"
|
|
|
|
# Standard-Befehl ausführen
|
|
exec "$@"
|
|
EOF
|
|
|
|
info "Erstelle .dockerignore..."
|
|
cat > "$DOCKER_DIR/../.dockerignore" << 'EOF'
|
|
# Docker Ignore für MYP System
|
|
|
|
# Git
|
|
.git
|
|
.gitignore
|
|
|
|
# Python
|
|
__pycache__/
|
|
*.py[cod]
|
|
*$py.class
|
|
*.so
|
|
.Python
|
|
build/
|
|
develop-eggs/
|
|
dist/
|
|
downloads/
|
|
eggs/
|
|
.eggs/
|
|
lib/
|
|
lib64/
|
|
parts/
|
|
sdist/
|
|
var/
|
|
wheels/
|
|
share/python-wheels/
|
|
*.egg-info/
|
|
.installed.cfg
|
|
*.egg
|
|
|
|
# Virtual Environments
|
|
venv/
|
|
env/
|
|
ENV/
|
|
|
|
# IDE
|
|
.vscode/
|
|
.idea/
|
|
*.swp
|
|
*.swo
|
|
|
|
# OS
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Logs (außer Verzeichnisstruktur)
|
|
logs/*.log
|
|
logs/**/*.log
|
|
|
|
# Uploads (außer Verzeichnisstruktur)
|
|
uploads/*
|
|
!uploads/.gitkeep
|
|
|
|
# Temporäre Dateien
|
|
*.tmp
|
|
*.temp
|
|
.cache/
|
|
|
|
# Node.js
|
|
node_modules/
|
|
npm-debug.log*
|
|
|
|
# SSL Zertifikate
|
|
ssl/
|
|
*.pem
|
|
*.crt
|
|
*.key
|
|
|
|
# Database
|
|
*.db
|
|
*.sqlite
|
|
*.sqlite3
|
|
|
|
# Docker
|
|
docker-compose.override.yml
|
|
Dockerfile.dev
|
|
EOF
|
|
|
|
# Berechtigung für Entrypoint setzen
|
|
chmod +x "$DOCKER_DIR/docker-entrypoint.sh"
|
|
|
|
log "✅ Docker-Dateien erfolgreich erstellt in: $DOCKER_DIR"
|
|
}
|
|
|
|
# ===== KIOSK-MODUS SETUP =====
|
|
|
|
setup_kiosk_mode() {
|
|
header "Kiosk-Modus Setup"
|
|
|
|
if [ -z "${SUDO_USER:-}" ]; then
|
|
warn "SUDO_USER nicht gesetzt - Kiosk-Setup übersprungen"
|
|
return 0
|
|
fi
|
|
|
|
info "Erstelle Kiosk-Skripte für Benutzer: $SUDO_USER"
|
|
|
|
# Kiosk-Start-Skript erstellen
|
|
cat > "/home/$SUDO_USER/start-myp-kiosk.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# MYP Kiosk-Modus Starter
|
|
# Mercedes-Benz TBA Marienfelde
|
|
|
|
# Warte bis Docker-Container verfügbar sind
|
|
echo "🚀 Starte MYP Kiosk-Modus..."
|
|
sleep 5
|
|
|
|
# Prüfe ob Container laufen
|
|
if ! docker ps --format "table {{.Names}}" | grep -q myp-system; then
|
|
echo "⚠️ MYP Container nicht aktiv - starte Docker Compose..."
|
|
cd /home/$(whoami)/myp-system 2>/dev/null || cd /opt/myp-system 2>/dev/null || echo "❌ MYP Verzeichnis nicht gefunden"
|
|
docker-compose up -d 2>/dev/null || echo "❌ Docker Compose fehlgeschlagen"
|
|
sleep 10
|
|
fi
|
|
|
|
# Warte auf Service-Verfügbarkeit
|
|
echo "⏳ Warte auf MYP Service..."
|
|
timeout=60
|
|
counter=0
|
|
while [ $counter -lt $timeout ]; do
|
|
if curl -f http://localhost:80/ >/dev/null 2>&1; then
|
|
echo "✅ MYP Service verfügbar"
|
|
break
|
|
fi
|
|
sleep 1
|
|
counter=$((counter + 1))
|
|
done
|
|
|
|
if [ $counter -eq $timeout ]; then
|
|
echo "❌ MYP Service nicht erreichbar nach ${timeout}s"
|
|
exit 1
|
|
fi
|
|
|
|
# Kiosk-Umgebung vorbereiten
|
|
export DISPLAY=:0
|
|
xset s off # Screensaver deaktivieren
|
|
xset -dpms # Power Management deaktivieren
|
|
xset s noblank # Bildschirm-Blanking deaktivieren
|
|
|
|
# Mauszeiger verstecken
|
|
unclutter -idle 0.5 -root &
|
|
|
|
# Chromium im Kiosk-Modus starten
|
|
echo "🌐 Starte Chromium Kiosk-Modus..."
|
|
chromium-browser \
|
|
--kiosk \
|
|
--no-sandbox \
|
|
--disable-web-security \
|
|
--disable-features=TranslateUI \
|
|
--disable-ipc-flooding-protection \
|
|
--disable-renderer-backgrounding \
|
|
--disable-backgrounding-occluded-windows \
|
|
--disable-background-timer-throttling \
|
|
--disable-background-networking \
|
|
--disable-sync \
|
|
--disable-translate \
|
|
--disable-extensions \
|
|
--disable-default-apps \
|
|
--disable-infobars \
|
|
--disable-notifications \
|
|
--disable-session-crashed-bubble \
|
|
--disable-component-update \
|
|
--no-first-run \
|
|
--fast \
|
|
--fast-start \
|
|
--disable-dev-shm-usage \
|
|
--memory-pressure-off \
|
|
--max_old_space_size=100 \
|
|
--aggressive-cache-discard \
|
|
--autoplay-policy=no-user-gesture-required \
|
|
--user-data-dir=/tmp/chrome-kiosk \
|
|
--app=http://localhost:80 \
|
|
2>/dev/null &
|
|
|
|
CHROME_PID=$!
|
|
echo "🎯 Chromium Kiosk gestartet (PID: $CHROME_PID)"
|
|
|
|
# Warte auf Chromium-Ende oder Signal
|
|
wait $CHROME_PID
|
|
echo "🏁 Kiosk-Modus beendet"
|
|
EOF
|
|
|
|
chmod +x "/home/$SUDO_USER/start-myp-kiosk.sh"
|
|
chown $SUDO_USER:$SUDO_USER "/home/$SUDO_USER/start-myp-kiosk.sh"
|
|
|
|
# Desktop-Verzeichnis erstellen falls nicht vorhanden
|
|
mkdir -p "$DESKTOP_PATH"
|
|
chown $SUDO_USER:$SUDO_USER "$DESKTOP_PATH"
|
|
|
|
# Desktop-Icon erstellen
|
|
cat > "$DESKTOP_PATH/MYP-Kiosk.desktop" << EOF
|
|
[Desktop Entry]
|
|
Version=1.0
|
|
Type=Application
|
|
Name=MYP Kiosk
|
|
Comment=Mercedes-Benz 3D-Drucker Management (Kiosk-Modus)
|
|
Icon=applications-internet
|
|
Exec=/home/$SUDO_USER/start-myp-kiosk.sh
|
|
Terminal=false
|
|
StartupNotify=true
|
|
Categories=Application;Network;
|
|
Keywords=MYP;Mercedes;Drucker;3D;Kiosk;
|
|
EOF
|
|
|
|
chmod +x "$DESKTOP_PATH/MYP-Kiosk.desktop"
|
|
chown $SUDO_USER:$SUDO_USER "$DESKTOP_PATH/MYP-Kiosk.desktop"
|
|
|
|
# System-Container Desktop-Icon
|
|
cat > "$DESKTOP_PATH/MYP-Container.desktop" << EOF
|
|
[Desktop Entry]
|
|
Version=1.0
|
|
Type=Application
|
|
Name=MYP Container
|
|
Comment=Mercedes-Benz MYP Docker Container Management
|
|
Icon=applications-system
|
|
Exec=x-terminal-emulator -e 'cd $(find /home /opt -name "docker-compose.yml" -path "*/myp*" -exec dirname {} \; 2>/dev/null | head -1) && echo "🐳 MYP Container Management" && echo "Verfügbare Befehle:" && echo " docker-compose ps - Status anzeigen" && echo " docker-compose logs -f - Logs verfolgen" && echo " docker-compose restart - Neustart" && echo " docker-compose down - Stoppen" && echo " docker-compose up -d - Starten" && echo "" && bash'
|
|
Terminal=false
|
|
StartupNotify=true
|
|
Categories=Application;System;
|
|
Keywords=MYP;Docker;Container;Management;
|
|
EOF
|
|
|
|
chmod +x "$DESKTOP_PATH/MYP-Container.desktop"
|
|
chown $SUDO_USER:$SUDO_USER "$DESKTOP_PATH/MYP-Container.desktop"
|
|
|
|
# Autostart-Verzeichnis erstellen
|
|
mkdir -p "$AUTOSTART_PATH"
|
|
chown -R $SUDO_USER:$SUDO_USER "$AUTOSTART_PATH"
|
|
|
|
# Optional: Autostart für Kiosk-Modus (auskommentiert)
|
|
cat > "$AUTOSTART_PATH/myp-kiosk.desktop.disabled" << EOF
|
|
[Desktop Entry]
|
|
Type=Application
|
|
Name=MYP Kiosk Autostart
|
|
Comment=Startet MYP automatisch im Kiosk-Modus
|
|
Exec=/home/$SUDO_USER/start-myp-kiosk.sh
|
|
Hidden=false
|
|
NoDisplay=false
|
|
X-GNOME-Autostart-enabled=true
|
|
EOF
|
|
|
|
chown $SUDO_USER:$SUDO_USER "$AUTOSTART_PATH/myp-kiosk.desktop.disabled"
|
|
|
|
# Kiosk-Stop-Skript
|
|
cat > "/home/$SUDO_USER/stop-myp-kiosk.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# MYP Kiosk-Modus Stopper
|
|
|
|
echo "🛑 Stoppe MYP Kiosk-Modus..."
|
|
|
|
# Chromium-Prozesse beenden
|
|
pkill -f "chromium.*kiosk.*localhost" 2>/dev/null
|
|
pkill -f "chromium.*app=http://localhost" 2>/dev/null
|
|
|
|
# Unclutter beenden
|
|
pkill unclutter 2>/dev/null
|
|
|
|
# Screensaver wieder aktivieren
|
|
export DISPLAY=:0
|
|
xset s on 2>/dev/null
|
|
xset +dpms 2>/dev/null
|
|
|
|
echo "✅ Kiosk-Modus gestoppt"
|
|
EOF
|
|
|
|
chmod +x "/home/$SUDO_USER/stop-myp-kiosk.sh"
|
|
chown $SUDO_USER:$SUDO_USER "/home/$SUDO_USER/stop-myp-kiosk.sh"
|
|
|
|
# Kiosk-Neustart-Skript
|
|
cat > "/home/$SUDO_USER/restart-myp-kiosk.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# MYP Kiosk-Modus Neustart
|
|
|
|
echo "🔄 Starte MYP Kiosk-Modus neu..."
|
|
|
|
# Stoppen
|
|
./stop-myp-kiosk.sh
|
|
|
|
# Warten
|
|
sleep 3
|
|
|
|
# Starten
|
|
./start-myp-kiosk.sh &
|
|
|
|
echo "✅ Kiosk-Modus neugestartet"
|
|
EOF
|
|
|
|
chmod +x "/home/$SUDO_USER/restart-myp-kiosk.sh"
|
|
chown $SUDO_USER:$SUDO_USER "/home/$SUDO_USER/restart-myp-kiosk.sh"
|
|
|
|
log "✅ Kiosk-Modus Setup abgeschlossen"
|
|
log "📍 Desktop-Icons erstellt in: $DESKTOP_PATH"
|
|
log "🚀 Kiosk-Skripte verfügbar in: /home/$SUDO_USER/"
|
|
}
|
|
|
|
# ===== DOCKER CONTAINER DEPLOYMENT =====
|
|
|
|
deploy_containers() {
|
|
header "Container-Deployment"
|
|
|
|
cd ./docker
|
|
|
|
info "Baue Docker-Images..."
|
|
docker-compose build --no-cache --parallel
|
|
|
|
info "Starte Container in Daemon-Modus..."
|
|
docker-compose up -d
|
|
|
|
log "Warte auf Container-Start..."
|
|
sleep 10
|
|
|
|
# Container-Status prüfen
|
|
info "Container-Status:"
|
|
docker-compose ps
|
|
|
|
# Health-Checks
|
|
info "Führe Health-Checks durch..."
|
|
|
|
# HTTP (Port 80)
|
|
if curl -f http://localhost:80/health 2>/dev/null; then
|
|
log "✅ HTTP Service (Port 80): Gesund"
|
|
else
|
|
warn "⚠️ HTTP Service (Port 80): Nicht erreichbar"
|
|
fi
|
|
|
|
# HTTPS (Port 443) - mit SSL-Ignore
|
|
if curl -k -f https://localhost:443/health 2>/dev/null; then
|
|
log "✅ HTTPS Service (Port 443): Gesund"
|
|
else
|
|
warn "⚠️ HTTPS Service (Port 443): Nicht erreichbar"
|
|
fi
|
|
|
|
# Development (Port 5000)
|
|
if curl -f http://localhost:5000/health 2>/dev/null; then
|
|
log "✅ Development Service (Port 5000): Gesund"
|
|
else
|
|
warn "⚠️ Development Service (Port 5000): Nicht erreichbar"
|
|
fi
|
|
|
|
log "✅ Container-Deployment abgeschlossen"
|
|
}
|
|
|
|
# ===== ABSCHLUSS-INFORMATIONEN =====
|
|
|
|
show_completion_info() {
|
|
header "Setup abgeschlossen!"
|
|
|
|
echo -e "${GREEN}🎉 MYP Docker-Setup erfolgreich abgeschlossen!${NC}\n"
|
|
|
|
echo -e "${BLUE}📊 System-Informationen:${NC}"
|
|
echo -e " 🐳 Docker Version: $(docker --version)"
|
|
echo -e " 🔧 Docker Compose: $(docker-compose --version)"
|
|
echo -e " 📦 Aktive Container: $(docker ps --format 'table {{.Names}}' | grep myp-system | wc -l)"
|
|
|
|
echo -e "\n${BLUE}🌐 Verfügbare Services:${NC}"
|
|
echo -e " 📡 HTTP: http://localhost:80 oder http://$(hostname -I | awk '{print $1}'):80"
|
|
echo -e " 🔒 HTTPS: https://localhost:443 oder https://$(hostname -I | awk '{print $1}'):443"
|
|
echo -e " 🛠️ Development: http://localhost:5000 oder http://$(hostname -I | awk '{print $1}'):5000"
|
|
|
|
echo -e "\n${BLUE}🖥️ Kiosk-Modus:${NC}"
|
|
echo -e " 🚀 Desktop-Icons: Doppelklick auf 'MYP Kiosk' für Vollbild-Modus"
|
|
echo -e " 📊 Container-Management: 'MYP Container' für Docker-Befehle"
|
|
echo -e " 🎯 Autostart: mv ~/.config/autostart/myp-kiosk.desktop.disabled ~/.config/autostart/myp-kiosk.desktop"
|
|
|
|
echo -e "\n${BLUE}🔧 Nützliche Befehle:${NC}"
|
|
echo -e " Container anzeigen: docker-compose ps"
|
|
echo -e " Logs verfolgen: docker-compose logs -f"
|
|
echo -e " Container stoppen: docker-compose down"
|
|
echo -e " Container neustarten: docker-compose restart"
|
|
echo -e " System bereinigen: docker system prune -f"
|
|
|
|
echo -e "\n${BLUE}📂 Persistente Daten:${NC}"
|
|
echo -e " Docker Volumes: docker volume ls | grep myp-system"
|
|
echo -e " Anwendungsdaten: myp-system-data"
|
|
echo -e " Datenbank: myp-system-database"
|
|
echo -e " Logs: myp-system-logs"
|
|
echo -e " Uploads: myp-system-uploads"
|
|
|
|
echo -e "\n${YELLOW}⚠️ Wichtige Hinweise:${NC}"
|
|
echo -e " • Führe dieses Skript erneut aus für komplette Neuinstallation"
|
|
echo -e " • SSL-Zertifikate sind selbstsigniert (Browser-Warnung normal)"
|
|
echo -e " • Produktions-Deployment: Prüfe Firewall-Einstellungen"
|
|
echo -e " • Logs: $LOG_FILE"
|
|
|
|
echo -e "\n${GREEN}✨ Mercedes-Benz TBA Marienfelde - MYP System bereit!${NC}"
|
|
}
|
|
|
|
# ===== HAUPTFUNKTION =====
|
|
|
|
main() {
|
|
# Log-Datei initialisieren
|
|
echo "=== MYP Docker Setup Log - $(date) ===" > "$LOG_FILE"
|
|
|
|
header "$SCRIPT_NAME - Mercedes-Benz TBA Marienfelde"
|
|
|
|
log "Starte automatisierte MYP-Docker-Installation..."
|
|
|
|
# Ausführungsschritte
|
|
check_system
|
|
cleanup_docker
|
|
update_system
|
|
install_docker
|
|
install_docker_compose
|
|
create_docker_files
|
|
deploy_containers
|
|
setup_kiosk_mode
|
|
show_completion_info
|
|
|
|
log "🎯 Setup-Skript erfolgreich abgeschlossen!"
|
|
echo -e "\n${GREEN}Log-Datei: $LOG_FILE${NC}"
|
|
}
|
|
|
|
# ===== SCRIPT EXECUTION =====
|
|
|
|
# Trap für Cleanup bei Unterbrechung
|
|
trap 'error "Script unterbrochen!"; exit 1' INT TERM
|
|
|
|
# Hauptfunktion ausführen
|
|
main "$@" |