clusev/resources/views/livewire/modals
boban 35b7c15598 feat(docker): container management over SSH (feature 3/8)
Manage the containers running ON a fleet server, agentlessly — the integrated Portainer.
List containers + state, view logs, start/stop/restart, all via `docker` over SSH.

- DockerService (over FleetService::runPrivileged → base64 transport, shell-injection-safe):
  containers() parses `docker ps -a --format '{{json .}}'`; containerAction() with an op allow-list
  (start|stop|restart|pause|unpause); logs() with a clamped tail; composeStacks() read-only. Every
  container ref is validated `^[a-zA-Z0-9][\w.-]*$` before interpolation — blocks shell metacharacters
  AND a leading-dash argument injection (mirrors serviceAction). A missing/errored docker → [] (never
  throws to the UI).
- Docker\Index page (route /docker, sidebar "Docker" with a new box icon): lazy container list for the
  active server, open to any role. Container actions are `operate`-gated (abort_unless per method) and
  audited (docker.action). Reading LOGS is also operate-gated (container output can leak secrets —
  consistent with gating file CONTENT reads); the list/state stays open. ContainerLogs modal re-gates
  the read itself.
- lang/{de,en}/docker.php + audit.php docker.action + shell.nav_docker (de/en parity). No emoji.

Codex hardening applied: logs output is byte-capped (head -c 262144) AND mb_scrub'd before it reaches
a Livewire property (invalid UTF-8 / a huge line can't break the JSON snapshot); the ref regex uses
\A…\z anchors so a trailing newline can't slip past.

16 new tests: service (json parse, empty-on-unavailable, valid-op command, reject unknown-op / shell-
metachars / leading-dash / trailing-newline ref, logs clamp+byte-cap, available probe), component
(viewer browses the list; viewer 403 on action AND on logs open + modal read; operator/admin act +
audited; logs modal tail). 685 tests green, Pint, lang parity, Codex-reviewed (fixes applied).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:23:56 +02:00
..
.gitkeep feat: scaffold — Dockerized Laravel 13 + Livewire 3 + Tailwind 4 + Reverb 2026-06-12 00:31:50 +02:00
add-ssh-key.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00
confirm-action.blade.php feat(security): signed confirm-action tokens + airtight backup-code reveal 2026-06-15 18:35:33 +02:00
container-logs.blade.php feat(docker): container management over SSH (feature 3/8) 2026-07-05 20:23:56 +02:00
create-server.blade.php feat(files): image preview in the file manager; modal polish 2026-06-14 23:10:37 +02:00
create-user.blade.php feat(rbac): user-management roles UI — role badge, selector, role-change with last-admin guard 2026-07-05 01:15:32 +02:00
edit-credential.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00
fail2ban-ban.blade.php feat(i18n): bilingual foundation (DE/EN) + localize auth/dashboard/servers/fleet/account 2026-06-13 22:36:16 +02:00
fail2ban-bans.blade.php feat(fail2ban): lazy-load Gesperrte IPs modal behind a skeleton 2026-06-15 03:05:35 +02:00
fail2ban-config.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00
file-editor.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00
firewall-rule.blade.php i18n: complete DE/EN localization (modals, shell, backend) + v0.3.0 2026-06-13 23:27:42 +02:00
hardening-action.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00
host-shell.blade.php fix(terminal): make the saved host-login state unmistakable in the modal 2026-06-25 20:08:50 +02:00
recovery-codes.blade.php feat(security): signed confirm-action tokens + airtight backup-code reveal 2026-06-15 18:35:33 +02:00
ssh-key-provision.blade.php feat(files): image preview in the file manager; modal polish 2026-06-14 23:10:37 +02:00
system-update.blade.php polish(ui): in-system design refinements from the design review 2026-07-05 18:06:32 +02:00