Skip to content

Fix: make Dockerfile self-contained with multi-stage build#24277

Open
Famous077 wants to merge 2 commits intogoogle-gemini:mainfrom
Famous077:fix/self-contained-dockerfile
Open

Fix: make Dockerfile self-contained with multi-stage build#24277
Famous077 wants to merge 2 commits intogoogle-gemini:mainfrom
Famous077:fix/self-contained-dockerfile

Conversation

@Famous077
Copy link
Copy Markdown
Contributor

Summary

Fixes Dockerfile to work on a clean git clone without requiring host pre-built artifacts.

Details

The Dockerfile used COPY packages/cli/dist/*.tgz which failed if the user hadn't
run npm run build locally first. Converted to a multi-stage build so everything
compiles inside the container.

Stage 1 (builder): installs git, runs npm install + npm run build + npm pack
Stage 2 (runtime): copies .tgz artifacts from builder via --from=builder

Added HUSKY=0 to skip git hooks during container build.

Related Issues

Fixes #15859

How to Validate

  1. Fresh clone the repo (no local build)
  2. Run: docker build --build-arg CLI_VERSION_ARG=1.0.0 -t gemini .
  3. Run: docker run --rm gemini --version
  4. Expected: builds successfully and prints 1.0.0

Before this fix, step 2 fails with:
ERROR: lstat /packages/cli/dist: no such file or directory

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • Docker
    • Windows
      • Docker
    • Linux
      • Docker ✅ (validated in GitHub Codespaces)

@Famous077 Famous077 requested a review from a team as a code owner March 30, 2026 21:39
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the Dockerfile to support a self-contained build process. By transitioning to a multi-stage build, the container now compiles the necessary packages internally, ensuring that users can build the image from a fresh repository clone without needing to perform local builds beforehand. This improves the developer experience and ensures consistent build environments.

Highlights

  • Multi-stage Docker build: Implemented a multi-stage Dockerfile to handle the build process entirely within the container, removing the dependency on pre-built artifacts from the host machine.
  • Build environment configuration: Added necessary build dependencies like git and configured the builder stage to install dependencies, run builds, and package the CLI and core modules.
  • Build optimization: Disabled Husky git hooks during the container build process to streamline execution and ensure compatibility.
  • Entrypoint update: Updated the container entrypoint to use the absolute path of the installed binary.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Famous077 Famous077 changed the title fix: make Dockerfile self-contained with multi-stage build Fix: make Dockerfile self-contained with multi-stage build Mar 30, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a multi-stage Docker build to compile and package the Gemini CLI within the container, eliminating the need for host-side pre-building. Feedback focuses on optimizing the Dockerfile for better caching and smaller image sizes, specifically by managing dependency files more efficiently and excluding the .git directory. Other recommendations include using npm ci for consistent builds, combining npm install commands to resolve package dependencies correctly, and reverting the change from CMD to ENTRYPOINT to preserve user flexibility.


# Copy ALL source files needed for build
COPY package*.json ./
COPY packages/ ./packages/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Copying the entire packages/ directory before npm install invalidates the Docker layer cache for dependencies whenever any source file changes. This significantly slows down subsequent builds. To optimize caching, copy only the package.json files for all workspaces first, run npm install (or npm ci), and then copy the rest of the source code.

Dockerfile Outdated
COPY eslint.config.js ./
COPY scripts/ ./scripts/
COPY esbuild.config.js ./
COPY .git/ ./.git/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Copying the .git directory into the Docker build context and image layers is discouraged as it can be very large, increasing build times and image size. Since the generate-git-commit-info.js script only needs the commit hash, consider passing the hash as a build argument (ARG GIT_COMMIT) and using it to generate the version info, rather than including the entire git history.

Dockerfile Outdated
COPY .git/ ./.git/

# Skip husky (no need in Docker), install deps and build
RUN HUSKY=0 npm install && \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Use npm ci instead of npm install for cleaner, faster, and more reliable builds in CI/Docker environments. npm ci ensures that the package-lock.json is strictly followed and avoids unnecessary updates to the lockfile during the build process.

RUN HUSKY=0 npm ci && \


# Copy built artifacts from builder stage (no host pre-build needed!)
COPY --from=builder /build/packages/cli/dist/google-gemini-cli-*.tgz /tmp/gemini-cli.tgz
COPY --from=builder /build/packages/core/dist/google-gemini-cli-core-*.tgz /tmp/gemini-core.tgz
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

When installing local tarballs that have inter-dependencies (e.g., @google/gemini-cli depending on @google/gemini-cli-core), it is critical to install them in a single npm install -g command (e.g., npm install -g /tmp/gemini-core.tgz /tmp/gemini-cli.tgz). This allows npm to correctly resolve the workspace dependencies from the provided tarballs. Installing them in separate RUN steps or separate commands will likely fail if the packages are not available in a public registry.


# default entrypoint when none specified
CMD ["gemini"]
ENTRYPOINT ["/usr/local/share/npm-global/bin/gemini"] No newline at end of file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Changing the default command from CMD to ENTRYPOINT is a breaking change that prevents users from easily overriding the command (e.g., to run a shell like bash). Additionally, using an absolute path is redundant as the binary is already in the PATH. It is recommended to revert to CMD ["gemini"] to maintain compatibility with existing workflows.

CMD ["gemini"]

@gemini-cli gemini-cli bot added priority/p2 Important but can be addressed in a future release. area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! labels Mar 30, 2026
@Famous077
Copy link
Copy Markdown
Contributor Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the Dockerfile into a multi-stage build process, which improves layer caching and allows the entire build and packaging workflow to occur within the container. Feedback indicates that the GIT_COMMIT build argument is currently ineffective because the underlying build script does not check the environment variable and fails to retrieve git information since the .git directory is not present in the builder stage.

Comment on lines +33 to +34
ARG GIT_COMMIT=unknown
ENV GIT_COMMIT=$GIT_COMMIT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The GIT_COMMIT build argument and environment variable are defined here, but the build process (specifically scripts/generate-git-commit-info.js called during npm run build) does not currently utilize this environment variable. The script attempts to run git rev-parse, which will fail inside the container since the .git directory is not copied. This results in the version metadata being set to 'N/A' regardless of the provided build argument. To fix this, the scripts/generate-git-commit-info.js file should be updated to check process.env.GIT_COMMIT before falling back to the git command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/platform Issues related to Build infra, Release mgmt, Testing, Eval infra, Capacity, Quota mgmt help wanted We will accept PRs from all issues marked as "help wanted". Thanks for your support! priority/p2 Important but can be addressed in a future release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to build it with Dockerfile

1 participant