Initially, we need a minimal root filesystem.
mkdir base-image cd base-image #assuming we're inside the base-image dir chr=$(pwd) mkdir -p dev/{pts,shm} touch dev/console mkdir etc touch etc/hostname etc/hosts etc/resolv.conf ln -s /proc/mounts etc/mtab mkdir ./{proc, sys} #now we copy our application that is the target of containerization, in this case it's bash and a few other utils cp -v /bin/{bash,touch,ls,rm} $chr/bin #copy bash dependencies, ldd will tell us what bash requires at runtime to run list="$(ldd /bin/bash | egrep -o '/lib.*\.[0-9]')" echo $list for i in $list; do cp -v --parents "$i" "${chr}"; done list="$(ldd /bin/touch | egrep -o '/lib.*\.[0-9]')" echo $list for i in $list; do cp -v --parents "$i" "${chr}"; done list="$(ldd /bin/ls | egrep -o '/lib.*\.[0-9]')" echo $list for i in $list; do cp -v --parents "$i" "${chr}"; done list="$(ldd /bin/rm | egrep -o '/lib.*\.[0-9]')" echo $list for i in $list; do cp -v --parents "$i" "${chr}"; done #run chroot to test sudo chroot . /bin/bash
Once chroot is working and we're able to jail the bash app, we proved that bash is able to run in isolation, it's got all it needs.
We now create the Dockerfile from scratch
FROM scratch COPY bin/ /bin/ COPY lib/ /lib COPY lib64/ /lib64 COPY usr/ /usr/ #RUN ["/bin/bash", "/bin/ls", "."] #ENTRYPOINT ["/bin/bash"] CMD ["/bin/bash"]
To build the image,
sudo docker build . -t bshell
To run the image
sudo docker run -it --rm bshell
[1] Using Chroot https://www.howtogeek.com/441534/how-to-use-the-chroot-command-on-linux/
[2] Docker: Up & Running 2nd Edition https://learning.oreilly.com/library/view/docker-up/9781492036722/ch04.html#docker_images