There are two, totally non-compatible, ways to declare a repository on the docker hub.
The first is the “normal” approach. Give it a name and push and pull arbitrary contents to it.
The second one is the “automated build” approach.
Automate, but nope.
There are advantages to auto build.
First, it’s the only way to bind a github repository to a hub repository. When you know the number of people who ask for the sources of your image, I can tell you it’s important :)
It synchronizes your README with the displayed description.
It watches on github pushes. You can chose to watch a list of specific branches and/or tags, and it will build and tag a new image for each push. Now you save CPU time on your machine, and you build in the cloud1!
Auto-builds are more trusted, up-to-date, and a sign of quality and active maintenance2.
But there is a massive, FATA (not fatal, it would be too long :)) drawback:
docker push docteurklein/sqitch:pgsql The push refers to a repository [docteurklein/sqitch] (len: 1) Sending image list FATA Error: Status 403 trying to push repository docteurklein/sqitch: "Access denied, you don't have access to this repo"
How dare you ? It’s mine!
Indeed, docker hub won’t allow you to push to this repo anymore. Instead, you have to manually create a github tag/branch, push it, and configure your repo to react to this specific tag/branch.
Now that’s what I call automated!3
Again something docker does not allow. Well, not everywhere.
If you want dynamic Dockerfiles, you need a templating system with variable interpolation. Or bash.
A simple way to make your Dockerfile dynamic is to use
docker build -, which reads from stdin, plus bash’s
driver=Pg eval "echo \"$(<Dockerfile)\"" 2> /dev/null | docker build -
With the corresponding Dockerfile:
FROM perl:latest RUN cpan App::Sqitch RUN cpan DBD::$driver VOLUME ["/src"] WORKDIR /src ENTRYPOINT ["sqitch"]
$driver variable that will be replaced with the corresponding environment variable (
Pg in that case).
Enter the Makefile
But it also says we re-use cool tools, like Makefiles.
In fact, nothing forces you to use a Makefile, it’s just a convenient way to remember and persist looooooong commands, a thing you end up to do quite often with docker3.
Put it all together
Now we have dynamic Dockerfiles, we just need to push it to github and the hub will automatically build it and tag it for us.
It requires a small git trick, that I also put in my Makefile:
push: git checkout -b $(tag) driver=$(driver) eval "echo \"$$(<Dockerfile)\"" 2> /dev/null > Dockerfile git commit -am"auto-build $(tag)" git tag -f $(tag) `git rev-parse HEAD` git checkout - git branch -D $(tag) git push origin $(tag)
Now, just execute it like that:
driver=Pg tag=pgsql make push
And make sure you configured this tag to auto-build in your hub’s repository settings.
It seems to work, and I’m curious to have your feedback!