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.
The Recommended Pattern
Use:
- an
emptyDirvolume for shared storage - an init container that runs
git clone - '
subPathon the main container mount to expose only the target folder'
Here is a complete example:
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:
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:
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
gitRepoinstead of the init-container pattern. - Forgetting that
subPathonly 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
gitRepovolume type is not the right modern solution for this problem. - Use an init container to clone the repository into an
emptyDir. - Use
subPathon 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.

