Recreate containers when a deploy rebuilds their image #2

Merged
reudy merged 1 commit from redeploy-fix into main 2026-09-27 22:44:23 +02:00
Member

Fixes "sync and deploy doesn't pick up the new code".

Cause. The image was rebuilt. Only the early layers (e.g. npm ci) came from cache, and COPY . . and later steps ran again. But podman-compose recreates containers only when the compose file's own hash changes. After a code-only push, the old containers kept running the old image.

Fix.

  • panelctl deploy now runs compose build first. If a container's image ID no longer matches its tag, it runs up --force-recreate; otherwise it runs a plain up. The deployment log shows "Images changed, recreating the app's containers". A deploy with nothing changed leaves the containers alone.
  • Every compose call passes -p <app>. Before, the project name came from the compose file's directory, so every git app (stacks/<app>/repo/compose.yaml) was the project repo. That had three effects:
    • the Terminal tab refused git apps' containers;
    • Monitoring couldn't match their containers to the app;
    • --remove-orphans could remove another git app's containers.
  • Migration. On an app's next deploy or restart, its containers from the old project are removed and recreated under its own name. An app whose containers use named volumes keeps the old project, because the volumes are named after it (repo_data). The manifest records that as APP_COMPOSE_PROJECT, and panelctl then skips --remove-orphans so it can't touch other apps.

Tested with real podman 5 and podman-compose 1.5.0 (the version the VPS uses), in a privileged container, using the real panelctl:

  • Three git apps were first deployed the old way, all in project repo.
  • Two of them migrate to their own projects and the third (named volume) stays on repo. No app loses its containers.
  • A code-only change rebuilds from COPY . . onward, and the running container serves the new version.
  • A deploy with nothing changed keeps the same container.

The 64 API checks pass, as does nix flake check.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UbWSNkXxZhYf7eqHTyx3Bf

Fixes "sync and deploy doesn't pick up the new code". **Cause.** The image *was* rebuilt. Only the early layers (e.g. `npm ci`) came from cache, and `COPY . .` and later steps ran again. But podman-compose recreates containers only when the compose file's own hash changes. After a code-only push, the old containers kept running the old image. **Fix.** - `panelctl deploy` now runs `compose build` first. If a container's image ID no longer matches its tag, it runs `up --force-recreate`; otherwise it runs a plain `up`. The deployment log shows "Images changed, recreating the app's containers". A deploy with nothing changed leaves the containers alone. - Every compose call passes `-p <app>`. Before, the project name came from the compose file's directory, so every git app (`stacks/<app>/repo/compose.yaml`) was the project `repo`. That had three effects: - the Terminal tab refused git apps' containers; - Monitoring couldn't match their containers to the app; - `--remove-orphans` could remove another git app's containers. - **Migration.** On an app's next deploy or restart, its containers from the old project are removed and recreated under its own name. An app whose containers use named volumes keeps the old project, because the volumes are named after it (`repo_data`). The manifest records that as `APP_COMPOSE_PROJECT`, and panelctl then skips `--remove-orphans` so it can't touch other apps. **Tested** with real podman 5 and podman-compose 1.5.0 (the version the VPS uses), in a privileged container, using the real panelctl: - Three git apps were first deployed the old way, all in project `repo`. - Two of them migrate to their own projects and the third (named volume) stays on `repo`. No app loses its containers. - A code-only change rebuilds from `COPY . .` onward, and the running container serves the new version. - A deploy with nothing changed keeps the same container. The 64 API checks pass, as does `nix flake check`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01UbWSNkXxZhYf7eqHTyx3Bf
agent added 1 commit 2026-09-27 22:40:15 +02:00
podman-compose only recreates containers when the compose file's own hash
changes. A push that only changed code built a new image, but the running
containers kept the old one. Deploys now build first and pass
--force-recreate when a container's image ID no longer matches its tag.

Compose calls also pass -p with the app's name. Without it, compose named
the project after the compose file's directory, so every git app
(stacks/<app>/repo/compose.yaml) was the project "repo". That broke the
terminal and monitoring checks, and --remove-orphans could remove another
git app's containers. On its next deploy or restart, an app's containers
from the old project are removed and recreated under the new name. An app
whose containers use named volumes keeps the old project (recorded as
APP_COMPOSE_PROJECT), since its volumes are named after it; for those apps
panelctl skips --remove-orphans.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UbWSNkXxZhYf7eqHTyx3Bf
reudy merged commit ba0a0155c8 into main 2026-09-27 22:44:23 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: reudy-net/panel#2
No description provided.