Sunday, February 28, 2021

A Docker Image from Scratch

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