Kubernetes
gitRepo
volume mounts
subdirectory
DevOps

Use sub directory with kubernetes gitRepo volume mounts

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you want only one subdirectory from a Git repository inside a Kubernetes container, the old gitRepo volume type is not the pattern to build around anymore. The safer modern approach is to clone the repository in an init container, store it in an emptyDir, and mount only the needed subdirectory with subPath.

Why gitRepo Is the Wrong Starting Point

Historically, Kubernetes had a gitRepo volume source that cloned a repository into a volume automatically. The problem is that it has long been discouraged and is not the path to recommend for current clusters. Even when it existed, it cloned the whole repository first, so it did not solve the "subdirectory only" problem cleanly.

What people usually want is:

  • fetch repository content before the app starts
  • expose only one folder inside the container
  • keep the manifest predictable

An init container does that more explicitly.

Use:

  • an emptyDir volume for shared storage
  • an init container that runs git clone
  • 'subPath on the main container mount to expose only the target folder'

Here is a complete example:

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: app-with-git-content
5spec:
6  initContainers:
7    - name: clone-repo
8      image: alpine/git:2.45.2
9      command:
10        - sh
11        - -c
12        - |
13          git clone --depth 1 https://github.com/example/project.git /work/repo
14      volumeMounts:
15        - name: repo-volume
16          mountPath: /work
17  containers:
18    - name: app
19      image: nginx:1.27
20      volumeMounts:
21        - name: repo-volume
22          mountPath: /usr/share/nginx/html
23          subPath: repo/site
24  volumes:
25    - name: repo-volume
26      emptyDir: {}

This works because the init container clones the repository into /work/repo, and the main container mounts only /work/repo/site into the application path.

Why subPath Helps

subPath lets one container mount a specific child path from a larger volume rather than the entire volume root. That is exactly what you want when the repository contains multiple services, configs, or documentation folders and the app needs only one of them.

Without subPath, the whole cloned repository would appear under the mount point. With subPath, you expose only the folder the container should see.

A Slightly More Robust Clone Step

If the pod depends on a specific branch or revision, make that explicit:

yaml
1command:
2  - sh
3  - -c
4  - |
5    git clone --depth 1 --branch main https://github.com/example/project.git /work/repo

Pinning the branch makes the deployment behavior easier to reason about. If you need a specific commit, check it out directly after cloning.

You can also copy only the target directory into a cleaner shared location:

yaml
1command:
2  - sh
3  - -c
4  - |
5    git clone --depth 1 https://github.com/example/project.git /tmp/repo
6    mkdir -p /work/site
7    cp -R /tmp/repo/site/. /work/site

Then the main container can mount /work/site without any nested repository path.

Operational Tradeoffs

This approach is simple, but it still has tradeoffs:

  • the clone happens on every pod start
  • the pod needs network access to the Git server
  • credentials must be handled carefully for private repositories

If the content changes infrequently, baking it into an image may be more reliable. If the content must update independently from the app image, the init-container approach is often a good compromise.

Common Pitfalls

  • Building new manifests around gitRepo instead of the init-container pattern.
  • Forgetting that subPath only controls what gets mounted, not what gets cloned.
  • Assuming this method updates automatically after the pod starts. It does not; the content is fetched at startup.
  • Omitting Git credentials for private repositories.
  • Mounting the wrong child path and then debugging the app instead of checking the cloned directory layout first.

Summary

  • The old gitRepo volume type is not the right modern solution for this problem.
  • Use an init container to clone the repository into an emptyDir.
  • Use subPath on the main container to mount only the needed subdirectory.
  • Make branch or revision selection explicit so startup behavior is predictable.
  • If startup-time cloning is undesirable, consider packaging the content into an image instead.

Course illustration
Course illustration

All Rights Reserved.