diff --git a/backend/Dockerfile b/backend/Dockerfile index 45b3bd9..2e8e7a4 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,15 +1,7 @@ FROM python:3.11-slim RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - curl \ - && curl -fsSL https://download.docker.com/linux/static/stable/x86_64/docker-27.5.1.tgz \ - | tar -xz --strip-components=1 -C /usr/local/bin docker/docker \ - && curl -fsSL "https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64" \ - -o /usr/local/bin/docker-compose \ - && chmod +x /usr/local/bin/docker-compose \ - && mkdir -p /usr/local/lib/docker/cli-plugins \ - && ln -s /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins/docker-compose \ + systemctl \ && rm -rf /var/lib/apt/lists/* WORKDIR /app diff --git a/backend/admin/router.py b/backend/admin/router.py index 9a2bb2d..3aab518 100644 --- a/backend/admin/router.py +++ b/backend/admin/router.py @@ -42,36 +42,13 @@ async def deploy(request: Request): logger.info("Auto-deploy triggered via Gitea webhook") - project_path = settings.deploy_project_path - # Write a deploy script to the host filesystem (via the mounted project path) - # then execute it with nsenter into the host's PID namespace so it runs as - # a host process — not a container child — and survives container restarts. - script_path = f"{project_path}/deploy.sh" - log_path = f"{project_path}/deploy.log" - script = ( - f"#!/bin/sh\n" - f"exec > {log_path} 2>&1\n" - f"echo \"Deploy started at $(date)\"\n" - f"git config --global --add safe.directory {project_path}\n" - f"cd {project_path}\n" - f"git fetch origin main\n" - f"git reset --hard origin/main\n" - f"docker-compose up -d --build\n" - f"echo \"Deploy finished at $(date)\"\n" - ) - - with open(script_path, "w") as f: - f.write(script) - - # nsenter into host PID namespace (PID 1 = host init) so the process - # is owned by the host and survives this container restarting. - trigger_cmd = f"chmod +x {script_path} && nsenter -t 1 -m -u -i -n -p -- sh -c 'nohup {script_path} &'" - + # Trigger the host-side systemd service which runs as the bellsystems user. + # This avoids running git/docker as root inside the container. await asyncio.create_subprocess_shell( - trigger_cmd, + "systemctl start bellsystems-deploy", stdout=asyncio.subprocess.DEVNULL, stderr=asyncio.subprocess.DEVNULL, ) - logger.info("Auto-deploy triggered on host via nsenter") + logger.info("Auto-deploy triggered via systemd") return {"ok": True, "message": "Deploy started"} diff --git a/docker-compose.yml b/docker-compose.yml index 2d5f4f1..ee5449f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,11 +10,9 @@ services: - ./data/built_melodies:/app/storage/built_melodies - ./data/firmware:/app/storage/firmware - ./data/firebase-service-account.json:/app/firebase-service-account.json:ro - # Auto-deploy: project root and Docker socket - - /home/bellsystems/bellsystems-cp:/home/bellsystems/bellsystems-cp - - /var/run/docker.sock:/var/run/docker.sock - pid: host - privileged: true + # Auto-deploy: systemd socket so container can trigger host services + - /run/systemd/private:/run/systemd/private + - /run/dbus/system_bus_socket:/run/dbus/system_bus_socket ports: - "8000:8000" depends_on: [] diff --git a/frontend/src/layout/Header.jsx b/frontend/src/layout/Header.jsx index f8118a6..83c3f05 100644 --- a/frontend/src/layout/Header.jsx +++ b/frontend/src/layout/Header.jsx @@ -12,7 +12,7 @@ export default function Header() { }} >