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. |