You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
programming-basics-2022/10_docker/lesson04/README.md

101 lines
3.8 KiB

# Lesson 4: Persisting data
1. Change directory into `lesson04`.
1. We saw in Lesson 3 that data written to the final container layer does
not persist. How do we deal with this? One option is to have the container
write to an external system like a database system or cloud storage. There
is, however, another method: mounting a local file system or directory.
1. Let's create a Docker container that saves the current date to a file. Here is
our first attempt:
# Dockerfile
FROM debian:buster-slim
LABEL maintainer="adamhl@stanford.edu"
ADD date.sh /root/date.sh
RUN chmod a+x /root/date.sh
CMD /root/date.sh
# date.sh
#!/bin/sh
echo "echoing date to /tmp/date.output"
date > /tmp/date.output
$ docker build . -t date
$ docker run --rm --name=fuzzle date
echoing date to /tmp/date.output
1. The above will create the file `/tmp/date.output` containing the date
but we know that the file will not persist after the container stops
running. To get around this we "mount" a local directory into the
container's `/tmp` directory. By "local directory" we mean a directory on
the computer where we run the our `docker` commands. We mount the colume
when we run the container.
$ mkdir -p /tmp/docker
$ docker run --rm --name=fuzzle --volume=/tmp/docker:/tmp date
echoing date to /tmp/date.output
$ cat /tmp/docker/date.output
1. You can run a container and override the `CMD` command.
$ docker run --rm --name=fuzzle date ls -ld /etc
drwxr-xr-x 1 root root 4096 Jan 17 17:23 /etc/
(The date.sh script did NOT run)
1. This is especially useful when you want to login to the container and
debug the filesystem or CMD command.
1. You can overwrite a file in the image using the same `--volume`
option. For example, let's overwrite `/etc/debian_version` with a
different file.
$ docker run --rm --name=fuzzle date cat /etc/debian_version
10.7
$ echo "fake-version" > /tmp/deb_ver
$ docker run --rm --name=fuzzle --volume=/tmp/deb_ver:/etc/debian_version date cat /etc/debian_version
fake-version
1. If you mount an external directory onto a container directory
**everything** in the directory in the container is **replaced** with the
external directory.
$ docker run --rm --name=fuzzle date ls -l /usr
total 32
drwxr-xr-x 2 root root 4096 Jan 11 00:00 bin
drwxr-xr-x 2 root root 4096 Nov 22 12:37 games
... more ...
# Create a directory in /tmp with a single file.
$ mkdir -p /tmp/usr; cp test.txt /tmp/usr
# Mount /tmp/usr over /usr in the container
$ docker run --rm --name=fuzzle --volume=/tmp/usr:/usr date ls -l /usr
total 4
-rw-r--r-- 1 52777 root 7 Jan 17 18:04 test.txt
1. You can mount an external directory in read-only mode. This is
particularly useful when injecting secrets or configuration information
into a container. Look for the `ro` in the `--volume` option below.
$ mkdir -p /tmp/secrets
$ echo "my-password" > /tmp/secrets/password
$ docker run --rm --name=fuzzle --volume=/tmp/secrets:/secrets:ro date sleep 100000 &
$ docker exec -ti fuzzle /bin/sh
# cat /secrets/password
my-password
# echo "another secret" >> /secrets/password
/bin/sh: 5: cannot create /secrets/password: Read-only file system
$ docker kill fuzzle
1. You can run the entire container in read-only mode. The `docker run`
option `--read-only` mounts the root filesystem (i.e., everything) in
read-only excepting any externally mounted volumes. This lets you
lock-down the filesystem except for those parts of the filesystem you
know need to be written to (e.g., `/tmp`, `/var/log`, etc.).