Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 1, 2025

Adds a chezmoi toolbox for managing dotfiles via container image.

Changes

  • base/Dockerfile: Added git to base image

    • Git is now available to all toolbox images extending the base
    • Eliminates duplication across derived images
  • chezmoi/Dockerfile: New image extending base toolbox

    • Installs chezmoi v2.56.1 via mise (aqua:twpayne/chezmoi)
    • Sets zsh as default command for easy container startup
    • Accepts optional CHEZMOI_REPO build arg to initialize dotfiles during build
    • Supports SSH key mounting for private repositories using RUN --mount=type=ssh
    • Dynamically detects Git host from SSH URLs (GitHub, GitLab, Bitbucket, self-hosted, etc.)
    • Includes security warning about code execution from dotfiles repos
  • devcontainer/Dockerfile: Simplified to remove git installation

    • Now inherits git from base image
  • .github/workflows/build-chezmoi-image.yml: CI/CD pipeline following devcontainer pattern

    • Triggers on chezmoi directory changes and after base image updates
    • Publishes to ghcr.io/jhulten/toolbox/chezmoi
  • README.md: Documents available toolboxes and usage

    • Updated base image description to include git
    • Updated devcontainer description to remove redundant git mention
    • Added security warning for CHEZMOI_REPO usage
    • Simplified container run command (zsh is now default)
    • Added examples for all authentication methods (HTTPS, token, SSH)

Usage

# Build without repo initialization
docker build -t my-chezmoi ./chezmoi

# Build with public dotfiles repo
docker build --build-arg CHEZMOI_REPO=https://github.com/username/dotfiles.git -t my-chezmoi ./chezmoi

# Build with private repo using SSH keys (GitHub)
docker buildx build --ssh default --build-arg [email protected]:username/dotfiles.git -t my-chezmoi ./chezmoi

# Build with private repo using SSH keys (GitLab or other Git hosts)
docker buildx build --ssh default --build-arg [email protected]:username/dotfiles.git -t my-chezmoi ./chezmoi

# Build with private repo using token
docker build --build-arg CHEZMOI_REPO=https://[email protected]/username/dotfiles.git -t my-chezmoi ./chezmoi

# Run the container (zsh starts by default)
docker run -it my-chezmoi

Warning

Using CHEZMOI_REPO will execute code from the dotfiles repository during the build process. Only use with trusted repositories.

Private Repository Access

For private dotfiles repositories, you can pass credentials via:

  • Token in URL: --build-arg CHEZMOI_REPO=https://[email protected]/user/dotfiles.git
  • SSH keys: Use Docker buildx --ssh default flag with SSH URL format (git@host:user/repo.git)
    • Automatically detects Git host from SSH URL
    • Works with any Git hosting service (GitHub, GitLab, Bitbucket, self-hosted)
    • Only configures SSH when using SSH-based URLs (not for HTTPS)
  • Manual init: Skip build-time initialization and run chezmoi init after starting the container with mounted credentials
Original prompt

Create a chezmoi image based on the base toolbox that installs chezmoi and fetches a repo provided in an argument to install.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add chezmoi image using base toolbox Add chezmoi toolbox image with optional dotfiles initialization Dec 1, 2025
Copilot AI requested a review from jhulten December 1, 2025 19:20
Copy link
Owner

@jhulten jhulten left a comment

Choose a reason for hiding this comment

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

Isnt git part of the base image? If not, add it there instead of in chezmoi image.

Copy link
Contributor Author

Copilot AI commented Dec 1, 2025

Isnt git part of the base image? If not, add it there instead of in chezmoi image.

You're right - git wasn't in the base image but was being duplicated in both devcontainer and chezmoi. I've moved it to the base image in commit 8c68db7, which also cleaned up the devcontainer Dockerfile by removing the duplicate git installation.

Copilot AI requested a review from jhulten December 1, 2025 19:35
@jhulten jhulten marked this pull request as ready for review December 1, 2025 19:52
Copilot AI review requested due to automatic review settings December 1, 2025 19:52
Copy link
Contributor

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 a new chezmoi toolbox image for managing dotfiles via containers. The changes refactor git installation to the base image, eliminating duplication across derived images, and introduce a new chezmoi image with optional dotfiles initialization during build time.

Key changes:

  • Consolidates git installation into the base image, removing duplication from devcontainer
  • Adds new chezmoi toolbox with version-pinned installation and optional CHEZMOI_REPO build argument
  • Implements CI/CD workflow following the established devcontainer pattern with base image dependency triggers

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
base/Dockerfile Adds git package to base image for reuse across all derived toolboxes
devcontainer/Dockerfile Removes redundant git installation now inherited from base
chezmoi/Dockerfile New toolbox image with chezmoi v2.56.1 and optional dotfiles repo initialization
.github/workflows/build-chezmoi-image.yml CI/CD pipeline for building and publishing chezmoi image with base image dependency handling
README.md Documents the new chezmoi toolbox with usage examples and security warnings
Comments suppressed due to low confidence (1)

chezmoi/Dockerfile:15

  • The chezmoi installation uses curl -fsLS without verifying the downloaded script's integrity (e.g., checksum or signature). Consider adding verification or using a pinned version with checksum validation for better security.
RUN sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}

build-args: |
BASE_IMAGE_TAG=${{ steps.base-tag.outputs.tag }}
cache-from: type=gha
cache-to: type=gha,mode=max
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

Missing trailing newline at end of file. According to POSIX standard and common best practices, text files should end with a newline character.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 679a0c4.

README.md Outdated
Base toolbox image with common dependencies (ca-certificates, curl, git, zsh, mise).

### Devcontainer
Development container image with git, SSH, GPG, and locale support.
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The description mentions "git" as available in the base image, but the Devcontainer description also lists "git" as one of its features. Since git is now inherited from the base image, this creates redundancy. Consider updating the description to focus on what Devcontainer adds beyond the base: "Development container image with SSH, GPG, and locale support."

Suggested change
Development container image with git, SSH, GPG, and locale support.
Development container image with SSH, GPG, and locale support.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 679a0c4.


# Install chezmoi using the official installation script
ARG CHEZMOI_VERSION=2.56.1
RUN sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}
Copy link

Copilot AI Dec 1, 2025

Choose a reason for hiding this comment

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

The install command uses curl get.chezmoi.io without an explicit scheme, which defaults to HTTP. Piping unverified HTTP content directly to sh enables a network attacker (e.g., MITM) to inject and execute arbitrary code during the image build. Fix by explicitly using https://get.chezmoi.io and adding integrity checks (e.g., download a specific release asset over https and verify its checksum/signature), for example:

RUN sh -c "$(curl -fsLS --proto '=https' https://get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}
Suggested change
RUN sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}
RUN sh -c "$(curl -fsLS --proto '=https' https://get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}

Copilot uses AI. Check for mistakes.
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of using the curl endpoint, please install chezmoi with mise (aqua:twpayne/chezmoi).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commits 679a0c4 and f716f20. Now using mise use --global aqua:twpayne/chezmoi@${CHEZMOI_VERSION} as the toolsmith user.

`... || exit 1` is redundant

Co-authored-by: Copilot <[email protected]>

# Install chezmoi using the official installation script
ARG CHEZMOI_VERSION=2.56.1
RUN sh -c "$(curl -fsLS get.chezmoi.io)" -- -b /usr/local/bin -t v${CHEZMOI_VERSION}
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of using the curl endpoint, please install chezmoi with mise (aqua:twpayne/chezmoi).

README.md Outdated
Run the container:
```bash
docker run -it my-chezmoi zsh
Copy link
Owner

Choose a reason for hiding this comment

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

Make zsh the default command for a run or start

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 679a0c4 by adding CMD ["/bin/zsh"] to the Dockerfile.

# Optional: Initialize chezmoi with a dotfiles repo
# WARNING: This will execute code from the dotfiles repository during build.
# Only use with trusted repositories.
ARG CHEZMOI_REPO=""
Copy link
Owner

Choose a reason for hiding this comment

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

How would we pass credentials to chezmoi to get dotfiles from a private repo?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For private repos, credentials can be passed by:

  1. Using --build-arg CHEZMOI_REPO=https://[email protected]/user/dotfiles.git with a GitHub personal access token
  2. Mounting SSH keys at build time with --ssh in Docker buildx (requires modifying the Dockerfile to use RUN --mount=type=ssh)
  3. Or, skip initialization during build and run chezmoi init manually after starting the container with mounted credentials

The current implementation supports option 1. Options 2-3 would require additional Dockerfile modifications if you'd like me to add them.

Copy link
Contributor Author

Copilot AI commented Dec 1, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/BurntSushi/ripgrep/releases
    • Triggering command: /usr/bin/mise mise use --global aqua:BurntSushi/ripgrep@latest (http block)
  • https://api.github.com/repos/BurntSushi/ripgrep/releases/tags/latest
    • Triggering command: /usr/bin/mise mise use --global aqua:BurntSushi/ripgrep@latest (http block)
  • https://api.github.com/repos/BurntSushi/ripgrep/releases/tags/vlatest
    • Triggering command: /usr/bin/mise mise use --global aqua:BurntSushi/ripgrep@latest (http block)
  • https://api.github.com/repos/twpayne/chezmoi/releases
    • Triggering command: /usr/bin/mise mise ls-remote aqua:twpayne/chezmoi (http block)
    • Triggering command: /usr/bin/mise mise install aqua:twpayne/[email protected] (http block)
  • https://api.github.com/repos/twpayne/chezmoi/releases/tags/2.56.1
    • Triggering command: /usr/bin/mise mise install aqua:twpayne/[email protected] (http block)
  • https://api.github.com/repos/twpayne/chezmoi/releases/tags/v2.56.1
    • Triggering command: /usr/bin/mise mise install aqua:twpayne/[email protected] (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from jhulten December 1, 2025 20:14
@jhulten
Copy link
Owner

jhulten commented Dec 1, 2025

@copilot Lets see option 2

Copy link
Contributor Author

Copilot AI commented Dec 1, 2025

@copilot Lets see option 2

Implemented in commits f8ca570 and dcfd2b3. The Dockerfile now supports SSH key mounting with:

  • RUN --mount=type=ssh to mount SSH keys during build
  • Dynamic Git host detection from SSH URLs (works with GitHub, GitLab, Bitbucket, self-hosted, etc.)
  • Smart SSH configuration only when using SSH-based repositories (not for HTTPS)

Usage: docker buildx build --ssh default --build-arg [email protected]:username/dotfiles.git -t my-chezmoi ./chezmoi

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.

2 participants