Skip to content

fix(container): preserve image init process#2243

Merged
yohamta0 merged 4 commits into
mainfrom
fix/container-init-reaper
Jun 1, 2026
Merged

fix(container): preserve image init process#2243
yohamta0 merged 4 commits into
mainfrom
fix/container-init-reaper

Conversation

@yohamta0

@yohamta0 yohamta0 commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • install Tini in official Docker images and run /entrypoint.sh under it so containers reap orphaned step subprocesses
  • keep the image entrypoint active in Helm and Kubernetes manifests by passing Dagu commands through args
  • preserve Tini in the Docker socket/root Compose example and add packaging regression tests
  • add pod fsGroup defaults so Helm/static Kubernetes deployments can still write the shared data volume after the entrypoint drops privileges
  • update vulnerable golang.org/x modules reported by govulncheck so security CI is green

Testing

  • make fmt
  • go test ./internal/packaging -count=1
  • helm lint ./charts/dagu
  • helm template dagu ./charts/dagu --set persistence.storageClass=nfs-client
  • docker compose -f deploy/docker/compose.minimal.yaml config
  • docker compose -f deploy/docker/compose.prod.yaml config
  • go run golang.org/x/vuln/cmd/govulncheck@v1.2.0 ./...
  • go test ./internal/packaging ./internal/runtime/builtin/ssh ./internal/gitsync -count=1
  • go test ./api/v1 -count=1
  • go mod verify

Closes #2237

Summary by CodeRabbit

Release Notes

  • New Features

    • Added tini init process (PID 1) to Docker images for improved container process management and signal handling.
  • Improvements

    • Updated Kubernetes deployments to use consistent container argument handling.
    • Added default pod security context with proper file group permissions for shared volumes.
  • Documentation

    • Updated Helm chart documentation with security context and volume permission guidance.
  • Tests

    • Added comprehensive container initialization and entrypoint validation tests.
  • Chores

    • Bumped Helm chart version to 1.0.9.
    • Updated Go dependencies.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 22bb22f0-35ea-4f83-8e28-91d0b03d31a9

📥 Commits

Reviewing files that changed from the base of the PR and between 2decfe2 and 7430463.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (10)
  • charts/dagu/README.md
  • charts/dagu/templates/coordinator-deployment.yaml
  • charts/dagu/templates/scheduler-deployment.yaml
  • charts/dagu/templates/ui-deployment.yaml
  • charts/dagu/templates/worker-deployment.yaml
  • charts/dagu/values.yaml
  • deploy/k8s/server-deployment.yaml
  • deploy/k8s/worker-deployment.yaml
  • go.mod
  • internal/packaging/container_init_test.go
✅ Files skipped from review due to trivial changes (3)
  • charts/dagu/values.yaml
  • deploy/k8s/worker-deployment.yaml
  • charts/dagu/README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • deploy/k8s/server-deployment.yaml
  • charts/dagu/templates/ui-deployment.yaml
  • charts/dagu/templates/scheduler-deployment.yaml
  • charts/dagu/templates/coordinator-deployment.yaml
  • internal/packaging/container_init_test.go

📝 Walkthrough

Walkthrough

This PR integrates tini across Docker images, Kubernetes manifests, and Docker Compose so entrypoints run under tini -g --. Helm chart values/docs set a default podSecurityContext.fsGroup: 1000, the Helm chart version is bumped, and tests were added to validate entrypoint and fsGroup patterns.

Changes

Init Process Integration

Layer / File(s) Summary
Docker image tini installation and entrypoint setup
Dockerfile, Dockerfile.alpine, Dockerfile.dev, deploy/docker/Dockerfile.alpine, deploy/docker/Dockerfile.dev
All Dockerfile variants install tini, create symlinks to /usr/local/bin/tini where necessary, and update ENTRYPOINT to run /entrypoint.sh via tini -g -- instead of directly.
Kubernetes manifests, Helm values & docs
charts/dagu/Chart.yaml, charts/dagu/templates/*, charts/dagu/values.yaml, charts/dagu/README.md, deploy/k8s/*, deploy/k8s/README.md
Helm templates and plain Kubernetes manifests switch from command: to args: to preserve the image entrypoint; chart version bumped to 1.0.9; podSecurityContext.fsGroup: 1000 added to values and documented.
Docker Compose entrypoint preservation
deploy/docker/compose.minimal.yaml
Compose minimal config now sets an explicit entrypoint that runs tini -g -- instead of clearing the image entrypoint.
Container init behavior validation
internal/packaging/container_init_test.go
New test suite validates Dockerfiles run entrypoint under tini, Kubernetes manifests use args: (not command:), compose does not clear entrypoint, and fsGroup: 1000 is present without fsGroupChangePolicy. Includes repo-root and file-reading helpers.
go.mod indirect dependency updates
go.mod
Bumped several indirect golang.org/x/* module versions and removed several unused indirect requirements.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(container): preserve image init process' is concise and directly describes the main change: integrating an init process to preserve container behavior while reaping orphaned processes.
Description check ✅ Passed The pull request description follows the template structure with Summary and Testing sections, clearly explaining the changes and testing performed. It links to the related issue #2237 and covers all major objectives.
Linked Issues check ✅ Passed All primary objectives from issue #2237 are met: Tini is installed in Docker images [Dockerfile, Dockerfile.alpine, Dockerfile.dev], container entrypoints run under Tini, image entrypoints are preserved in Helm/K8s manifests via args instead of command, fsGroup defaults are added, and Go dependencies are updated. Comprehensive tests validate the changes.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #2237 objectives: installing and running Tini as init process, updating Helm/Kubernetes manifests to preserve entrypoints, adding fsGroup security context, adding regression tests, and updating vulnerable dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/container-init-reaper

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
charts/dagu/templates/coordinator-deployment.yaml (1)

27-31: ⚠️ Potential issue | 🟠 Major

Ensure /entrypoint.sh privilege-drop is compatible with the mounted /data PVC

Switching command:args: preserves the image’s tini ENTRYPOINT, so Kubernetes now executes /entrypoint.sh:

args:
  - dagu
  - coordinator
  - --config
  - /etc/dagu/dagu.yaml

entrypoint.sh ends with:

  • exec sudo ... -u "#${PUID}" -g "#${RUN_GID}" -- "$@"

The Helm chart sets no securityContext/runAsUser/fsGroup, and the image defaults PUID=${USER_UID} / PGID=${USER_GID} (both default to 1000; DOCKER_GID=-1RUN_GID=PGID). That changes the container from running as root (when command: bypassed the ENTRYPOINT) to running as 1000:1000.

Because the entrypoint only mkdir -p $DAGU_HOME (and the chart sets DAGU_HOME=/data) without chowning the mounted PVC, pre-existing /data permissions that were root-owned or otherwise not readable/writable by UID 1000 may break pods after this change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@charts/dagu/templates/coordinator-deployment.yaml` around lines 27 - 31, The
container now runs the image ENTRYPOINT which drops privileges to PUID/PGID
(PUID/PGID → RUN_GID) and may be unable to write the mounted /data (DAGU_HOME);
add a compatible securityContext and/or an init step: set
pod.spec.containers[*].securityContext to runAsUser: <PUID> and fsGroup:
<RUN_GID> (make these values configurable via chart values), or add an
initContainer that runs as root to mkdir -p $DAGU_HOME and chown it to the same
UID/GID before the main container starts; reference the args block (switch to
ENTRYPOINT), entrypoint.sh privilege-drop, PUID, RUN_GID, PGID, and DAGU_HOME
when implementing the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/packaging/container_init_test.go`:
- Around line 33-38: Replace raw t.Fatalf checks in container_init_test.go with
stretchr/testify require assertions: where the test currently does string
presence checks using strings.Contains and t.Fatalf (referencing variables
tiniEntrypoint, content, and file), use require.Contains/require.NotContains
(e.g., require.Contains(t, content, tiniEntrypoint, "%s must run /entrypoint.sh
under tini") and require.True/require.False as appropriate) and replace any
readFile error checks with require.NoError(t, err, "read %s", path). Apply the
same pattern to the other occurrences called out (lines around the blocks
referencing content/file at 61-66, 76-81, 88-99) to ensure consistent
testify-style assertions.

---

Outside diff comments:
In `@charts/dagu/templates/coordinator-deployment.yaml`:
- Around line 27-31: The container now runs the image ENTRYPOINT which drops
privileges to PUID/PGID (PUID/PGID → RUN_GID) and may be unable to write the
mounted /data (DAGU_HOME); add a compatible securityContext and/or an init step:
set pod.spec.containers[*].securityContext to runAsUser: <PUID> and fsGroup:
<RUN_GID> (make these values configurable via chart values), or add an
initContainer that runs as root to mkdir -p $DAGU_HOME and chown it to the same
UID/GID before the main container starts; reference the args block (switch to
ENTRYPOINT), entrypoint.sh privilege-drop, PUID, RUN_GID, PGID, and DAGU_HOME
when implementing the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 69d35c92-5519-4e87-9d9a-c9d287d05ecd

📥 Commits

Reviewing files that changed from the base of the PR and between 90e344e and 2decfe2.

📒 Files selected for processing (15)
  • Dockerfile
  • Dockerfile.alpine
  • Dockerfile.dev
  • charts/dagu/Chart.yaml
  • charts/dagu/templates/coordinator-deployment.yaml
  • charts/dagu/templates/scheduler-deployment.yaml
  • charts/dagu/templates/ui-deployment.yaml
  • charts/dagu/templates/worker-deployment.yaml
  • deploy/docker/Dockerfile.alpine
  • deploy/docker/Dockerfile.dev
  • deploy/docker/compose.minimal.yaml
  • deploy/k8s/README.md
  • deploy/k8s/server-deployment.yaml
  • deploy/k8s/worker-deployment.yaml
  • internal/packaging/container_init_test.go

Comment thread internal/packaging/container_init_test.go Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 15 files

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 8 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread charts/dagu/values.yaml Outdated
@yohamta0

yohamta0 commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@yohamta0 yohamta0 merged commit d5885ef into main Jun 1, 2026
15 checks passed
@yohamta0 yohamta0 deleted the fix/container-init-reaper branch June 1, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: zombie processes accumulation in containers

1 participant