Task ordering design policy:
- Phase 1 (this phase): Reproduce an image with the same specifications as the current one using a DHI base image + TypeScript entrypoint. The build pipeline (3-stage structure using
COPY . .) is kept as-is, prioritizing a safe runtime migration.- Phase 2 (next phase): Introduction of build optimization via the
turbo prune --dockerpattern. This will be done after runtime is stable in Phase 1. Adding pruner/deps stages to create a 5-stage structure.Implementation directory: Create new files in
apps/app/docker-new/. The existingapps/app/docker/will not be modified at all. Maintain a state where parallel comparison and verification is possible.Directory permission handling is implemented and tested as the highest priority to detect regressions early. Since the entrypoint (TypeScript) and Dockerfile are independent files, some tasks can be executed in parallel.
[x] 1. (P) Strengthen build context filter
.git, .env* (except production), test files, IDE configuration files, etc. to the current exclusion rulesnode_modules, .next, .turbo, apps/slackbot-proxy, etc.)[x] 2. TypeScript entrypoint directory initialization and permission management
[x] 2.1 (P) Create entrypoint skeleton and recursive chown helper
main() function with top-level try-catch for error handling[x] 2.2 Implement directory initialization processing
/data/uploads, symlink creation to ./public/uploads, and recursive ownership change/tmp/page-bulk-export, recursive ownership change, and permission 700 settingrecursive: true for mkdir, prevent duplicate symlink creation)docker-entrypoint.sh (using fs mocks, verifying each state of directories, symlinks, ownership, and permissions)[x] 2.3 Implement privilege dropping
[x] 3. Heap size calculation and node flag assembly
[x] 3.1 (P) Implement cgroup memory limit detection
"max" string as unlimited)[x] 3.2 (P) Implement heap size specification via environment variable
GROWI_HEAP_SIZE environment variable (positive integer, in MB)[x] 3.3 Implement node flag assembly and log output
--expose_gc flag--optimize-for-size when GROWI_OPTIMIZE_MEMORY=true, and --lite-mode when GROWI_LITE_MODE=true--max-heap-size directly as a spawn argument (do not use --max_old_space_size, do not include in NODE_OPTIONS)[x] 4. Migration execution and app process management
[x] 4.1 Direct migration execution
[x] 4.2 App process startup and signal management
[x] 5. Dockerfile reconstruction (current 3-stage pattern + DHI)
[x] 5.1 (P) Build the base stage
--no-install-recommends and apply apt cache mounts[x] 5.2 Build the builder stage
COPY . . pattern to copy the entire monorepo, then install dependencies, build, and extract production dependencies--frozen-lockfile typo (3 dashes -> 2 dashes)apps/app/tmp directory).next/cache is not included in the artifact[x] 5.3 Build the release stage
[x] 5.4 (P) Configure OCI labels and port/volume declarations
EXPOSE 3000 and VOLUME /data[x] 6. Integration verification and backward compatibility confirmation
[x] 6.1 Docker build E2E verification
[x] 6.2 Runtime behavior and backward compatibility verification
MONGO_URI, FILE_UPLOAD, etc.) are transparently passed to the application as before/data volume mounts and file upload functionalitydocker compose up and graceful shutdown via SIGTERMTo be done after runtime is stable in Phase 1. Migrate from the current
COPY . .+ 3-stage structure to aturbo prune --docker+ 5-stage structure to improve build cache efficiency.
[x] 7.1 Create pruner stage
turbo prune @growi/app @growi/pdf-converter --docker@growi/pdf-converter: @growi/pdf-converter-client/turbo.json has a task dependency on @growi/pdf-converter#gen:swagger-spec, so turbo cannot resolve task dependencies unless it is included in the pruned workspace[x] 7.2 Separate deps stage and restructure builder
[x] 7.3 Integration verification of 5-stage structure
To be done after the 5-stage structure is stable in Phase 2. Move the artifacts from
apps/app/docker-new/toapps/app/docker/, delete the old files, and update the CI/CD pipeline for DHI support.
[x] 8.1 (P) Replace docker-new directory with docker directory
apps/app/docker/ (old Dockerfile, docker-entrypoint.sh, old Dockerfile.dockerignore)apps/app/docker-new/ (Dockerfile, docker-entrypoint.ts, docker-entrypoint.spec.ts, Dockerfile.dockerignore) to apps/app/docker/apps/app/docker-new/ directorycodebuild/ directory and README.md are maintained within apps/app/docker/apps/app/docker-new/docker-entrypoint.ts to apps/app/docker/docker-entrypoint.ts)[x] 8.2 (P) Add DHI registry login to buildspec.yml
docker login dhi.io command to the pre_build phase of apps/app/docker/codebuild/buildspec.ymlDOCKER_REGISTRY_PASSWORD secret and growimoogle username./apps/app/docker/Dockerfile) is correct after replacement[x] 8.3 Integration verification after replacement
apps/app/docker/Dockerfilecodebuild.tf, .github/workflows/release.yml, ci-app.yml, update-readme.sh) work correctlyRename the
GROWI_-prefixed memory management environment variables toV8_-prefixed names aligned with V8 option names, and add documentation to the Docker Hub README.
[x] 9.1 (P) Rename all GROWI-prefixed environment variables to V8-prefixed names in the entrypoint
GROWI_HEAP_SIZE to V8_MAX_HEAP_SIZE in the heap size detection function, validation logic, and error messagesGROWI_OPTIMIZE_MEMORY to V8_OPTIMIZE_FOR_SIZE in the node flag assembly functionGROWI_LITE_MODE to V8_LITE_MODE in the node flag assembly function[x] 9.2 (P) Update all environment variable references in entrypoint unit tests
GROWI_HEAP_SIZE references with V8_MAX_HEAP_SIZEGROWI_OPTIMIZE_MEMORY with V8_OPTIMIZE_FOR_SIZE and GROWI_LITE_MODE with V8_LITE_MODE[x] 10. Add V8 memory management environment variable documentation to README
V8_MAX_HEAP_SIZE, V8_OPTIMIZE_FOR_SIZE, V8_LITE_MODE