diff --git a/docker/bookstack/docker-compose.yml b/docker/bookstack/docker-compose.yml new file mode 100644 index 0000000..68c4136 --- /dev/null +++ b/docker/bookstack/docker-compose.yml @@ -0,0 +1,50 @@ +version: "3" +services: + bookstack: + image: lscr.io/linuxserver/bookstack:latest + container_name: bookstack + environment: + - PUID=1000 + - PGID=1000 + - APP_URL=https://bookstack.hessenkamp-server.de + - DB_HOST=bookstack_db + - DB_PORT=3306 + - DB_USER=bookstack + - DB_PASS=ObV2rbC9MgBKGCZjTLI2 # Ändern Sie dies! + - DB_DATABASE=bookstackapp + volumes: + - ../containerdaten/bookstack/config:/config + ports: + - 6875:80 + restart: unless-stopped + depends_on: + - bookstack_db + networks: + - traefik_network + labels: + - "traefik.enable=true" + - "traefik.http.routers.bookstack.rule=Host(`bookstack.hessenkamp-server.de`)" + - "traefik.http.routers.bookstack.entrypoints=websecure" + - "traefik.http.routers.bookstack.tls.certresolver=letsencrypt" + - "traefik.http.services.bookstack.loadbalancer.server.port=80" + + bookstack_db: + image: lscr.io/linuxserver/mariadb:latest + container_name: bookstack_db + environment: + - PUID=1000 + - PGID=1000 + - MYSQL_ROOT_PASSWORD=ObV2rbC9MgBKGCZjTLI2 # Ändern Sie dies! + - TZ=Europe/Berlin + - MYSQL_DATABASE=bookstackapp + - MYSQL_USER=bookstack + - MYSQL_PASSWORD=ObV2rbC9MgBKGCZjTLI2 # Muss mit DB_PASS übereinstimmen + volumes: + - ../containerdaten/bookstack/db:/config + restart: unless-stopped + networks: + - traefik_network + +networks: + traefik_network: + external: true diff --git a/docker/duplicati/docker-compose.yml b/docker/duplicati/docker-compose.yml new file mode 100644 index 0000000..83d7dad --- /dev/null +++ b/docker/duplicati/docker-compose.yml @@ -0,0 +1,21 @@ +networks: + traefik_network: + external: true +services: + duplicati: + container_name: duplicati + image: lscr.io/linuxserver/duplicati:latest + labels: + - traefik.enable=true + - traefik.http.routers.duplicati.rule=Host(`duplicati.hessenkamp-server.de`) + - traefik.http.routers.duplicati.entrypoints=websecure + - traefik.http.routers.duplicati.tls.certresolver=letsencrypt + - traefik.http.services.duplicati.loadbalancer.server.port=8200 + networks: + - traefik_network + restart: always + volumes: + - /home/andiamolino/backups:/backups + - ../containerdaten/duplicati/config:/config + - /:/source:ro +version: '3' diff --git a/docker/elasticsearch/docker-compose.yml b/docker/elasticsearch/docker-compose.yml new file mode 100644 index 0000000..4c57c71 --- /dev/null +++ b/docker/elasticsearch/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3' + +networks: + traefik_network: + external: true + +services: + elasticsearch: + container_name: elasticsearch + image: docker.elastic.co/elasticsearch/elasticsearch:7.17.10 + environment: + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - "discovery.type=single-node" + labels: + - traefik.enable=true + - traefik.http.routers.elasticsearch.rule=Host(`elasticsearch.hessenkamp-server.de`) + - traefik.http.routers.elasticsearch.entrypoints=websecure + - traefik.http.routers.elasticsearch.tls.certresolver=letsencrypt + - traefik.http.services.elasticsearch.loadbalancer.server.port=9200 + networks: + - traefik_network + restart: always + volumes: + - ../containerdaten/elasticsearch/data:/usr/share/elasticsearch/data + ports: + - "9200:9200" diff --git a/docker/gitea/docker-compose.yml b/docker/gitea/docker-compose.yml new file mode 100644 index 0000000..1298a6a --- /dev/null +++ b/docker/gitea/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3" + +services: + gitea: + image: gitea/gitea:latest + container_name: gitea + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=sqlite3 + restart: always + networks: + - traefik_network + volumes: + - ../containerdaten/gitea/data:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + labels: + - "traefik.enable=true" + - "traefik.http.routers.gitea.rule=Host(`gitea.hessenkamp-server.de`)" + - "traefik.http.routers.gitea.entrypoints=websecure" + - "traefik.http.routers.gitea.tls.certresolver=letsencrypt" + - "traefik.http.services.gitea.loadbalancer.server.port=3000" + +networks: + traefik_network: + external: true diff --git a/docker/grafana/docker-compose.yml b/docker/grafana/docker-compose.yml new file mode 100644 index 0000000..e09803e --- /dev/null +++ b/docker/grafana/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' + +services: + grafana: + image: grafana/grafana:latest + container_name: grafana + restart: always + networks: + - traefik_network + volumes: + - ../containerdaten/grafana/data:/var/lib/grafana + labels: + - "traefik.enable=true" + - "traefik.http.routers.grafana.rule=Host(`grafana.hessenkamp-server.de`)" + - "traefik.http.routers.grafana.entrypoints=websecure" + - "traefik.http.routers.grafana.tls.certresolver=letsencrypt" + - "traefik.http.services.grafana.loadbalancer.server.port=3000" + +networks: + traefik_network: + external: true diff --git a/docker/invoiceNinja/docker-compose.yml b/docker/invoiceNinja/docker-compose.yml new file mode 100644 index 0000000..e671f2d --- /dev/null +++ b/docker/invoiceNinja/docker-compose.yml @@ -0,0 +1,53 @@ + +services: + server: + container_name: invoiceninja-server + image: nginx + restart: always + env_file: env + volumes: + - /etc/localtime:/etc/localtime:ro + - ./config/nginx/in-vhost.conf:/etc/nginx/conf.d/in-vhost.conf:ro + - ./docker/app/public:/var/www/app/public:ro + labels: + - "traefik.enable=true" + - "traefik.http.routers.invoiceninja.rule=Host(`invoice.hessenkamp-server.de`)" + - "traefik.http.routers.invoiceninja.entrypoints=websecure" + - "traefik.http.routers.invoiceninja.tls.certresolver=letsencrypt" + - "traefik.http.services.invoiceninja.loadbalancer.server.port=80" + depends_on: + - app + networks: + - traefik_network + + app: + container_name: invoiceninja-app + image: invoiceninja/invoiceninja:5 + env_file: env + restart: always + volumes: + - /etc/localtime:/etc/localtime:ro + - ./config/hosts:/etc/hosts:ro + - ./docker/app/public:/var/www/app/public:rw,delegated + - ./docker/app/storage:/var/www/app/storage:rw,delegated + depends_on: + - db + networks: + - traefik_network + + db: + container_name: invoiceninja-db + image: mariadb:10.4 + restart: always + env_file: env + volumes: + - /etc/localtime:/etc/localtime:ro + - ./docker/mysql/data:/var/lib/mysql:rw,delegated + - ./docker/mysql/bak:/backups:rw + - ./config/mysql/backup-script:/etc/cron.weekly/weekly:ro + networks: + - traefik_network + +networks: + traefik_network: + external: true diff --git a/docker/logstash/docker-compose.yml b/docker/logstash/docker-compose.yml new file mode 100644 index 0000000..9c9b408 --- /dev/null +++ b/docker/logstash/docker-compose.yml @@ -0,0 +1,20 @@ +networks: + traefik_network: + external: true +services: + logstash: + container_name: logstash + image: docker.elastic.co/logstash/logstash:7.17.10 + labels: + - traefik.enable=true + - traefik.http.routers.logstash.rule=Host(`logstash.hessenkamp-server.de`) + - traefik.http.routers.logstash.entrypoints=websecure + - traefik.http.routers.logstash.tls.certresolver=letsencrypt + - traefik.http.services.logstash.loadbalancer.server.port=5044 + networks: + - traefik_network + restart: always + volumes: + - ../containerdaten/logstash/config:/usr/share/logstash/config + - ../containerdaten/logstash/pipeline:/usr/share/logstash/pipeline +version: '3' diff --git a/docker/portainer/docker-compose.yml b/docker/portainer/docker-compose.yml new file mode 100644 index 0000000..d01de44 --- /dev/null +++ b/docker/portainer/docker-compose.yml @@ -0,0 +1,28 @@ +version: '3' + +services: + portainer: + image: portainer/portainer-ce:latest + container_name: portainer + restart: always + security_opt: + - no-new-privileges:true + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - portainer_data:/data + networks: + - traefik_network + labels: + - "traefik.enable=true" + - "traefik.http.routers.portainer.rule=Host(`portainer.hessenkamp-server.de`)" + - "traefik.http.routers.portainer.entrypoints=websecure" + - "traefik.http.routers.portainer.tls.certresolver=letsencrypt" + - "traefik.http.services.portainer.loadbalancer.server.port=9000" + +volumes: + portainer_data: + +networks: + traefik_network: + external: true + diff --git a/docker/prometheus/docker-compose.yml b/docker/prometheus/docker-compose.yml new file mode 100644 index 0000000..85bdbae --- /dev/null +++ b/docker/prometheus/docker-compose.yml @@ -0,0 +1,19 @@ +networks: + traefik_network: + external: true +services: + prometheus: + container_name: prometheus + image: prom/prometheus:latest + labels: + - traefik.enable=true + - traefik.http.routers.prometheus.rule=Host(`prometheus.hessenkamp-server.de`) + - traefik.http.routers.prometheus.entrypoints=websecure + - traefik.http.routers.prometheus.tls.certresolver=letsencrypt + - traefik.http.services.prometheus.loadbalancer.server.port=9090 + networks: + - traefik_network + restart: always + volumes: + - ../containerdaten/prometheus/data:/data +version: '3' diff --git a/docker/traefik/docker-compose.yml b/docker/traefik/docker-compose.yml new file mode 100644 index 0000000..9269672 --- /dev/null +++ b/docker/traefik/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3' +services: + reverse-proxy: + image: traefik:v3.1 + ports: + - "80:80" + - "443:443" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./traefik.yml:/etc/traefik/traefik.yml + - ./acme.json:/acme.json + networks: + - traefik_network + labels: + - "traefik.enable=true" + - "traefik.http.routers.dashboard.rule=Host(`traefik.hessenkamp-server.de`)" + - "traefik.http.routers.dashboard.service=api@internal" + - "traefik.http.routers.dashboard.middlewares=auth" + - "traefik.http.middlewares.auth.basicauth.users=admino:$$apr1$$RaHHY28p$$EMckBAfuRv1BF2Qvy40d20" + - "traefik.http.routers.dashboard.entrypoints=websecure" + - "traefik.http.routers.dashboard.tls=true" + - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" + - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)" + - "traefik.http.routers.http-catchall.entrypoints=web" + - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" + - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + + +networks: + traefik_network: + name: traefik_network + diff --git a/docker/traefik/traefik.yml b/docker/traefik/traefik.yml new file mode 100644 index 0000000..4aa16eb --- /dev/null +++ b/docker/traefik/traefik.yml @@ -0,0 +1,20 @@ +api: + dashboard: true + +entryPoints: + web: + address: ":80" + websecure: + address: ":443" + +providers: + docker: + exposedByDefault: false + +certificatesResolvers: + letsencrypt: + acme: + email: alexander@hessenkamp.de + storage: acme.json + httpChallenge: + entryPoint: web diff --git a/docker/wg-easy/docker-compose.yml b/docker/wg-easy/docker-compose.yml new file mode 100644 index 0000000..671c549 --- /dev/null +++ b/docker/wg-easy/docker-compose.yml @@ -0,0 +1,37 @@ +version: "3" +services: + wg-easy: + image: weejewel/wg-easy + container_name: wg-easy + environment: + - WG_HOST=wgeasy.hessenkamp-server.de + - PASSWORD=!(hB1nDerAdn1n + - WG_PORT=51820 + - WG_DEFAULT_ADDRESS=10.8.0.x + - WG_DEFAULT_DNS=1.1.1.1 + volumes: + - ../containerdaten/wg-easy:/etc/wireguard + ports: + - "51820:51820/udp" + - "51821:51821/tcp" + restart: unless-stopped + cap_add: + - NET_ADMIN + - SYS_MODULE + sysctls: + - net.ipv4.conf.all.src_valid_mark=1 + - net.ipv4.ip_forward=1 + networks: + - traefik_network + labels: + - "traefik.enable=true" + - "traefik.http.routers.wg-easy.rule=Host(`wgeasy.hessenkamp-server.de`)" + - "traefik.http.routers.wg-easy.entrypoints=websecure" + - "traefik.http.routers.wg-easy.tls.certresolver=letsencrypt" + - "traefik.http.services.wg-easy.loadbalancer.server.port=51821" + - "traefik.http.routers.wg-easy.middlewares=wg-easy-auth" + - "traefik.http.middlewares.wg-easy-auth.basicauth.users=admino:$$apr1$$ffntQ3Qe$$WPCeUgCF7jgWYuJ6FyrC9." + +networks: + traefik_network: + external: true diff --git a/docker/wireguard-ui/docker-compose.yml b/docker/wireguard-ui/docker-compose.yml new file mode 100644 index 0000000..9de21e5 --- /dev/null +++ b/docker/wireguard-ui/docker-compose.yml @@ -0,0 +1,54 @@ +version: "3" +services: + wireguard: + image: linuxserver/wireguard + container_name: wireguard + cap_add: + - NET_ADMIN + - SYS_MODULE + environment: + - PUID=1000 + - PGID=1000 + - SERVERURL=wgcool.hessenkamp-server.de + - SERVERPORT=51820 + - PEERS=1 + - PEERDNS=auto + - INTERNAL_SUBNET=10.13.13.0 + volumes: + - ./config:/config + - /lib/modules:/lib/modules + ports: + - 51820:51820/udp + sysctls: + - net.ipv4.conf.all.src_valid_mark=1 + restart: unless-stopped + + wireguard-ui: + image: ngoduykhanh/wireguard-ui:latest + container_name: wireguard-ui + depends_on: + - wireguard + cap_add: + - NET_ADMIN + environment: + - WGUI_USERNAME=admino + - WGUI_PASSWORD=!(hB1nDerAdn1n + - WGUI_MANAGE_START=true + - WGUI_MANAGE_RESTART=true + volumes: + - ./config:/etc/wireguard + - ./db:/app/db + labels: + - "traefik.enable=true" + - "traefik.http.routers.wireguard-ui.rule=Host(`wgcool.hessenkamp-server.de`)" + - "traefik.http.routers.wireguard-ui.entrypoints=websecure" + - "traefik.http.routers.wireguard-ui.tls.certresolver=letsencrypt" + - "traefik.http.services.wireguard-ui.loadbalancer.server.port=5000" + - "traefik.http.routers.wireguard-ui.middlewares=wireguard-auth" + - "traefik.http.middlewares.wireguard-auth.basicauth.users=admino:$$apr1$$ffntQ3Qe$$WPCeUgCF7jgWYuJ6FyrC9." + restart: unless-stopped + +networks: + default: + external: true + name: traefik_network diff --git a/scripts/docker_compose_creator/compose_utils.py b/scripts/docker_compose_creator/compose_utils.py new file mode 100644 index 0000000..d7bc91f --- /dev/null +++ b/scripts/docker_compose_creator/compose_utils.py @@ -0,0 +1,40 @@ +import os +import yaml + +def load_existing_compose(file_path): + try: + with open(file_path, 'r') as f: + return yaml.safe_load(f) + except FileNotFoundError: + return None + +def create_compose_config(service_name): + # Beispieldaten basierend auf dem Service + image_name = input("Enter image name: ") + image_tag = input("Enter image tag [latest]: ") or "latest" + subdomain = input("Enter subdomain for Traefik: ") + container_port = input("Enter container port [80]: ") or "80" + + return { + 'version': '3', + 'services': { + service_name: { + 'image': f"{image_name}:{image_tag}", + 'container_name': service_name, + 'restart': 'always', + 'networks': ['traefik_network'], + 'labels': [ + "traefik.enable=true", + f"traefik.http.routers.{service_name}.rule=Host(`{subdomain}.hessenkamp-server.de`)", + f"traefik.http.routers.{service_name}.entrypoints=websecure", + f"traefik.http.routers.{service_name}.tls.certresolver=letsencrypt", + f"traefik.http.services.{service_name}.loadbalancer.server.port={container_port}" + ] + } + }, + 'networks': { + 'traefik_network': { + 'external': True + } + } + } diff --git a/scripts/docker_compose_creator/create_docker_compose.py b/scripts/docker_compose_creator/create_docker_compose.py new file mode 100644 index 0000000..20e5a90 --- /dev/null +++ b/scripts/docker_compose_creator/create_docker_compose.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +import os +import yaml +from volume_utils import setup_volume_paths, check_existing_volumes +from compose_utils import create_compose_config, load_existing_compose +from permission_utils import check_permissions +from input_utils import get_input +from escape_handler import start_exit_handler + +DOCKER_DIR = os.path.expanduser("~/docker") + +def main(): + start_exit_handler() + service_name = get_input("Enter service name (e.g., gitea, bookstack)") + service_dir = os.path.join(DOCKER_DIR, service_name) + + if os.path.exists(service_dir): + compose_file = os.path.join(service_dir, 'docker-compose.yml') + if os.path.exists(compose_file): + existing_compose = load_existing_compose(compose_file) + if existing_compose: + print("Existing configuration:") + print(yaml.dump(existing_compose, default_flow_style=False)) + print("\nChecking existing volumes:") + check_existing_volumes(existing_compose) + if get_input("Do you want to overwrite this file? (y/n)", "n").lower() != 'y': + print("Operation cancelled.") + return + + compose = create_compose_config(service_name) + + volumes = [] + while True: + volume = get_input("Enter volume mapping (host:container) or press Enter to finish") + if not volume: + break + volumes.append(volume) + + if volumes: + compose['services'][service_name]['volumes'] = volumes + setup_volume_paths(service_name, volumes) + + os.makedirs(service_dir, exist_ok=True) + compose_file = os.path.join(service_dir, 'docker-compose.yml') + with open(compose_file, 'w') as f: + yaml.dump(compose, f, default_flow_style=False) + + print(f"docker-compose.yml has been created successfully in {service_dir}!") + +if __name__ == "__main__": + main() diff --git a/scripts/docker_compose_creator/escape_handler.py b/scripts/docker_compose_creator/escape_handler.py new file mode 100644 index 0000000..84b9d32 --- /dev/null +++ b/scripts/docker_compose_creator/escape_handler.py @@ -0,0 +1,10 @@ +import signal +import sys + +def signal_handler(sig, frame): + print("\nStrg+C wurde gedrückt. Beende das Programm...") + sys.exit(0) + +def start_exit_handler(): + signal.signal(signal.SIGINT, signal_handler) + print("Drücken Sie Strg+C, um das Programm zu beenden.") diff --git a/scripts/docker_compose_creator/escape_handler.py.save b/scripts/docker_compose_creator/escape_handler.py.save new file mode 100644 index 0000000..b28b04f --- /dev/null +++ b/scripts/docker_compose_creator/escape_handler.py.save @@ -0,0 +1,3 @@ + + + diff --git a/scripts/docker_compose_creator/input_utils.py b/scripts/docker_compose_creator/input_utils.py new file mode 100644 index 0000000..4302255 --- /dev/null +++ b/scripts/docker_compose_creator/input_utils.py @@ -0,0 +1,3 @@ +def get_input(prompt, default=None): + value = input(f"{prompt} {f'[{default}]' if default else ''}: ").strip() + return value if value else default diff --git a/scripts/docker_compose_creator/permission_utils.py b/scripts/docker_compose_creator/permission_utils.py new file mode 100644 index 0000000..0462cd7 --- /dev/null +++ b/scripts/docker_compose_creator/permission_utils.py @@ -0,0 +1,84 @@ +import os +import stat +import subprocess + +# Standardwerte für Berechtigungen +DEFAULT_DIR_PERMS = 0o755 +DEFAULT_FILE_PERMS = 0o644 +DEFAULT_OWNER = "65534:65534" # nobody:nogroup + +def check_permissions(path): + try: + stat_info = os.stat(path) + uid = stat_info.st_uid + gid = stat_info.st_gid + mode = stat_info.st_mode + if uid == 65534 and gid == 65534 and (mode & 0o777) == 0o755: + print(f"Permissions are correct for: {path}") + else: + print(f"Warning: Permissions may not be correct for: {path}") + print(f"Current: UID={uid}, GID={gid}, Mode={mode:o}") + print(f"Expected: UID=65534, GID=65534, Mode=755") + except OSError as e: + print(f"Error checking permissions: {e}") + +def set_permissions(path, is_directory=True): + if is_directory: + perms = input(f"Enter directory permissions [{DEFAULT_DIR_PERMS:o}]: ") or DEFAULT_DIR_PERMS + else: + perms = input(f"Enter file permissions [{DEFAULT_FILE_PERMS:o}]: ") or DEFAULT_FILE_PERMS + + owner = input(f"Enter owner [{DEFAULT_OWNER}]: ") or DEFAULT_OWNER + + if isinstance(perms, str): + perms = int(perms, 8) + + try: + subprocess.run(['sudo', 'chmod', f'{perms:o}', path], check=True) + subprocess.run(['sudo', 'chown', owner, path], check=True) + print(f"Set permissions for {path}: {perms:o}, owner: {owner}") + except subprocess.CalledProcessError as e: + print(f"Error setting permissions: {e}") + +def set_permissions_recursive(path): + for root, dirs, files in os.walk(path): + set_permissions(root, is_directory=True) + for file in files: + set_permissions(os.path.join(root, file), is_directory=False) + +def ensure_correct_permissions(path, is_directory=True): + stat_info = os.stat(path) + uid = stat_info.st_uid + gid = stat_info.st_gid + mode = stat_info.st_mode + + expected_mode = DEFAULT_DIR_PERMS if is_directory else DEFAULT_FILE_PERMS + + if uid != 65534 or gid != 65534 or (mode & 0o777) != expected_mode: + print(f"Correcting permissions for: {path}") + set_permissions(path, is_directory) + else: + print(f"Permissions are already correct for: {path}") + +def ensure_correct_permissions_recursive(path): + for root, dirs, files in os.walk(path): + ensure_correct_permissions(root, is_directory=True) + for file in files: + ensure_correct_permissions(os.path.join(root, file), is_directory=False) + +def create_files_in_directory(directory): + while True: + create_file = input(f"Do you want to create a file in {directory}? (y/n): ").lower() + if create_file != 'y': + break + + filename = input("Enter the file name: ") + full_path = os.path.join(directory, filename) + + try: + with open(full_path, 'w') as f: + pass # Create an empty file + print(f"Created file: {full_path}") + set_permissions(full_path, is_directory=False) + except IOError as e: + print(f"Error creating file: {e}") diff --git a/scripts/docker_compose_creator/volume_utils.py b/scripts/docker_compose_creator/volume_utils.py new file mode 100644 index 0000000..c6a0fbf --- /dev/null +++ b/scripts/docker_compose_creator/volume_utils.py @@ -0,0 +1,64 @@ +import os +from permission_utils import set_permissions, check_permissions, set_permissions_recursive + +def setup_volume_paths(service_name, volumes): + created_paths = [] + for volume in volumes: + if ':' in volume: + host_path, _ = volume.split(':', 1) + if host_path.startswith('../containerdaten'): + _, path = host_path.split('../containerdaten/', 1) + full_path = os.path.expanduser(f"~/docker/containerdaten/{path}") + created_paths.extend(setup_volume_path(service_name, full_path)) + + # Setze Berechtigungen für alle erstellten Pfade am Ende + for path in created_paths: + set_permissions_recursive(path) + +def setup_volume_path(service_name, full_path): + created_paths = [] + if not os.path.exists(full_path): + os.makedirs(full_path, exist_ok=True) + print(f"Created directory: {full_path}") + else: + print(f"Directory already exists: {full_path}") + + created_paths.append(full_path) + + while True: + create_file_choice = input(f"Do you want to create a file in {full_path}? (y/n): ").lower() + if create_file_choice != 'y': + break + file_name = input("Enter the file name: ") + file_path = create_file(full_path, file_name) + if file_path: + created_paths.append(file_path) + + return created_paths + +def create_file(path, filename): + full_path = os.path.join(path, filename) + try: + with open(full_path, 'w') as f: + pass # Create an empty file + print(f"Created file: {full_path}") + return full_path + except IOError as e: + print(f"Error creating file: {e}") + return None + +def check_existing_volumes(compose_data): + if 'services' in compose_data: + for service in compose_data['services'].values(): + if 'volumes' in service: + for volume in service['volumes']: + if ':' in volume: + host_path, _ = volume.split(':', 1) + if host_path.startswith('../containerdaten'): + _, path = host_path.split('../containerdaten/', 1) + full_path = os.path.expanduser(f"~/docker/containerdaten/{path}") + if os.path.exists(full_path): + print(f"Directory exists: {full_path}") + check_permissions(full_path) + else: + print(f"Directory does not exist: {full_path}") diff --git a/scripts/escape_handler.py b/scripts/escape_handler.py new file mode 100644 index 0000000..84b9d32 --- /dev/null +++ b/scripts/escape_handler.py @@ -0,0 +1,10 @@ +import signal +import sys + +def signal_handler(sig, frame): + print("\nStrg+C wurde gedrückt. Beende das Programm...") + sys.exit(0) + +def start_exit_handler(): + signal.signal(signal.SIGINT, signal_handler) + print("Drücken Sie Strg+C, um das Programm zu beenden.") diff --git a/scripts/start_docker_services.py b/scripts/start_docker_services.py new file mode 100644 index 0000000..2542afb --- /dev/null +++ b/scripts/start_docker_services.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import sys +from escape_handler import start_exit_handler + +DOCKER_DIR = "/home/andiamolino/docker" + +def get_running_containers(): + """Gibt eine Liste der laufenden Container zurück.""" + result = subprocess.run(["docker", "ps", "--format", "{{.Names}}"], capture_output=True, text=True) + return result.stdout.strip().split('\n') if result.stdout else [] + +def stop_container(container_name): + """Stoppt einen spezifischen Container.""" + subprocess.run(["docker", "stop", container_name], check=True) + +def start_docker_compose(dir_path): + """Startet Docker-Compose in einem bestimmten Verzeichnis.""" + print(f"Starte Docker-Compose in {dir_path}") + subprocess.run(["docker-compose", "up", "-d"], cwd=dir_path, check=True) + +def get_docker_compose_dirs(): + """Findet alle Verzeichnisse mit einer docker-compose.yml Datei.""" + dirs = [] + for dir_name in os.listdir(DOCKER_DIR): + dir_path = os.path.join(DOCKER_DIR, dir_name) + if os.path.isdir(dir_path) and dir_name != "containerdaten": + if os.path.exists(os.path.join(dir_path, "docker-compose.yml")): + dirs.append(dir_path) + return dirs + +def main(): + start_exit_handler + running_containers = get_running_containers() + + if running_containers: + print("Laufende Container:") + for container in running_containers: + print(f"- {container}") + + choice = input("Möchten Sie laufende Container stoppen? (j/n): ").strip().lower() + if choice == 'j': + for container in running_containers: + stop_container(container) + print("Alle laufenden Container wurden gestoppt.") + + start_new = input("Möchten Sie neue Container starten? (j/n): ").strip().lower() + if start_new != 'j': + print("Keine neuen Container werden gestartet. Programm wird beendet.") + sys.exit(0) + + docker_dirs = get_docker_compose_dirs() + + print("\nGefundene Docker-Compose-Projekte:") + for i, dir_path in enumerate(docker_dirs, 1): + print(f"{i}. {os.path.basename(dir_path)}") + + print("\nWählen Sie die zu startenden Projekte (durch Kommas getrennte Nummern, oder 'alle'):") + choice = input().strip().lower() + + if choice == 'alle': + to_start = docker_dirs + else: + try: + indices = [int(x.strip()) - 1 for x in choice.split(',')] + to_start = [docker_dirs[i] for i in indices if 0 <= i < len(docker_dirs)] + except ValueError: + print("Ungültige Eingabe. Beende Programm.") + sys.exit(1) + + # Stelle sicher, dass Traefik zuerst gestartet wird + traefik_dir = next((d for d in to_start if os.path.basename(d) == "traefik"), None) + if traefik_dir: + to_start.remove(traefik_dir) + to_start.insert(0, traefik_dir) + + for dir_path in to_start: + try: + start_docker_compose(dir_path) + except subprocess.CalledProcessError as e: + print(f"Fehler beim Starten von {os.path.basename(dir_path)}: {e}") + +if __name__ == "__main__": + main()