0

I have a Git repo with a simple Dockerfile. First row goes like this:

FROM python:3.7

My company has an internal registry with the base images. Because of this, the DevOps guys want me to change the Dockerfile to:

FROM registry.company.com:5000/python:3.7

I don't want this infrastructure detail baked in my code. URLs may change, I may want to build this image in another environment, etc. If possible, I would rather indicate the server in the pipeline, but the documentation regarding docker build has no parameter for this.

Is there a way to avoid editing the Dockerfile in this situation?

  • Does this answer your question? [How to change the default docker registry from docker.io to my private registry?](https://stackoverflow.com/questions/33054369/how-to-change-the-default-docker-registry-from-docker-io-to-my-private-registry) – jonrsharpe May 01 '21 at 14:56
  • 1
    @jonrsharpe Nope. That question is about docker pull. I want to do this during image building. – guest22654018 May 01 '21 at 15:03
  • These appear to be different questions, one asking for how to change the default for `docker pull` commands, and the other asking for how to adjust the registry used for the their builds without hardcoding it into the Dockerfile. – BMitch May 01 '21 at 15:03
  • @jonrsharpe Actually that question is closer to mine than I initially thought. From the answers in there, I learned that the default registry is fixed **by design** to comply with Docker's philosophy of making sure everybody knows which image is gonna be pulled if no registry is specified. – guest22654018 May 01 '21 at 16:51

2 Answers2

1

You would use a build arg for this:

ARG registry=docker.io/library
FROM ${registry}/python:3.7

Then for the build process:

docker build --build-arg registry=registry.company.com:5000 ...

Use docker.io for the registry name for the default Docker Hub, and library is the repository for official docker images, both of which you normally don't see when using the short format. Note that I usually include the library part in the local mirror so that official docker images and other repos that are mirrored can all use the same registry variable:

ARG registry=docker.io
FROM ${registry}/library/python:3.7

That means your local registry would need to have registry.company.com:5000/library/python:3.7.

To force users to specify the registry as part of the build, then don't provide a default value to the arg (or you could default the value of registry to something internal if that's preferred):

ARG registry
FROM ${registry}/python:3.7
BMitch
  • 231,797
  • 42
  • 475
  • 450
  • I see. No other alternatives? This way I would still have the dependence with docker.io (more stable, but still a dependence). It also looks non-standard. I really want my Dockerfile to look like a regular one. – guest22654018 May 01 '21 at 14:54
  • @guest22654018 if everything is internal, then default to a local registry server, or don't default and require everyone building to specify a registry to get the build to work. I tend to default to a public image to avoid private data being included in my Dockerfile and keep it usable by anyone. – BMitch May 01 '21 at 14:56
  • Well, that would end up baking in the server URL on my code, which is precisely what I want to avoid. – guest22654018 May 01 '21 at 15:07
  • @guest22654018 so don't provide a default. Pick one, either include a server so people can easily build, or don't and require the server to be specified on each build. You can't have both, but you can have either option. – BMitch May 01 '21 at 15:14
  • This solution has also the advantage of making the use of non-official registries explicit, which now I understand is the way Docker's maintainers want. – guest22654018 May 02 '21 at 12:39
  • minor nitpick: maybe you should name the variable in the first example as "repository" or "repo" to make clear that a full URL to a repository (not to a registry) is needed. – guest22654018 May 02 '21 at 12:45
  • @guest22654018 I typically use the second example, where it is just a registry, or at least the prefix to a mirror of a registry. Means my CI sets the variable to one value that can be set globally, instead of tracking a different value per build, or even multiple values in a single multi stage build. – BMitch May 02 '21 at 13:24
0

You can work around the situation by manually pulling and re-tagging the image. docker build (and docker run) won't try to pull an image that already appears to be present locally, but that also means there's no verification that it actually matches what Docker Hub has. That means you can pull the image from your mirror, then docker tag it to look like a Docker Hub image:

docker pull registry.company.com:5000/python:3.7
docker tag registry.company.com:5000/python:3.7 python:3.7
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • This answer is in the spirit of what I originally wanted, but after reading [this](https://github.com/moby/moby/issues/7203) and [this](https://github.com/moby/moby/issues/11815), I now understand that Docker's maintainers want to force you to use the official registry when no one is specified for a reason, namely to make Dockerfiles consistent across different environments. – guest22654018 May 02 '21 at 12:34