Title: Docker cheatsheet
       Author: Solène
       Date: 24 September 2020
       Tags: docker
       Description: 
       
       Simple Docker cheatsheet. This is a short introduction about Docker
       usage
       and common questions I have been asking myself about Docker.
       
       The official documentation for building docker images can be [found
       here](https://docs.docker.com/develop/)
       
       ## Build an image
       
       Building an image is really easy. As a requirement, you need to be
       in a directory that can contain data you will use for building the
       image but most importantly, you need a `Dockerfile` file.
       
       The Dockerfile file hold all the instructions to create the container.
       A simple example would be this description:
       
           FROM busybox
           CMD "echo" "hello world"
       
       This will create a docker container using busybox base image
       and run `echo "hello world"` when you run it.
       
       To create the container, use the following command in the same
       directory in which Dockerfile is:
       
           $ docker build -t your-image-name .
       
       
       ## Advanced image building
       
       If you need to compile sources to distribute a working binary,
       you need to prepare the environment to have the required
       dependencies to compile and then you need to compile a static
       binary to ship the container without all the dependencies.
       
       In the following example we will use a debian environment to build
       the software downloaded by git.
       
           FROM debian as work
           WORKDIR /project
       
           RUN apt-get update
           RUN apt-get install -y git make gcc
           RUN git clone git://bitreich.org/sacc /project
           RUN apt-get install -y libncurses5-dev libncurses5
           RUN make LDFLAGS="-static -lncurses -ltinfo"
       
           FROM debian
       
           COPY --from=work /project/sacc /usr/local/bin/sacc
       
           CMD "sacc" "gopherproject.org"
       
       I won't explain every command here, but you may see that I have
       split the packages installation in two commands. This was to help
       debugging.
       
       The trick here is that the docker build process has a cache feature.
       Every time you use a `FROM`, `COPY`, `RUN` or `CMD` docker will
       cache the current state of the build process, if you re-run the
       process docker will be able to pick up the most recent state until
       the change.
       
       I wasn't sure how to compile statically the software at first, and
       having to install git make and gcc and run git clone EVERY TIME
       was very time consuming and bandwidth consuming.
       
       In case you run this build and it fails, you can re-run the build
       and docker will catch up directly at the last working step.
       
       If you change a line, docker will reuse the last state with a
       FROM/COPY/RUN/CMD command before the changed line. Knowing about
       this is really important for more efficient cache use.
       
       
       ## Run an image
       
       With the previously locally built image we can run it with the command:
       
           $ docker run your-image-name
           hello world
       
       By default, when you use an image name to run, if you don't have a
       local image that match the name *docker* will check on the docker
       official repository if an image exists, if so, it will be pulled
       and run.
       
           $ docker run hello-world
       
       This is a sample official container that will display some
       explanations about docker.
       
       If you want to try a gopher client, I made a docker version of it
       that you can run with the following command:
       
           $ docker run -t -i rapennesolene/sacc
       
       Why did you require `-t` and `-i` parameters? The former
       is to tell docker you want a tty because it will manipulate
       a terminal and the latter is to ask an interactive session.
       
       
       ## Persistant data
       
       By default, every data of the docker container get wiped out
       once it stops, which may be really undesirable if you use
       docker to deploy a service that has a state and require an
       installation, configuration files etc...
       
       Docker has two ways to solve it:
       
       1) map a local directory
       2) map a docker volume name
       
       This is done with the parameter `-v` with the `docker run` command.
       
           $ docker run -v data:/var/www/html/ nextcloud
       
       This will map a persistent storage named "data" on the host
       on the path `/var/www/html` in the docker instance. By using `data`,
       docker will check if `/var/lib/docker/volumes/data` exists, if so
       it will reuse it and if not it will create it.
       
       This is a convenient way to name volumes and let docker manage it.
       
       The other way is to map a local path to a container environment
       path.
       
           $ docker run -v /home/nextcloud:/var/www/html nextcloud
       
       In this case, the directory `/home/nextcloud` on the host and
       `/var/www/html` in the docker environment will be the same directory.