Skip to content

Conversation

@jhassine
Copy link
Contributor

@jhassine jhassine commented Aug 12, 2025

User description

See more:

  • Now it is possible to use this as base image even if missing pyproject.toml, uv.lock and .python-version files.
  • set VIRTUAL_ENV env var in the hopes that some tooling find the right Python

PR Type

Enhancement


Description

  • Add SSH support for git+ssh pip packages

  • Enable usage without required project files

  • Set VIRTUAL_ENV environment variable

  • Improve Docker build flexibility


Diagram Walkthrough

flowchart LR
  A["Docker Build"] --> B["SSH Mount"]
  B --> C["SSH Key Setup"]
  C --> D["UV Sync"]
  D --> E["Conditional Install"]
  E --> F["Cleanup Files"]
Loading

File Walkthrough

Relevant files
Enhancement
Dockerfile
Enable SSH git packages and optional files                             

Dockerfile

  • Add Docker syntax directive for advanced features
  • Enable SSH mount for git authentication
  • Make project files optional with conditional logic
  • Set VIRTUAL_ENV environment variable
  • Reorganize environment variable declarations
  • Add SSH key scanning for GitHub
  • Clean up temporary files after installation
+13/-8   

See more:
- https://docs.astral.sh/uv/concepts/authentication/#git-authentication
- https://docs.docker.com/reference/cli/docker/buildx/build/#ssh

+ Now it is possible to use this as base image even if missing pyproject.toml, uv.lock and .python-version files.
+ set `VIRTUAL_ENV` env var  in the hopes that some tooling find the right Python
@jhassine jhassine requested a review from phuongfi91 August 12, 2025 16:41
Copilot AI review requested due to automatic review settings August 12, 2025 16:41
Copy link

@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.

Summary of Changes

Hello @jhassine, 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 enhances the Dockerfile to support installing Python packages from "git+ssh" sources, which is crucial for private repository access. It achieves this by enabling Docker BuildKit's SSH mounting feature and configuring the SSH environment within the build process. Additionally, the changes improve the Docker image's reusability and flexibility by making the presence of "pyproject.toml", "uv.lock", and ".python-version" files optional for the build, and by explicitly setting the "VIRTUAL_ENV" environment variable to assist Python tooling.

Highlights

  • SSH Support for Git Packages: The Dockerfile now supports installing pip packages from Git repositories using SSH authentication, leveraging Docker BuildKit's SSH mounting capabilities.
  • Improved Image Flexibility: The Docker image is made more flexible, allowing it to be used as a base even if "pyproject.toml", "uv.lock", or ".python-version" files are missing, by conditionally running "uv sync".
  • Virtual Environment Discovery: The "VIRTUAL_ENV" environment variable is now explicitly set within the Docker image, which helps various Python tooling automatically discover and utilize the correct virtual environment.
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 in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

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 issue 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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

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.

@qodo-code-review
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 Security concerns

SSH configuration:
Writing to ~/.ssh/known_hosts without setting appropriate permissions on ~/.ssh (0700) and known_hosts (0644) can cause SSH to ignore the files. Consider chmod 700 ~/.ssh && chmod 644 ~/.ssh/known_hosts. Also, limiting known_hosts to only github.com could encourage disabling host key checking elsewhere; prefer StrictHostKeyChecking=accept-new if broader host support is needed.

⚡ Recommended focus areas for review

SSH Known Hosts Robustness

Only GitHub is added to known_hosts; git+ssh dependencies may come from other hosts. Consider parameterizing or using StrictHostKeyChecking=accept-new or adding additional hosts to avoid build failures.

mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
&& uv venv \
&& if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
    uv sync --frozen --no-install-project --no-cache; \
fi \
Cache Utilization

Previous ONBUILD used uv cache mount; new flow drops cache mounts which may slow builds. Validate whether adding a uv cache mount to ONBUILD RUN is desirable.

ONBUILD RUN --mount=type=ssh \
    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && uv venv \
    && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
        uv sync --frozen --no-install-project --no-cache; \
    fi \
    && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*
Cleanup Safety

The cleanup command removes pyproject/lock/python-version from /app; ensure this does not delete user files if image is used as a base layer expecting those files to persist for later stages.

&& if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
    uv sync --frozen --no-install-project --no-cache; \
fi \
&& rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for pip packages with git+ssh sources by enabling SSH agent forwarding in Docker builds and making the base image more flexible for projects without complete uv configuration files.

Key changes:

  • Enables SSH authentication for git repositories during package installation
  • Makes pyproject.toml, uv.lock, and .python-version files optional by copying them conditionally
  • Sets VIRTUAL_ENV environment variable for better Python tooling compatibility

uv venv \
&& uv sync --frozen --no-install-project
ONBUILD RUN --mount=type=ssh \
mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

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

Hard-coding GitHub's host keys in the Dockerfile creates a security risk. If GitHub's host keys change, builds will fail, and there's no verification of the keys being added. Consider using a more secure approach like ssh-keyscan -H github.com for hashed known_hosts or allowing users to mount their own known_hosts file.

Suggested change
mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
mkdir -p ~/.ssh && \
if [ -f /tmp/known_hosts ]; then \
cp /tmp/known_hosts ~/.ssh/known_hosts; \
else \
echo "WARNING: No known_hosts file provided, using ssh-keyscan (less secure)"; \
ssh-keyscan -H github.com >> ~/.ssh/known_hosts; \
fi \

Copilot uses AI. Check for mistakes.
mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
&& uv venv \
&& if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
uv sync --frozen --no-install-project --no-cache; \
Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

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

Using --no-cache disables uv's caching mechanism, which will make subsequent builds slower. Since this is in an ONBUILD instruction that runs for every derived image, consider removing --no-cache to allow uv to cache downloaded packages and improve build performance.

Suggested change
uv sync --frozen --no-install-project --no-cache; \
uv sync --frozen --no-install-project; \

Copilot uses AI. Check for mistakes.
&& if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
uv sync --frozen --no-install-project --no-cache; \
fi \
&& rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*
Copy link

Copilot AI Aug 12, 2025

Choose a reason for hiding this comment

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

Removing the copied configuration files at the end of the RUN instruction defeats the purpose of copying them in the ONBUILD COPY step. If these files are needed for the uv sync operation, they should remain available for potential future operations in derived images. Consider whether this cleanup is necessary or if it should be conditional.

Suggested change
&& rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

Copilot uses AI. Check for mistakes.
@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Avoid leaking SSH material

The ONBUILD step enables SSH mount and writes known_hosts into the image layer,
which can both leak build-time SSH context and create nondeterministic layers.
Use --mount=type=ssh only for the specific uv command that needs it and avoid
persisting ~/.ssh/known_hosts in the image (pipe to a temp file within the same
RUN scope or rely on StrictHostKeyChecking=no). Additionally, ensure the SSH
mount is not active for builds that don't require git+ssh to prevent unexpected
failures and supply clear failure modes.

Examples:

Dockerfile [74-80]
ONBUILD RUN --mount=type=ssh \
    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && uv venv \
    && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
        uv sync --frozen --no-install-project --no-cache; \
    fi \
    && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

Solution Walkthrough:

Before:

ONBUILD RUN --mount=type=ssh \
    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && uv venv \
    && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
        uv sync --frozen --no-install-project --no-cache; \
    fi \
    && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

After:

ONBUILD RUN --mount=type=ssh \
    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && uv venv \
    && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
        uv sync --frozen --no-install-project --no-cache; \
    fi \
    && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock* ~/.ssh
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant issue where build-time SSH artifacts (~/.ssh/known_hosts) are leaked into the final image layer, which is a security and image hygiene concern.

Medium
Security
Harden SSH setup during build

Ensure SSH agent socket is correctly forwarded and permissions are secure to
avoid "permission denied" and MITM risks. Set restrictive perms on ~/.ssh and
known_hosts, and pass SSH_AUTH_SOCK to the build. This hardens SSH usage during
git+ssh installs.

Dockerfile [74-80]

 ONBUILD RUN --mount=type=ssh \
-    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
+    mkdir -p ~/.ssh \
+    && chmod 700 ~/.ssh \
+    && ssh-keyscan -t rsa,ecdsa,ed25519 github.com >> ~/.ssh/known_hosts \
+    && chmod 600 ~/.ssh/known_hosts \
     && uv venv \
     && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
         uv sync --frozen --no-install-project --no-cache; \
     fi \
     && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a security best practice by proposing to set restrictive permissions on the ~/.ssh directory and known_hosts file, which hardens the image against potential misuse of SSH credentials within the build environment.

Medium
  • More

Copy link

@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 enhances the Docker image by adding support for installing pip packages from git+ssh sources, which is a great feature for private dependencies. It also makes the presence of pyproject.toml and uv.lock optional, increasing the image's flexibility.

My review includes two main suggestions:

  1. Making the ssh-keyscan host configurable to support git providers other than GitHub.
  2. Re-enabling the uv cache to avoid a performance regression during builds.

The changes are well-structured and address the stated goals effectively. Addressing these points will make the image even more robust and performant.

Comment on lines +74 to +80
ONBUILD RUN --mount=type=ssh \
mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
&& uv venv \
&& if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
uv sync --frozen --no-install-project --no-cache; \
fi \
&& rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

Choose a reason for hiding this comment

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

high

The uv cache mount has been removed and uv sync is now run with --no-cache. This will significantly slow down builds by preventing dependency caching. It's recommended to reintroduce the cache mount for uv and remove the --no-cache flag to leverage Docker's build cache for faster dependency installation on subsequent builds.

ONBUILD RUN --mount=type=ssh --mount=type=cache,target=/root/.cache/uv \
    mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \
    && uv venv \
    && if [ -f "pyproject.toml" ] && [ -f "uv.lock" ]; then \
        uv sync --frozen --no-install-project; \
    fi \
    && rm -rf /app/.python-version* /app/pyproject.toml* /app/uv.lock*

uv venv \
&& uv sync --frozen --no-install-project
ONBUILD RUN --mount=type=ssh \
mkdir -p ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts \

Choose a reason for hiding this comment

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

medium

Hardcoding github.com in ssh-keyscan limits this feature to GitHub-hosted repositories. To make this image more versatile for git+ssh dependencies from other providers (e.g., GitLab, Bitbucket, or private servers), consider allowing the host(s) to be configurable via a build argument.

For example:

ARG GIT_SSH_HOSTS="github.com"
...
ONBUILD RUN --mount=type=ssh \
    mkdir -p ~/.ssh && for host in $GIT_SSH_HOSTS; do ssh-keyscan "$host" >> ~/.ssh/known_hosts; done \
    ...

Copy link
Contributor

@phuongfi91 phuongfi91 left a comment

Choose a reason for hiding this comment

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

🚀

@phuongfi91 phuongfi91 merged commit 3e6f017 into latest Aug 13, 2025
12 checks passed
@phuongfi91 phuongfi91 deleted the gitssh branch August 13, 2025 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants