3

I am writing a Dockerfile for my project like

RUN git clone https://github.com/CNA/contract.git --depth 1 --branch 20.0 /opt/CNA-contract

I would like to freeze the code at a particular commit. What is the best practice to do something like this in Docker? I see it fairly easy in buildouts something like

git clone https://github.com/CNA/contract.git --depth 1 --branch 20.0 /opt/CNA-contract commit-SHA
  • Note that if you can set a *tag* in the source repository, `--depth 1 --branch ` does the trick regardless of how old your Git is. You'll get a detached-HEAD clone, but that should be fine. – torek Dec 20 '21 at 02:50
  • Thanks but this can’t be done with repos you don’t own right? – BrIndSofts Brazil Dec 20 '21 at 08:31
  • @BrIndSoftsBrazil Yes, [my answer](https://stackoverflow.com/a/70415877/6309) below can be done with (public) repository you do not own. – VonC Dec 20 '21 at 08:33
  • Right. It's just a note that *if* you can do X (create tag) you can get Y (the effect you want, "free"). If you *can't* do X ... see VonC's answer :-) (and also David Maze's, which as he notes has its own advantages) – torek Dec 20 '21 at 08:49

2 Answers2

2

It would better to add a few steps in your RUN, as described in "How to shallow clone a specific commit with depth 1?", assuming a recent version of Git 2.24 or mroe:

RUN \
mkdir repo && \
cd repo && \
git init . && \
git remote add origin <url> && \\
git fetch --depth 1 origin <sha1> && \\ 
git checkout FETCH_HEAD

That way, you only fetch the commit you need.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
0

If you don't run git clone in your Dockerfile but rather on the host, then you can check out and build whatever commit you want.

# on the host, not in a Dockerfile
git clone https://github.com/CNA/contract.git
cd contract
git checkout 20.0
docker build -t cna/contract:20.0 .
git checkout main
docker build -t cna/contract:$(git rev-parse --short HEAD)

This approach also avoids some dangerous problems around getting appropriate credentials to run the git clone command (that repository isn't public; can you use docker run to get a private key back out of the image?), it supports building things that aren't actually committed to source control, and it avoids some problems with Docker layer caching where Docker won't repeat a git clone command even if the repository has changed.

David Maze
  • 130,717
  • 29
  • 175
  • 215