diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d9ef2d9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+MARIADB/
+WEBSERVER/
+TEMP/
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..e1de2a9
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,16 @@
+# Basis-Image: Apache + PHP
+FROM php:8.2-apache
+
+# PHP Erweiterungen installieren (mysqli)
+RUN docker-php-ext-install mysqli
+
+# pdftk installieren
+RUN apt-get update && \
+ apt-get install -y pdftk net-tools geoip-bin && \
+ apt-get clean && rm -rf /var/lib/apt/lists/*
+
+# Apache Mod Rewrite aktivieren (optional)
+RUN a2enmod rewrite
+
+# NEU: AllowOverride All aktivieren, damit .htaccess funktioniert
+RUN sed -i '//,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
\ No newline at end of file
diff --git a/HAPROXY/blackpi-ipv64-net.pem b/HAPROXY/blackpi-ipv64-net.pem
new file mode 100644
index 0000000..19a63d0
--- /dev/null
+++ b/HAPROXY/blackpi-ipv64-net.pem
@@ -0,0 +1,53 @@
+-----BEGIN CERTIFICATE-----
+MIIDrDCCAzOgAwIBAgISBftNmlblpprVEwQ90Ba8xcnJMAoGCCqGSM49BAMDMDIx
+CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
+ODAeFw0yNTEyMTAwNzA0MTNaFw0yNjAzMTAwNzA0MTJaMBwxGjAYBgNVBAMTEWJs
+YWNrcGkuaXB2NjQubmV0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEUjOsE2/
+P2uG7qtZzACOvGIo60ILeArhcXkabLeYZuYiM+m9V8lzfRw1I69f2C2cG6oKZZN0
+jfbaupqp2hsTnqOCAj0wggI5MA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr
+BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQULsYl0Ccu
+8LxQ3E3ErsbZlVaz4UkwHwYDVR0jBBgwFoAUjw0TovYuftFQbDMYOF1ZjiNykcow
+MgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAChhZodHRwOi8vZTguaS5sZW5jci5v
+cmcvMDMGA1UdEQQsMCqCEWJsYWNrcGkuaXB2NjQubmV0ghV3d3cuYmxhY2twaS5p
+cHY2NC5uZXQwEwYDVR0gBAwwCjAIBgZngQwBAgEwLQYDVR0fBCYwJDAioCCgHoYc
+aHR0cDovL2U4LmMubGVuY3Iub3JnLzc0LmNybDCCAQsGCisGAQQB1nkCBAIEgfwE
+gfkA9wB2AEmcm2neHXzs/DbezYdkprhbrwqHgBnRVVL76esp3fjDAAABmwdItI4A
+AAQDAEcwRQIgEWU6WP/UjWpOplHAJyVKu38dHZdFsWVmksGleeLuv58CIQCMU1T1
+efco+svUKzC0AgQ+wVx2LLKoExngI29CklPVeAB9ABqLnWlKV5jImaDKiL30j8C0
+VmDMw2ANH3H0af/H0ayjAAABmwdIuGsACAAABQAjFj4YBAMARjBEAiAGF8tLRC+P
+FV1kyEihTlluRDL3+O6HnYP6gvpRHgMIJgIgWMBgZXFgPmSbY31H5ASbkfSrkt5E
+fJ44yviNrAjRXbAwCgYIKoZIzj0EAwMDZwAwZAIwdT1TTRq/4DueiBoofMh7s+CZ
+Viz7TqDfpsAiSV7V6FD3NkH08OJds/BOywlc4jZ0AjAV6WG+PPQ302/VeYCKSczn
+p3haTeSiFQgUTzA4/Jwva+745L5TXe1/lyzL3s2lt5Q=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIEVjCCAj6gAwIBAgIQY5WTY8JOcIJxWRi/w9ftVjANBgkqhkiG9w0BAQsFADBP
+MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy
+Y2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMTAeFw0yNDAzMTMwMDAwMDBa
+Fw0yNzAzMTIyMzU5NTlaMDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBF
+bmNyeXB0MQswCQYDVQQDEwJFODB2MBAGByqGSM49AgEGBSuBBAAiA2IABNFl8l7c
+S7QMApzSsvru6WyrOq44ofTUOTIzxULUzDMMNMchIJBwXOhiLxxxs0LXeb5GDcHb
+R6EToMffgSZjO9SNHfY9gjMy9vQr5/WWOrQTZxh7az6NSNnq3u2ubT6HTKOB+DCB
+9TAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMB
+MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFI8NE6L2Ln7RUGwzGDhdWY4j
+cpHKMB8GA1UdIwQYMBaAFHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEB
+BCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzATBgNVHSAE
+DDAKMAgGBmeBDAECATAnBgNVHR8EIDAeMBygGqAYhhZodHRwOi8veDEuYy5sZW5j
+ci5vcmcvMA0GCSqGSIb3DQEBCwUAA4ICAQBnE0hGINKsCYWi0Xx1ygxD5qihEjZ0
+RI3tTZz1wuATH3ZwYPIp97kWEayanD1j0cDhIYzy4CkDo2jB8D5t0a6zZWzlr98d
+AQFNh8uKJkIHdLShy+nUyeZxc5bNeMp1Lu0gSzE4McqfmNMvIpeiwWSYO9w82Ob8
+otvXcO2JUYi3svHIWRm3+707DUbL51XMcY2iZdlCq4Wa9nbuk3WTU4gr6LY8MzVA
+aDQG2+4U3eJ6qUF10bBnR1uuVyDYs9RhrwucRVnfuDj29CMLTsplM5f5wSV5hUpm
+Uwp/vV7M4w4aGunt74koX71n4EdagCsL/Yk5+mAQU0+tue0JOfAV/R6t1k+Xk9s2
+HMQFeoxppfzAVC04FdG9M+AC2JWxmFSt6BCuh3CEey3fE52Qrj9YM75rtvIjsm/1
+Hl+u//Wqxnu1ZQ4jpa+VpuZiGOlWrqSP9eogdOhCGisnyewWJwRQOqK16wiGyZeR
+xs/Bekw65vwSIaVkBruPiTfMOo0Zh4gVa8/qJgMbJbyrwwG97z/PRgmLKCDl8z3d
+tA0Z7qq7fta0Gl24uyuB05dqI5J1LvAzKuWdIjT1tP8qCoxSE/xpix8hX2dt3h+/
+jujUgFPFZ0EVZ0xSyBNRF3MboGZnYXFUxpNjTWPKpagDHJQmqrAcDmWJnMsFY3jS
+u1igv3OefnWjSQ==
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgXXSjWepmrhBxCPnB
+e9swRUqo71F+dsQtbNfUySLF37KhRANCAAQRSM6wTb8/a4buq1nMAI68YijrQgt4
+CuFxeRpst5hm5iIz6b1XyXN9HDUjr1/YLZwbqgplk3SN9tq6mqnaGxOe
+-----END PRIVATE KEY-----
diff --git a/HAPROXY/haproxy.cfg b/HAPROXY/haproxy.cfg
new file mode 100644
index 0000000..3e8e54b
--- /dev/null
+++ b/HAPROXY/haproxy.cfg
@@ -0,0 +1,41 @@
+global
+ log stdout format raw local0 info
+ maxconn 8192
+
+defaults
+ log global
+ mode http
+ option httplog
+ option dontlognull
+ option forwardfor
+ timeout connect 5000
+ timeout client 50000
+ timeout server 50000
+
+frontend https
+ bind *:80
+
+ acl is_public hdr_end(host) -i public.local.ipv64.net
+ acl is_backend hdr_end(host) -i backend.local.ipv64.net
+ acl is_stats hdr_end(host) -i stats.local.ipv64.net
+
+ use_backend web_public if is_public
+ use_backend web_backend if is_backend
+ use_backend stats if is_stats
+
+ default_backend web_public
+
+backend web_public
+ server node1 172.30.0.11:80 cookie node1 check
+
+backend web_backend
+ server node1 172.30.0.13:80 cookie node1 check
+
+backend stats
+ mode http
+ stats enable
+ stats uri /
+ stats realm Haproxy\ Statistics
+ stats auth worker:p2x338
+ stats admin if TRUE
+
diff --git a/SCRIPTS/Database.sh b/SCRIPTS/Database.sh
new file mode 100644
index 0000000..b40e66e
--- /dev/null
+++ b/SCRIPTS/Database.sh
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+set -Eeuo pipefail
+
+RED="\e[31m"
+GREEN="\e[32m"
+YELLOW="\e[33m"
+BLUE="\e[34m"
+RESET="\e[0m"
+
+log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
+log_success() { echo -e "${GREEN}[OK]${RESET} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${RESET} $1"; }
+log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
+
+trap 'log_error "Fehler in Zeile $LINENO"' ERR
+
+if [[ "$EUID" -ne 0 ]]; then
+ log_error "Script muss als root laufen!"
+ exit 1
+fi
+
+exec 9>/var/lock/docker-control.lock
+flock -n 9 || { log_error "Script läuft bereits!"; exit 1; }
+
+export_database() {
+ log_info "Exportiere DEV"
+ cp /data/TEMP/Database.sql /data/TEMP/Database-$(date +%Y-%m-%d_%H-%M-%S).sql
+ echo "Letzten 5 Dateien gelistet:"
+ du -sh /data/TEMP/* | tail -n 5
+ mariadb-dump -h 127.0.0.1 -u worker -pbBHofurUJWKzPE8Z --all-databases > /data/TEMP/Database.sql
+ log_info "DEV wurde nach DEV.sql exportiert"
+}
+
+import_database() {
+ $timestamp=$(date +%Y%m%d%H%M%S)
+ log_info "Bereinige alte Datenbank"
+ mariadb -h 127.0.0.1 -u worker -pbBHofurUJWKzPE8Z -e "DROP DATABASE DEV; CREATE DATABASE DEV;"
+ log_info "Alte Datenbank bereinigt"
+ echo ""
+ log_info "Lese DEV.sql ein"
+ mariadb -h 127.0.0.1 -u worker -pbBHofurUJWKzPE8Z DEV < /data/TEMP/Database.sql
+ mv /data/TEMP/Database.sql /data/TEMP/Database-${timestamp}.sql
+ log_info "DEV-${timestamp}.sql wurde eingelesen"
+}
+
+ACTION="${1:-}"
+
+case "$ACTION" in
+
+ export)
+ export_database
+ ;;
+
+ import)
+ import_database
+ ;;
+
+ *)
+ echo "Usage:"
+ echo " $0 import"
+ echo " $0 export"
+ exit 1
+ ;;
+esac
diff --git a/SCRIPTS/MONITOR.sh b/SCRIPTS/MONITOR.sh
new file mode 100644
index 0000000..b97d705
--- /dev/null
+++ b/SCRIPTS/MONITOR.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+
+# -------------------------------
+# Server Status Report Script
+# -------------------------------
+# Datum/Zeit
+DATE=$(date +"%Y-%m-%d %H:%M:%S")
+
+# -------------------------------
+# Systemauslastung
+# -------------------------------
+
+CPU_LOAD=$(uptime | awk -F 'load average:' '{ print $2 }' | sed 's/^ *//')
+CPU_TEMP=$(vcgencmd measure_temp)
+MEMORY_USAGE=$(free -h | awk '/Mem:/ {print $3 " used / " $2 " total"}')
+DISK_USAGE=$(df -h /)
+NFS_USAGE=$(df -h /data)
+
+# -------------------------------
+# Docker Status
+# -------------------------------
+
+if command -v docker &> /dev/null
+then
+ DOCKER_CONTAINERS=$(docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}")
+else
+ DOCKER_CONTAINERS="Docker ist nicht installiert oder der Docker-Daemon läuft nicht."
+fi
+
+# -------------------------------
+# Ausgabe auf Konsole
+# -------------------------------
+
+echo "Server Status Report"
+echo =====================================================
+echo
+echo "Hostname : $(hostname)"
+echo "Datum : $DATE"
+echo "CPU Load : $CPU_LOAD"
+echo "CPU Temperature : $CPU_TEMP"
+echo "RAM : $MEMORY_USAGE"
+echo
+echo "System Festplatten:"
+echo "$DISK_USAGE"
+echo
+echo "NFS Festplatten:"
+echo "$NFS_USAGE"
+echo
+echo "Docker Container:"
+echo "$DOCKER_CONTAINERS"
+echo
+echo "====================================================="
diff --git a/SCRIPTS/certs-renew.sh b/SCRIPTS/certs-renew.sh
new file mode 100644
index 0000000..f144a8e
--- /dev/null
+++ b/SCRIPTS/certs-renew.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+
+DB_HOST="127.0.0.1"
+DB_USER="worker"
+DB_PASS="bBHofurUJWKzPE8Z"
+DB_NAME="LIVE"
+
+CERT_NAME="mrhossa"
+EMAIL="bruno.eckhardt07@gmail.com"
+
+PEM_FILE="/data/HAPROXY/mrhossa.pem"
+BACKUP_DIR="/data/HAPROXY/backups"
+
+mkdir -p "$BACKUP_DIR"
+
+echo "Lade Domains aus MySQL..."
+
+DOMAINS=$(mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -N -B -e "SELECT SUBDOMAIN FROM Domains;")
+
+DOMAIN_ARGS=()
+
+for domain in $DOMAINS
+do
+ DOMAIN_ARGS+=("-d" "$domain")
+done
+
+echo "Domains:"
+printf '%s\n' "${DOMAIN_ARGS[@]}"
+
+# Backup vorhandenes Zertifikat
+if [ -f "$PEM_FILE" ]; then
+ TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
+ cp "$PEM_FILE" "$BACKUP_DIR/mrhossa_$TIMESTAMP.pem"
+ echo "Backup erstellt: $BACKUP_DIR/mrhossa_$TIMESTAMP.pem"
+fi
+
+echo "Bereinige alte Backups..."
+ls -t $BACKUP_DIR/*.pem 2>/dev/null | tail -n +21 | xargs -r rm -f
+
+echo "Stoppe HAProxy Container..."
+sudo docker stop haproxy
+
+echo "Hole/erneuere Zertifikat..."
+
+sudo certbot certonly --standalone \
+ --cert-name "$CERT_NAME" \
+ "${DOMAIN_ARGS[@]}" \
+ --non-interactive \
+ --agree-tos \
+ -m "$EMAIL" \
+ --keep-until-expiring
+
+echo "Finde aktuelles Zertifikat..."
+
+LATEST_CERT=$(ls -dt /etc/letsencrypt/live/mrhossa* | head -n1)
+
+echo "Benutze Zertifikat aus:"
+echo "$LATEST_CERT"
+
+echo "Baue HAProxy PEM..."
+
+cat "$LATEST_CERT/privkey.pem" \
+ "$LATEST_CERT/fullchain.pem" \
+ > "$PEM_FILE"
+
+echo "Starte HAProxy Container..."
+sudo docker start haproxy
+
+echo "Fertig."
diff --git a/SCRIPTS/deploy.sh b/SCRIPTS/deploy.sh
new file mode 100644
index 0000000..da9db27
--- /dev/null
+++ b/SCRIPTS/deploy.sh
@@ -0,0 +1,241 @@
+#!/usr/bin/env bash
+
+# ./deploy.sh public
+# ./deploy.sh backend
+# ./deploy.sh all
+# ./deploy.sh list-backups public
+# ./deploy.sh rollback public
+# ./deploy.sh rollback public PUBLIC-20260216-143015-server01
+
+
+set -Eeuo pipefail
+
+########################################
+# Farben
+########################################
+RED="\e[31m"
+GREEN="\e[32m"
+YELLOW="\e[33m"
+BLUE="\e[34m"
+BOLD="\e[1m"
+RESET="\e[0m"
+
+########################################
+# Logging
+########################################
+log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
+log_success() { echo -e "${GREEN}[OK]${RESET} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${RESET} $1"; }
+log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
+
+trap 'log_error "Fehler in Zeile $LINENO"' ERR
+
+########################################
+# Konfiguration
+########################################
+BASE_DIR="/data/WEBSERVER"
+BACKUP_DIR="$BASE_DIR/BACKUP"
+
+PUBLIC_REPO="http://gitea.blackpi.ipv64.net/bruno/Web-Public.git"
+BACKEND_REPO="http://gitea.blackpi.ipv64.net/bruno/Backend.git"
+
+TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
+HOSTNAME=$(hostname)
+
+########################################
+# Root-Check
+########################################
+if [[ "$EUID" -ne 0 ]]; then
+ log_error "Script muss als root laufen!"
+ exit 1
+fi
+
+########################################
+# Lockfile
+########################################
+exec 9>/var/lock/webdeploy.lock
+flock -n 9 || { log_error "Deploy läuft bereits!"; exit 1; }
+
+########################################
+# Helper
+########################################
+ensure_directory() {
+ [[ -d "$1" ]] || mkdir -p "$1"
+}
+
+restart_container() {
+ local container="$1"
+ if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then
+ docker restart "$container" >/dev/null
+ log_success "Container $container neu gestartet."
+ else
+ log_warn "Container $container existiert nicht."
+ fi
+}
+
+backup_current() {
+ local name="$1"
+ local target="$BASE_DIR/$name"
+ local rsync_server="10.233.1.89"
+ local rsync_user="root"
+ local rsync_dir="/root/BACKUP/NFS/WEBSERVER/"
+
+ if [[ -d "$target" ]]; then
+ ensure_directory "$BACKUP_DIR"
+ local backup_name="${name}-${TIMESTAMP}-${HOSTNAME}"
+ mv "$target" "$BACKUP_DIR/$backup_name"
+ log_info "$name wurde lokal gesichert: $backup_name"
+
+ # rsync ausführen
+ if rsync -avz "$BACKUP_DIR/$backup_name" "${rsync_user}@${rsync_server}:${rsync_dir}"; then
+ log_info "$backup_name wurde erfolgreich auf den Backup-Server: ${rsync_user}@${rsync_server}:${rsync_dir} kopiert."
+ else
+ log_error "Fehler beim Kopieren von $backup_name auf den Backup-Server!"
+ fi
+ fi
+}
+
+deploy() {
+ local name="$1"
+ local repo="$2"
+ local container="$3"
+ local target="$BASE_DIR/$name"
+
+ log_info "Deploying $name ..."
+
+ backup_current "$name"
+
+ git clone "$repo" "$target"
+
+ if [[ "$name" == "BACKEND" ]]; then
+ git -C "$target" checkout live
+ fi
+
+ restart_container "$container"
+ log_success "$name erfolgreich deployed."
+}
+
+########################################
+# Rollback
+########################################
+list_backups() {
+ local name="$1"
+ log_info "Verfügbare Backups für $name:"
+ ls -ldt "$BACKUP_DIR/${name}-"* 2>/dev/null || log_warn "Keine Backups gefunden."
+}
+
+rollback() {
+ local name="$1"
+ local container="$2"
+ local specific_backup="${3:-}"
+
+ ensure_directory "$BACKUP_DIR"
+
+ local current="$BASE_DIR/$name"
+ local backup_to_restore
+
+ if [[ -n "$specific_backup" ]]; then
+ backup_to_restore="$BACKUP_DIR/$specific_backup"
+ else
+ backup_to_restore=$(ls -dt "$BACKUP_DIR/${name}-"* 2>/dev/null | head -n1)
+ fi
+
+ if [[ -z "${backup_to_restore:-}" || ! -d "$backup_to_restore" ]]; then
+ log_error "Kein gültiges Backup gefunden!"
+ exit 1
+ fi
+
+ log_warn "Rollback von $name → $(basename "$backup_to_restore")"
+
+ # 🔴 Container stoppen
+ if docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
+ log_info "Stoppe Container $container ..."
+ docker stop "$container" >/dev/null
+ fi
+
+ # 🔴 Verzeichnis sicher löschen
+ if [[ -d "$current" ]]; then
+ log_info "Entferne aktuelles Verzeichnis ..."
+ rm -rf "$current"
+ fi
+
+ # 🔴 Backup zurückspielen
+ mv "$backup_to_restore" "$current"
+
+ # 🟢 Container neu starten
+ docker start "$container" >/dev/null
+ log_success "Rollback abgeschlossen."
+}
+
+
+########################################
+# Fetch
+########################################
+fetch_changes() {
+ local name="$1"
+ local target="$BASE_DIR/$name"
+
+ if [[ -d "$target/.git" ]]; then
+ git -C "$target" fetch origin
+ git -C "$target" diff HEAD..origin/main --name-only
+ else
+ log_warn "$name ist nicht installiert."
+ fi
+}
+
+########################################
+# CLI
+########################################
+ACTION="${1:-}"
+TARGET="${2:-}"
+OPTIONAL="${3:-}"
+
+case "$ACTION" in
+ all)
+ deploy "PUBLIC" "$PUBLIC_REPO" "webserver_public"
+ deploy "BACKEND" "$BACKEND_REPO" "webserver_backend"
+ ;;
+ public)
+ deploy "PUBLIC" "$PUBLIC_REPO" "webserver_public"
+ ;;
+ backend)
+ deploy "BACKEND" "$BACKEND_REPO" "webserver_backend"
+ ;;
+ rollback)
+ case "$TARGET" in
+ public)
+ rollback "PUBLIC" "webserver_public" "$OPTIONAL"
+ ;;
+ backend)
+ rollback "BACKEND" "webserver_backend" "$OPTIONAL"
+ ;;
+ *)
+ echo "Usage: $0 rollback {public|backend} [backup-name]"
+ exit 1
+ ;;
+ esac
+ ;;
+ list-backups)
+ case "$TARGET" in
+ public) list_backups "PUBLIC" ;;
+ backend) list_backups "BACKEND" ;;
+ *)
+ echo "Usage: $0 list-backups {public|backend}"
+ exit 1
+ ;;
+ esac
+ ;;
+ fetch)
+ fetch_changes "PUBLIC"
+ fetch_changes "BACKEND"
+ ;;
+ *)
+ echo "Usage:"
+ echo " $0 {all|public|backend}"
+ echo " $0 rollback {public|backend} [backup-name]"
+ echo " $0 list-backups {public|backend}"
+ echo " $0 fetch"
+ exit 1
+ ;;
+esac
+
diff --git a/SCRIPTS/docker.sh b/SCRIPTS/docker.sh
new file mode 100644
index 0000000..d2eeb6f
--- /dev/null
+++ b/SCRIPTS/docker.sh
@@ -0,0 +1,121 @@
+#!/usr/bin/env bash
+
+set -Eeuo pipefail
+
+RED="\e[31m"
+GREEN="\e[32m"
+YELLOW="\e[33m"
+BLUE="\e[34m"
+RESET="\e[0m"
+
+log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
+log_success() { echo -e "${GREEN}[OK]${RESET} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${RESET} $1"; }
+log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
+
+trap 'log_error "Fehler in Zeile $LINENO"' ERR
+
+if [[ "$EUID" -ne 0 ]]; then
+ log_error "Script muss als root laufen!"
+ exit 1
+fi
+
+exec 9>/var/lock/docker-control.lock
+flock -n 9 || { log_error "Script läuft bereits!"; exit 1; }
+
+docker_up() {
+
+ local CONTAINER="$1"
+
+ if [[ "$CONTAINER" == "all" ]]; then
+ log_info "Starte alle gestoppten Container"
+ docker start $(docker ps -aq)
+ else
+ log_info "Starte Container: $CONTAINER"
+ docker start "$CONTAINER"
+ fi
+
+ log_success "Start abgeschlossen"
+}
+
+docker_stop() {
+
+ local CONTAINER="$1"
+
+ if [[ "$CONTAINER" == "all" ]]; then
+ log_info "Stoppe alle Container"
+ docker stop $(docker ps -q)
+ else
+ log_info "Stoppe Container: $CONTAINER"
+ docker stop "$CONTAINER"
+ fi
+
+ log_success "Stop abgeschlossen"
+}
+
+docker_restart() {
+
+ local CONTAINER="$1"
+
+ if [[ "$CONTAINER" == "all" ]]; then
+ log_info "Restart aller Container"
+ docker restart $(docker ps -q)
+ else
+ log_info "Restart Container: $CONTAINER"
+ docker restart "$CONTAINER"
+ fi
+
+ log_success "Restart abgeschlossen"
+}
+
+docker_remove() {
+
+ local CONTAINER="$1"
+
+ if [[ "$CONTAINER" == "all" ]]; then
+ log_info "Loesche aller Container"
+ docker stop $(docker ps -q)
+ docker rm $(docker ps -q)
+ else
+ log_info "Loesche Container: $CONTAINER"
+ docker stop "$CONTAINER"
+ docker rm "$CONTAINER"
+ fi
+
+ log_success "Loeschen abgeschlossen"
+}
+
+########################################
+# CLI
+########################################
+
+ACTION="${1:-}"
+TARGET="${2:-}"
+
+case "$ACTION" in
+
+ up)
+ docker_up "$TARGET"
+ ;;
+
+ stop)
+ docker_stop "$TARGET"
+ ;;
+
+ restart)
+ docker_restart "$TARGET"
+ ;;
+
+ remove)
+ docker_remove "$TARGET"
+ ;;
+
+ *)
+ echo "Usage:"
+ echo " $0 up "
+ echo " $0 stop "
+ echo " $0 remove "
+ echo " $0 restart "
+ exit 1
+ ;;
+esac
\ No newline at end of file
diff --git a/SCRIPTS/generate-sitemap.sh b/SCRIPTS/generate-sitemap.sh
new file mode 100644
index 0000000..ffd9b8b
--- /dev/null
+++ b/SCRIPTS/generate-sitemap.sh
@@ -0,0 +1,177 @@
+#!/usr/bin/env bash
+set -Eeuo pipefail
+
+RED="\e[31m"
+GREEN="\e[32m"
+YELLOW="\e[33m"
+BLUE="\e[34m"
+BOLD="\e[1m"
+RESET="\e[0m"
+
+log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
+log_success() { echo -e "${GREEN}[OK]${RESET} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${RESET} $1"; }
+log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
+
+trap 'log_error "Fehler in Zeile $LINENO"' ERR
+
+if [[ "$EUID" -ne 0 ]]; then
+ log_error "Script muss als root laufen!"
+ exit 1
+fi
+
+backend() {
+ echo ""
+ echo "BACKEND Sitemap wird erzeugt..."
+ echo ""
+ BASEURL="https://backend.blackpi.ipv64.net"
+ SEARCH_PATH="/data/WEBSERVER/BACKEND/WEBROOT"
+ SITEMAP="/data/WEBSERVER/BACKEND/WEBROOT/sitemap.xml"
+ EXCLUDE_DIRS=(
+ "config_backups"
+ "Commands"
+ "controller"
+ "modules"
+ "config.php"
+ "main.js"
+ "style.js"
+ "login.php"
+ ".htaccess"
+ "static"
+ "templates"
+ #"api"
+ )
+
+ echo ""
+ echo '' > $SITEMAP
+ echo '' >> $SITEMAP
+
+ find "$SEARCH_PATH" -type f | while read file; do
+ relpath="${file#$SEARCH_PATH/}"
+
+ skip=false
+ for dir in "${EXCLUDE_DIRS[@]}"; do
+ if [[ "$relpath" == "$dir"* ]]; then
+ skip=true
+ break
+ fi
+ done
+ if [ "$skip" = true ]; then
+ continue
+ fi
+
+ lastmod=$(date -r "$file" "+%Y-%m-%d")
+
+ changefreq="daily"
+ priority="1.0"
+
+ if [ "$relpath" == "index.php" ] || [ "$relpath" == "index.html" ]; then
+ changefreq="weekly"
+ priority="1.0"
+ fi
+
+ echo " " >> $SITEMAP
+ echo " $BASEURL/$relpath" >> $SITEMAP
+ echo " $lastmod" >> $SITEMAP
+ echo " $changefreq" >> $SITEMAP
+ echo " $priority" >> $SITEMAP
+ echo " " >> $SITEMAP
+
+ echo " -> $BASEURL/$relpath"
+ done
+
+ echo '' >> $SITEMAP
+
+ echo ""
+ echo "Sitemap wurde erzeugt: $SITEMAP"
+ echo ""
+}
+
+public() {
+ echo ""
+ echo " PUBLIC Sitemap wird erzeugt..."
+ echo ""
+ BASEURL="https://www.blackpi.ipv64.net"
+ SEARCH_PATH="/data/WEBSERVER/PUBLIC/WEBROOT"
+ SITEMAP="/data/WEBSERVER/PUBLIC/WEBROOT/sitemap.xml"
+ EXCLUDE_DIRS=(
+ "controller"
+ "moduls"
+ "templates"
+ "services/GenBerichte/"
+ "services/GenBerichte/Arbeitsberichte/overtime_corrections.json"
+ "services/Berichte/Arbeitsberichte/overtime_corrections.json"
+ "services/test/"
+ "services/test.php"
+ "main.js"
+ "style.js"
+ "api"
+ ".htaccess"
+ )
+
+ echo ""
+ echo '' > $SITEMAP
+ echo '' >> $SITEMAP
+
+ find "$SEARCH_PATH" -type f | while read file; do
+ relpath="${file#$SEARCH_PATH/}"
+
+ skip=false
+ for dir in "${EXCLUDE_DIRS[@]}"; do
+ if [[ "$relpath" == "$dir"* ]]; then
+ skip=true
+ break
+ fi
+ done
+ if [ "$skip" = true ]; then
+ continue
+ fi
+
+ lastmod=$(date -r "$file" "+%Y-%m-%d")
+
+ changefreq="daily"
+ priority="1.0"
+
+ if [ "$relpath" == "index.php" ] || [ "$relpath" == "index.html" ]; then
+ changefreq="weekly"
+ priority="1.0"
+ fi
+
+ echo " " >> $SITEMAP
+ echo " $BASEURL/$relpath" >> $SITEMAP
+ echo " $lastmod" >> $SITEMAP
+ echo " $changefreq" >> $SITEMAP
+ echo " $priority" >> $SITEMAP
+ echo " " >> $SITEMAP
+
+ echo " -> $BASEURL/$relpath"
+ done
+
+ echo '' >> $SITEMAP
+
+ echo ""
+ echo "Sitemap wurde erzeugt: $SITEMAP"
+ echo ""
+}
+
+ACTION="${1:-}"
+TARGET="${2:-}"
+OPTIONAL="${3:-}"
+
+case "$ACTION" in
+ all)
+ backend
+ public
+ ;;
+ public)
+ public
+ ;;
+ backend)
+ backend
+ ;;
+ *)
+ echo " $0 {public|backend}"
+ exit 1
+ ;;
+esac
+
diff --git a/SCRIPTS/git-config.sh b/SCRIPTS/git-config.sh
new file mode 100644
index 0000000..d33e2f8
--- /dev/null
+++ b/SCRIPTS/git-config.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+echo "Git Config"
+
+USER="bruno"
+MAIL="bruno.eckhardt07@gmail.com"
+
+git config --global credential.helper store
+git config --global user.name $USER
+git config --global user.email $MAIL
diff --git a/SERVER.code-workspace b/SERVER.code-workspace
new file mode 100644
index 0000000..38c9264
--- /dev/null
+++ b/SERVER.code-workspace
@@ -0,0 +1,13 @@
+{
+ "folders": [
+ {
+ "path": "."
+ }
+ ],
+ "settings": {
+ "files.exclude": {
+ // "**/.git": true,
+ // "**/WEBSERVER": true,
+ }
+ }
+}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..037118d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,61 @@
+services:
+ haproxy:
+ image: haproxy:latest
+ container_name: HAPROXY
+ volumes:
+ - ./HAPROXY/:/usr/local/etc/haproxy
+ ports:
+ - "80:80"
+ - "443:443"
+ networks:
+ docker-net:
+ ipv4_address: 172.30.0.10
+ restart: always
+
+ webserver-public:
+ build: .
+ container_name: WEBSERVER-PUBLIC
+ volumes:
+ - ./WEBSERVER/PUBLIC/WEBROOT/:/var/www/html/
+ ports:
+ - "8001:80"
+ networks:
+ docker-net:
+ ipv4_address: 172.30.0.11
+ restart: always
+
+ webserver-backend:
+ build: .
+ container_name: WEBSERVER-BACKEND
+ volumes:
+ - ./WEBSERVER/BACKEND/WEBROOT/:/var/www/html/
+ ports:
+ - "8002:80"
+ networks:
+ docker-net:
+ ipv4_address: 172.30.0.13
+ restart: always
+
+ mariadb:
+ image: mariadb:latest
+ container_name: MARIADB
+ volumes:
+ - ./MARIADB:/var/lib/mysql
+ ports:
+ - "3306:3306"
+ environment:
+ MARIADB_ROOT_PASSWORD: bBHofurUJWKzPE8Z
+ MARIADB_DATABASE: DEV
+ MARIADB_USER: worker
+ MARIADB_PASSWORD: bBHofurUJWKzPE8Z
+ networks:
+ docker-net:
+ ipv4_address: 172.30.0.12
+ restart: always
+
+networks:
+ docker-net:
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.30.0.0/16
diff --git a/install.sh b/install.sh
new file mode 100644
index 0000000..36d3f86
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+set -Eeuo pipefail
+
+########################################
+# Farben
+########################################
+RED="\e[31m"
+GREEN="\e[32m"
+YELLOW="\e[33m"
+BLUE="\e[34m"
+BOLD="\e[1m"
+RESET="\e[0m"
+
+########################################
+# Logging
+########################################
+log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
+log_success() { echo -e "${GREEN}[OK]${RESET} $1"; }
+log_warn() { echo -e "${YELLOW}[WARN]${RESET} $1"; }
+log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
+
+BASE_DIR="$(pwd)/WEBSERVER/"
+TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
+HOSTNAME=$(hostname)
+
+PUBLIC_REPO="https://gitea.mrhossa.de/bruno/Web-Public.git"
+BACKEND_REPO="https://gitea.mrhossa.de/bruno/Backend.git"
+
+if [[ "$EUID" -ne 0 ]]; then
+ log_error "Script muss als root laufen!"
+ exit 1
+fi
+
+git clone https://gitea.mrhossa.de/bruno/Backend.git $BASE_DIR/BACKEND
+git -C $BASE_DIR/BACKEND checkout live
+docker restart webserver_backend
+
+git clone https://gitea.mrhossa.de/bruno/Web-Public.git $BASE_DIR/PUBLIC
\ No newline at end of file