Monday, March 16, 2015

Creating Base Images

In First Steps with Docker, we have used a fairly crude way to create initial base images. A minimalistic approach to come to a base image environment is to have only the necessary rpms installed through on-board tools. This assumes the system is enabled for accessing all packages online.

Inspired from, this script works both for SLES 12 and RHEL 7:

Update 3/26: added "--releasever=/" to the yum statement, per Neale's comment and the discussion on the LINUX390 mailing list at Marist. Also added copying of /etc/rhsm and /etc/pki (works the same for me, works better for Neale). Thanks for pointing this out, Neale.
Update 5/07: added "/etc/products.d" to the cp statement, to avoid warnings in some cases when using zypper.
Update 10/12: removing yum cache contents (via that "yum clean all" takes another 34MB away, so down to ~110 MB now
Update 1/29: hint on an issue. It seems the LinuxONE cloud also requires the comment to be uncommented...
Update 5/17: set CMD to /bin/bash for convenience
Update 6/21: use yum-plugin-ovl to avoid issues between yum and overlayfs-backend (also Thanks again for pointing to this package, Neale!
mkdir img || exit
mkdir -m 755 img/dev
mknod -m 600 img/dev/console c 5 1
mknod -m 600 img/dev/initctl p
mknod -m 666 img/dev/full c 1 7
mknod -m 666 img/dev/null c 1 3
mknod -m 666 img/dev/ptmx c 5 2
mknod -m 666 img/dev/random c 1 8
mknod -m 666 img/dev/tty c 5 0
mknod -m 666 img/dev/tty0 c 4 0
mknod -m 666 img/dev/urandom c 1 9
mknod -m 666 img/dev/zero c 1 5

test -d /etc/yum && yum --installroot=$PWD/img --releasever=/ --setopt=tsflags=nodocs \
--setopt=group_package_types=mandatory -y install bash yum vim-minimal yum-plugin-ovl
test -d /etc/yum && cp -a /etc/yum* /etc/rhsm/* /etc/pki/* img/etc/
test -d /etc/yum && yum --installroot=$PWD/img clean all

# in some cases the following line is needed. I still have not understood, why...
# test -d /etc/zypp && mkdir img/etc && cp -a /etc/zypp* /etc/products.d img/etc/

test -d /etc/zypp && zypper --root $PWD/img  -D /etc/zypp/repos.d/ \

--no-gpg-checks -n install -l bash zypper vim
test -d /etc/zypp && cp -a /etc/zypp* /etc/products.d img/etc/

rm -fr img/usr/{{lib,share}/locale,{lib,lib64}/gconv,bin/localedef,sbin/build-locale-archive}
rm -fr img/usr/share/{man,doc,info,gnome/help}
rm -fr img/usr/share/cracklib
rm -fr img/usr/share/i18n
rm -fr img/etc/
rm -fr img/var/cache/ldconfig/*

Please pay attention to line feeds due to the rendering in your browser (particularly watch the yum and zypper commands and the first line with rm). This script produces a directory img containing a lean environment just capable of running a shell, editing files and comfortably install further packages (via zypper/yum). You can import it into an image using
cd img
tar cf - . | docker import --change "CMD /bin/bash" - your-image-name

The results is a comfortably small image:
r1745044:~ # docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
sles12-mini           latest              d67d54066582        19 seconds ago      249.7 MB
[root@r1745042 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
rhel7-mini          latest              ea7c03641155        23 seconds ago      138.1 MB
You can add any packages to the package installer line (zypper/yum) in the script, e.g. should you prefer another editor. Of course, true fans of emacs probably can remove all other packages except emacs (but then they still need a good editor :-).


  1. For yum, I learned that I needed to add --repository=7Server as the $releasever variable wasn't being expanded and the yum install would fail.

  2. Hi Neale, thanks a lot! I updated the script in the article.