Table of Contents
- Overview
- Quickstart
- Minimal working example (Debian slim)
- Step-by-step: Use Git for your host repo inside the container
- Distro install quick reference
- Configure identity (inside the container)
- Non-root setup (recommended)
- Using SSH agent safely (runtime)
- Keep Git out of production images (multi-stage)
- Pitfalls and how to avoid them
- Performance notes
- Tiny FAQ
Overview
This guide shows practical ways to install and use Git inside Docker containers. You’ll get a minimal working example, distro-specific install commands, secure configuration, non-root usage, and performance tips.
Quickstart
- Choose a base image (Debian/Ubuntu or Alpine are common).
- Install Git with the distro’s package manager.
- Use volumes to reuse your host repo and Git config.
- Avoid baking credentials into images.
Minimal working example (Debian slim)
This Dockerfile installs Git, initializes a sample repo during build, and prints the latest commit at runtime.
# syntax=docker/dockerfile:1
FROM debian:stable-slim
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /opt/demo
# Create a tiny repo for demonstration
RUN git init . \
&& git config user.email "[email protected]" \
&& git config user.name "CI" \
&& echo "hello" > README.md \
&& git add README.md \
&& git commit -m "init"
# Show Git version and the latest commit
CMD ["sh", "-c", "git --version && git -C /opt/demo log --oneline -n1"]
Build and run:
docker build -t git-in-docker .
docker run --rm git-in-docker
Interact with the sample repository:
docker run --rm git-in-docker sh -c "cd /opt/demo && git status"
Step-by-step: Use Git for your host repo inside the container
- Build an image with Git installed (see Dockerfile above).
- Mount your host repo into the container and run Git against it:
docker run --rm -it \ -v "$PWD":/work \ -w /work \ git-in-docker git status - Reuse your host Git config and (optionally) SSH keys:
- As root (default):
docker run --rm -it \ -v "$PWD":/work -w /work \ -v "$HOME/.gitconfig":/root/.gitconfig:ro \ -v "$HOME/.ssh":/root/.ssh:ro \ git-in-docker sh -c "git config --list && git status" - If you use a non-root user, mount to that user’s home instead (see Non-root section).
- As root (default):
Distro install quick reference
| Base image | Install Git |
|---|---|
| Debian/Ubuntu | apt-get update && apt-get install -y --no-install-recommends git ca-certificates |
| Alpine | apk add --no-cache git ca-certificates |
| RHEL/CentOS/Fedora | dnf install -y git ca-certificates (or yum install -y git ca-certificates) |
Notes:
- Keep ca-certificates to avoid TLS errors.
- Clean package caches (apt lists) to shrink layers.
Configure identity (inside the container)
Set your identity so commits succeed:
# Local to a repository (recommended inside containers)
cd /work
git config user.name "Your Name"
git config user.email "[email protected]"
For a global config, mount your host .gitconfig or supply one:
# /root/.gitconfig or /home/gituser/.gitconfig
[user]
name = Your Name
email = [email protected]
[core]
editor = vi
Tip: To force a specific global config path, set GIT_CONFIG_GLOBAL=/etc/gitconfig and mount a file there.
Non-root setup (recommended)
Running Git as a non-root user prevents permission issues with mounted volumes.
FROM debian:stable-slim
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Create an unprivileged user
RUN useradd -m -u 10001 gituser
USER gituser
WORKDIR /home/gituser/work
Run with mounted config and SSH for that user:
docker run --rm -it \
-v "$PWD":/home/gituser/work \
-v "$HOME/.gitconfig":/home/gituser/.gitconfig:ro \
-v "$HOME/.ssh":/home/gituser/.ssh:ro \
your-image sh
Using SSH agent safely (runtime)
Forward your host SSH agent instead of copying private keys:
# Ensure an SSH agent is running on the host
# Forward it into the container
docker run --rm -it \
-v "$PWD":/work -w /work \
-v "$SSH_AUTH_SOCK":/ssh-agent \
-e SSH_AUTH_SOCK=/ssh-agent \
git-in-docker sh -c "ssh-add -l && git fetch --all || true"
This avoids storing keys in the image. Ensure openssh-client is installed if you need SSH operations.
Keep Git out of production images (multi-stage)
Use a builder stage that has Git, then copy only the source into a slim final image.
# syntax=docker/dockerfile:1
FROM alpine:3 AS builder
RUN apk add --no-cache git
WORKDIR /src
RUN git init . && echo "app" > app.txt && git add app.txt && git commit -m "seed"
FROM alpine:3
WORKDIR /app
COPY --from=builder /src .
# No Git here; final image stays small
CMD ["sh", "-c", "ls -la"]
Pitfalls and how to avoid them
- Credentials in layers: Never RUN git clone with embedded tokens. Use runtime mounts or BuildKit secrets/SSH forwarding.
- Ownership mismatches: Mounted files may be owned by your host UID. Use a matching UID in the container or chown the workdir; set safe.directory if needed:
git config --global --add safe.directory /work - Missing CA certs or proxies: Install ca-certificates and configure http(s).proxy env vars if corporate proxies are in use.
- Line endings: Containers often default to LF. Set core.autocrlf appropriately when collaborating with Windows hosts.
- Timezone/clock skew: If GPG signing or strict timestamps matter, ensure correct time syncing.
Performance notes
- Shallow and partial clones: Use --depth 1 or --filter=blob:none to reduce network and disk I/O.
- Avoid installing recommends: Saves space and time (apt --no-install-recommends, apk --no-cache).
- Clean caches: Remove apt lists and temporary files in the same layer as install commands.
- Multi-stage builds: Keep Git only in builder stages.
- Volume mounts over bind: Use local volume drivers on remote Docker hosts to reduce latency when appropriate.
Tiny FAQ
- Can I install Git in scratch? No. Use a base with a package manager (Alpine or Debian) or copy a static Git binary you trust.
- How do I persist my Git config? Mount your host .gitconfig or supply a file at /etc/gitconfig, /root/.gitconfig, or the non-root user’s home.
- I see “detected dubious ownership” on mounted repos. Set a safe.directory for the mount path or match the container user’s UID to the host.
- How do I use private repos? Forward your SSH agent or mount SSH keys read-only; avoid putting secrets in Dockerfiles or image layers.