grundstruktur der dockerverzeichnisse mit richtegen funktionsfähigen docker files

This commit is contained in:
Alexander Hessenkamp
2024-08-22 16:25:57 +02:00
parent 034aedef72
commit 464b87a74b
22 changed files with 765 additions and 0 deletions

View File

@@ -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
}
}
}

View File

@@ -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()

View File

@@ -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.")

View File

@@ -0,0 +1,3 @@

View File

@@ -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

View File

@@ -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}")

View File

@@ -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}")

10
scripts/escape_handler.py Normal file
View File

@@ -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.")

View File

@@ -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()