-
Notifications
You must be signed in to change notification settings - Fork 8
Developer Notes
Mostly this container was adapted from the conda-forge linux-anvil container https://github.com/conda-forge/docker-images
TL;DR: Make new changes at the bottom of the Dockerfile to keep the result small.
Docker images are built from Dockerfile
's. You can find ours, along with support scripts
in docker/
after cloning this repository. The Dockerfile is a recipe for building this
container. If you want to produce a new container or make a change, you'll need to alter
the Dockerfile.
I hope the Dockerfile is self-documenting with its comments, but here's a summary.
FermiBottle is built in a Centos 6 container, with the stage name 'builder'. The Yum package manager is used to update the build toolchain. Next, scripts are called to install ftools, ScienceTools, tempo(s) etc. This builder container has outlived its usefulness, so a newer, younger container is spun up and the binaries from builder are copied into it. The entrypoint script is copied and set as the docker entrypoint after being passed through tini, the tini-est init process. A volume point is mounted to '/data' and a default command is set to launch a bash shell.
Entrypoint will create the fermi user, set permissions and make symbolic links for the build products. It will pass input prompts through 'pysu' to provide a colorful, functional terminal experience for the fermi user that will properly handle keyboard interrupts and kernal signals.
Docker images and containers are built out of sets of layers. A layer is like a snapshot of a filesystem or directory structure. When you create a container from an image, docker takes all the layers of that image and merges them into the new container's file system, then adds a new layer on top. The lower layers are read only, and all changes that the user makes goes into the topmost layer. This is how docker maintains encapsulation. When the Dockerfile issues and of the uppercase commands, like RUN
, a new layer is created for our image. The builder makes a bunch of layers, while the production container copies some of the content out into its own separate set of layers. Docker push
and Docker pull
know that if only 1 of the 7 layers in an image has changed, it only needs to pull that one layer. This is the critical component in Docker's smart caching.
FermiBottle is huge, so the fact that docker has a smart caching feature is a big help to us. If you run docker image build once from scratch it will go through the whole long process of building every tool in our suite from source. If you try to build it right away however Docker will intelligently realize you've already built parts of it and it won't change a thing. Hurray! Now if you change a part of the Dockerfile Docker will try to only rebuild the things IT THINKS have changed, or will be affected by the change.
Essentially that means if you alter a line or run commnad in the Dockerfile, docker will build that line, and rebuild every line after it, but not the ones before it. For that reason it is smart to try putting any small changes that simply append to what's already there at the end of the Dockerfile. The way we broke this up that means it will be in the product container, not the builder container.
If you just append, docker will simply add a new layer to the set that makes up this image. If you docker push
this to dockerhub, it should say a bunch of the earlier layer's already exist and make a single new layer with the change. This should be a smart way to distribute patches and fixes to the students.
git clone https://github.com/fermi-lat/FermiBottle.git
cd FermiBottle/docker
docker image build -t fssc/fermibottle .
- Save a built image
docker save fermibottle -o fermibottle.tar
- Compress it with zip, to be nice to windows:
zip fermibottle.tar
- Log in to dockerhub
docker login
- Push to dockerhub
docker push fssc/fermibottle
I'm a Fermi in a bottle, baby. Gotta docker run
me the right way.