Files
podman-mvp/CLAUDE.md
T
kodi fba9b59445 docs: update documentatie voor app_volumes en tabs tree view
- CLAUDE.md: app_volumes.py in module-tabel, frontend tabs lijst, py_compile en smoke tests
- ARCHITECTURE.md: app_volumes.py in feature routers, py_compile en smoke tests
- API_GOLDEN.md: volumes endpoints gedocumenteerd (GET/POST/DELETE/prune/exists)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 18:26:08 +01:00

5.5 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

podman-mvp is a Portainer-like web dashboard for managing rootless user-session Podman containers. It runs as a two-container Podman pod: a FastAPI backend (mvp-backend) that talks to Podman over a Unix socket, and a static Apache frontend (mvp-webui) that reverse-proxies /api/ to the backend.

Architecture

Backend — FastAPI modular monolith (control/)

File Role
app.py Bootstrap only — creates FastAPI app, wires routers, no feature logic
common.py Shared helpers: Podman HTTP, systemctl, utilities
app_system.py System/platform router: /health, /daemon-reload, systemctl unit actions
app_containers.py Containers router: dashboard, inspect, logs, stats stream, exec sessions
app_pods.py Pods router: dashboard, pod actions
app_networks.py Networks router
app_images.py Images router
app_volumes.py Volumes router: list, create, delete, prune, exists
app_files.py Files/workloads router: tree, read, save

Backend communicates with Podman through the Unix socket at /run/user/1000/podman/podman.sock using requests_unixsocket. Podman API base: http+unix://%2Frun%2Frun%2Fuser%2F1000%2Fpodman%2Fpodman.sock/v5.4.2.

Frontend — Static Apache (webui/)

  • webui/html/index.html — single-page app shell
  • webui/html/assets/js/tabs/ — per-tab JavaScript modules (containers, networks, images, volumes, files)
  • webui/conf/httpd.conf — Apache config, proxies /api/http://127.0.0.1:8000/api/

Build & Deploy

# Build backend image
podman build -t mvp-control:latest control/

# Create pod
podman pod create --name mvp-pod -p 8080:8000 -p 8081:8081 --userns=keep-id

# Run backend
podman run -d --pod mvp-pod --name mvp-backend \
  --ipc=host --pid=host \
  -e XDG_RUNTIME_DIR=/run/user/1000 \
  -v /run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock:rw \
  -v /run/user/1000/podman-mvp:/run/podman-mvp \
  -v /home/kodi/.config/containers:/app/workloads:rw \
  mvp-control:latest

# Run frontend
podman run -d --pod mvp-pod --name mvp-webui \
  -v $HOME/.config/podman-mvp/webui/html:/usr/local/apache2/htdocs:ro \
  -v $HOME/.config/podman-mvp/webui/conf/httpd.conf:/usr/local/apache2/conf/httpd.conf:ro \
  docker.io/library/httpd:2.4

Verification Commands

# Syntax check all backend modules
python3 -m py_compile control/app.py control/common.py control/app_system.py \
  control/app_containers.py control/app_pods.py control/app_networks.py \
  control/app_files.py control/app_images.py control/app_volumes.py

# Smoke test key endpoints (all via proxy on :8081)
curl -fsS http://127.0.0.1:8081/api/health | jq
curl -fsS http://127.0.0.1:8081/api/containers-dashboard >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/pods-dashboard >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/files/tree >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/volumes >/dev/null && echo OK
curl -fsS http://127.0.0.1:8081/api/networks/meta | jq

All test/verification URLs must target 127.0.0.1:8081 (the proxy), not port 8000 directly.

Health Check (/api/health)

GET /api/health geeft drie deelresultaten terug:

Veld Wat het meet Techniek
podman.ok Podman API bereikbaar HTTP GET /libpod/info op Unix socket
helper.ok podman-helper socket bereikbaar TCP connect op /run/podman-mvp/podman-helper.sock
systemd_user.reachable Afgeleid van helper.ok Identiek — helper draait als host-user en voert systemctl --user uit, dus bereikbaarheid van helper impliceert bereikbaarheid van systemd

ok (toplevel) is true als én podman.ok én helper.ok waar zijn.

De container voert zelf geen systemctl --user of D-Bus aanroepen uit. Alle systemctl-acties (start/stop/restart/daemon-reload) gaan via de helper-socket. D-Bus en /run/user/1000/bus zijn niet gemount.

Hard Rules

Module placement

  • app.py is bootstrap-only — no endpoints, no feature logic, no Podman/systemctl calls.
  • New system/platform endpoints → app_system.py.
  • New domain feature endpoints → the corresponding app_<domain>.py.
  • Shared helpers → common.py, never duplicated into routers.
  • allow_list / allowed_units.txt has been removed and must NOT be reintroduced.
  • app_system.py broad wildcard routes (/{action}/{unit}) must be defined last.

API contract (contracts/API_GOLDEN.md)

  • Never remove or rename existing JSON response keys.
  • Never change existing key data types.
  • Extend via new optional fields or new endpoints only.
  • UI-critical endpoints requiring pre-approval before any change: /containers-dashboard, /pods-dashboard, /images, /networks/meta.

Security

  • No shell=True in subprocess calls.
  • All subprocess commands must be explicit lists.

Infrastructure (propose before changing)

  • Pod name, port mappings, userns=keep-id.
  • DBus/XDG_RUNTIME_DIR mounts, Podman socket path, host PID/IPC namespaces.
  • control/Containerfile, webui/conf/httpd.conf.

Change Workflow

For non-trivial changes, follow PR_RULES.md:

  1. Analyse existing behaviour with curl.
  2. Propose minimal plan identifying affected files.
  3. Confirm API contract safety.
  4. Provide curl validation commands showing expected output change.
  5. Implement after agreement.

Minimize diff size. Do not reformat unrelated code. No large rewrites or hidden refactors.