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