Skip to content

Instantly share code, notes, and snippets.

@silveraid
Created October 27, 2017 12:09
Show Gist options
  • Save silveraid/e6bdf78441c731a30a66fc6adca6f4b5 to your computer and use it in GitHub Desktop.
Save silveraid/e6bdf78441c731a30a66fc6adca6f4b5 to your computer and use it in GitHub Desktop.
Creating minimal CentOS docker image from scratch
# Create a folder for our new root structure
$ export centos_root='/centos_image/rootfs'
$ mkdir -p $centos_root
# initialize rpm database
$ rpm --root $centos_root --initdb
# download and install the centos-release package, it contains our repository sources
$ yum reinstall --downloadonly --downloaddir . centos-release
$ rpm --root $centos_root -ivh centos-release*.rpm
$ rpm --root $centos_root --import $centos_root/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
# install yum without docs and install only the english language files during the process
$ yum -y --installroot=$centos_root --setopt=tsflags='nodocs' --setopt=override_install_langs=en_US.utf8 install yum
# configure yum to avoid installing of docs and other language files than english generally
$ sed -i "/distroverpkg=centos-release/a override_install_langs=en_US.utf8\ntsflags=nodocs" $centos_root/etc/yum.conf
# chroot to the environment and install some additional tools
$ cp /etc/resolv.conf $centos_root/etc
$ chroot $centos_root /bin/bash <<EOF
yum install -y procps-ng iputils
yum clean all
EOF
$ rm -f $centos_root/etc/resolv.conf
# install and enable docker
$ yum install -y docker
...
$ systemctl start docker
# create docker image
$ tar -C $centos_root -c . | docker import - centos
sha256:28843acfa85226385d2db0196db72465729db38088ea98751d4a5c3d4c85ccd
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 28843acfa852 11 seconds ago 287.7 MB
# run docker image
$ docker run --rm centos cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
Source: https://www.sidorenko.io/post/2016/07/creating-container-base-image-of-centos/
@dedalqq
Copy link

dedalqq commented Oct 1, 2018

[root@8a986baef9eb /]# rpm --root $centos_root -ivh centos-release*.rpm
warning: centos-release-7-5.1804.4.el7.centos.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
error: Failed dependencies:
        /bin/sh is needed by centos-release-7-5.1804.4.el7.centos.x86_64
        coreutils is needed by centos-release-7-5.1804.4.el7.centos.x86_64
        grep is needed by centos-release-7-5.1804.4.el7.centos.x86_64

need add --nodeps

rpm --nodeps --root $centos_root -ivh centos-release*.rpm

@gbolo
Copy link

gbolo commented Feb 8, 2019

Very nice! smallest centos image I have ever seen!

@jmturner
Copy link

You need to add --nodeps to the rpm --root $centos_root -ivh centos-release*.rpm line. Otherwise, it asks for a shell, coreutils, and grep.

@kbuley
Copy link

kbuley commented Oct 1, 2019

In case anyone else runs into this...

mount -o bind /dev $centos_root/dev

should be executed before trying to run yum in the chroot

@silveraid
Copy link
Author

In case anyone else runs into this...

mount -o bind /dev $centos_root/dev

should be executed before trying to run yum in the chroot

Yes, you are absolutely right! I should get these steps fixed up, I haven't noticed that it is gaining popularity. I really really like docker's multi stage build idea and I build everything in containers nowadays to remove dependency on my own workstation, so back in the days when I worked on this I turned the same idea into a Dockerfile, can be found here:

https://github.com/silveraid/docker-centos-micro/blob/master/Dockerfile.

For me it was very important to have as small footprint as possible, in the dockerfile version I avoid installing rpm or yum packages, because they pull down a lot of dependencies with themselves. Instead I compile and install busybox which has its own minimal rpm implementation which works in case of a big need to get something installed, but for a production docker image there should not really be.

@knight-of-ni
Copy link

knight-of-ni commented Jan 5, 2020

Thanks for posting this script. I had been on the hunt for a centos-8 aarch64 image when I came across these instructions to make my own.

What follows is an adaptation of the original script for el8. My host machine is an rpi-3b running Fedora 31 aarch64. Since the host OS is different than the target OS, I used wget to grab a remote copy of centos-release.

The override_install_langs flag is not available in dnf.conf so I couldn't use that. Perhaps that is why the image turned out quite a bit fatter. If there is another way to set this flag, I am open to feedback.

#!/bin/bash 

# Create a folder for our new root structure
$ export centos_root='/centos_image/rootfs'
$ mkdir -p $centos_root

# initialize rpm database
$ rpm --root $centos_root --initdb

# download and install the centos-release package, it contains our repository sources
# grab the centos-release package appropriate to your architecture
$ wget http://mirror.lax.genesisadaptive.com/centos/8.0.1905/BaseOS/aarch64/os/Packages/centos-release-8.0-0.1905.0.9.el8.aarch64.rpm
$ rpm --nodeps --root $centos_root -ivh centos-release*.rpm
$ rpm --root $centos_root --import  $centos_root/etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial

# install dnf without docs during the process
$ dnf -y --installroot=$centos_root --setopt=tsflags='nodocs' install dnf

# configure dnf to avoid installing of docs
echo "tsflags=nodocs" >> $centos_root/etc/dnf/dnf.conf

# chroot to the environment and install some additional tools
$ cp /etc/resolv.conf $centos_root/etc
$ chroot $centos_root /bin/bash <<EOF
dnf install -y procps-ng iputils
dnf clean all
EOF
$ rm -f $centos_root/etc/resolv.conf

# install and enable docker
$ dnf install -y docker
...
$ systemctl start docker

# create docker image
$ tar -C $centos_root -c . | docker import - centos
sha256:6e726203e4864e000d367551515c5531055cb5b871cfdd63acad816bbddb9bbb

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos              latest              6e726203e486        30 seconds ago      569MB

# run docker image
$ docker run --rm centos cat /etc/redhat-release
CentOS Linux release 8.0.1905 (Core)

Source: https://www.sidorenko.io/post/2016/07/creating-container-base-image-of-centos/

@nileshkumar008
Copy link

[root@localhost ~]# chroot $centos_root /bin/bash <<EOF
yum install -y procps-ng iputils
yum clean all
EOF
error: Failed to initialize NSS library
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

cannot import name ts

Please install a package which provides this module, or
verify that the module is installed correctly.

It's possible that the above module doesn't match the
current version of Python, which is:
2.7.5 (default, Apr 2 2020, 13:16:51)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

If you cannot solve this problem yourself, please go to
the yum faq at:
http://yum.baseurl.org/wiki/Faq

error: Failed to initialize NSS library
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

cannot import name ts

Please install a package which provides this module, or
verify that the module is installed correctly.

It's possible that the above module doesn't match the
current version of Python, which is:
2.7.5 (default, Apr 2 2020, 13:16:51)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]

If you cannot solve this problem yourself, please go to
the yum faq at:
http://yum.baseurl.org/wiki/Faq

@nileshkumar008
Copy link

mount -o bind /dev $centos_root/dev

issue has been resolved

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment