busybox-python Docker image Minimal Docker base image for aws-cli
In my last post I demonstrated how to build a minimal Docker image for the cron-container. All in all this approach works pretty well for the described use case. Following this road I wanted to use aws-cli for periodical AWS infrastructure updates. The aws
command line tool is implemented in Python which needs to be installed inside the container. I found the python base images which provides the interpreter but comes with a massive overhead. The container became kind of huge for a simple script (the python:2-slim
image has a size of approx. 200mb).
Searching around pointed me to Pyrun - a static linked Python binary of 11mb size. In combination with progrium/busybox the container becomes much smaller. Missing dependencies needed by Pyrun (Openssl, zlib, SQlite, bzip2) can be installed with the help of the opkg
.
So far so good. Sadly I realized that using curl
and aws
inside the container reveals SSL/TLS problems. I was able to tweak curl
to run without the --insecure
parameter by adding --capath
pointing to the CA certificates (those are provided by the ca-certificates
packages that can be installed with opkg
). However aws
and especially botocore Python package refused to run without the --no-verify-ssl
option (got some weird SSL error in _ssl.c:510
).
I tried hard but wasn’t able to overcome the SSL/TLS termination problems with the progrium/busybox
base image. So I started to build my own base image providing all the necessary CA certificates and libraries needed for Pyrun.
Busybox is the best approach to implement small Docker base images I know (please point me to alternatives). Building a rootfs.tar
with the help of Buildroot has been done by many people in the past and a lot of boilerplate projects exists out there. My solution is based on the tarmaker
component of the radial/busyboxplus project.
How to build a Docker base image from scratch? Lets have a look on a Dockerfile that does nothing but setup the basics:
FROM scratch
ADD rootfs.tar /
It all starts with the creation of the root filesystem. Busybox can be configured and compiled with the help of the Buildroot toolchain. Ideally this will be done as part of a container build. Here are the steps to create the filesystem as part of a docker build
command:
- Create a Ubuntu based container with
docker build
and bring it up-to-date. - Install some basic tools needed for the compilation of Busybox (wget, build-essential, libncurses-dev, rsync, unzip etc).
- Get the Buildroot archive of your choice, put it somewhere inside the container.
- Configure the build. This works very much the same as a Linux kernel build.
- Build the whole Busybox toolchain. This will create a tar archive inside the Docker container that can be used as root filesystem with Docker.
- Run the created Docker image and copy the root filesystem tar archive out of the Docker container.
Please have a look at the run.sh
script and the tarmaker Dockerfile
for further details.
The rest is a piece of cake. Here is the odise/busybox-python base image Dockerfile:
FROM scratch
ADD rootfs.tar /
# install standalone python binary
ADD pyrun2.7 /bin/python2.7
RUN ln -s /bin/python2.7 /bin/python2
RUN ln -s /bin/python2.7 /bin/python
RUN ln -s /usr/lib/libbz2.so.1.0 /usr/lib/libbz2.so.1
RUN mkdir -p /lib/python2.7/site-packages/
RUN mkdir -p /include/python2.7/
# install easy_install
RUN curl https://bitbucket.org/pypa/setuptools/raw/0.7.4/ez_setup.py -o - | python - --user
RUN rm -f /setuptools-0.7.4.tar.gz
CMD [ "/bin/sh" ]
Using the aws-cli
tool inside your own container of small size becomes easy now:
FROM odise/busybox-python:stable
RUN easy_install awscli
There might be some limitations due to the nature of Pyrun. I didn’t tested tools other then aws
so far. If you have some experience in using Pyrun, please drop me a line.
blog comments powered by Disqus