Note The version of crane described below is a modified one. Find it on my github fork.
If you’re custom to working with
github that you’ll recognize the following flow:
- You fork a repo (e.g.
user/foo)
- You commit and push code to your fork (e.g.
bivas/foo)
- You create a pull request (PR) to merge your changes with original repo.
This approach is usually referred to as
upstream remote and branching model is taken from
git flow.
The docker flow problem
When working with
docker, you pull and push images to a registry. Usually, when using your own registry, your push, pull, tag, build cycle might get messy.
- You pull
company/foo from registry.company.co
- The pulled imaged is now locally tagged as
registry.company.co/company/foo
- You write a
Dockerfile to build a dependent image:
a. Start with FROM company/foo ?
b. Start with FROM registry.company.co/company/foo?
- So you decide to
tag the pulled image as company/foo Remember: You can’t use ARG in FROM directive, so your registry prefix is there for good (or until refactored)
- Completed your local tests and you wish to
push. Again, your tag your image and push it as registry.company.co/company/foo
Why can’t we simply do - pull, build, and push? Let someone else deal with the registry and tagging.
The crane flow
So we have our registry at
registry.company.co, our images are prefixed as
company and all our
Dockerfiles begin with something like
company/foo. We extended
crane to support our flow of
pull (from official registry),
build (locally on developer workspace, and
push (to a user registry for backup). The entire flow keeps the original image name as
company/foo but knows when to change tags to support other flows.
Here’s an example
crane.yaml file:
containers:
os:
image: company/os
build:
context: os/
pull:
registry: ${DOCKER_REGISTRY}
etcd:
image: coreos/etcd:2
push:
skip: true
service:
image: company/service
build:
context: service/
pull:
registry: registry.company.co
push:
registry: registry.${USER}.company.co
override_user: ${USER}
The added directives:
pull.registry = which registry to pullfrom
crane will pull from registry.company.co/company/foo and locally tag it as company/foo
pull.override_user = which user to pull as
crane will pull the specified image as ${USER}/foo and locally tag it as company/foo (useful when testing against your version of the container stack.
push.registry = which registry to push to
crane will push to registry.company.co/company/foo the image locally tagged as company/foo
push.override_user= which user to push as
crane will push the specified image as ${USER}/foo the image locally tagged as company/foo (useful to backup your images in registry)
push.skip = skip the image when attempting push (useful when dealing with community images)
Now, a developer can easily work with
FROM company/foo directive without dealing with re-tag. She can also modify
company/foo and keep a backups without the need to re-tag the entire images stack.
We have a github-like development cycle of “forking” (
pull) the official registry,
pushing images to your private registry for development and backup (
push). Once the developer is satisfied with the modifications - she creates a
normal pull request to the modified
Dockerfile.