Containers and Persistence
10 MINUTE EXERCISE
Containers are meant to be run as "immutable" instances that exactly match the state of the image that they were started from (as we saw in the last section). However, there many scenarios where adjusting this otherwise immutable state would be useful such as:
-
Having the containers running the same image run differently in different environments (e.g. Pre-Production vs Production environments)
-
For instance, having applications in the container consume different configuration data based on the environment
-
-
Persisting state beyond the life of the container (e.g. Databases, logfiles)
-
Sharing state between containers
Luckily, containers have facilities to support all these things. We’ll explore some of these features in this section
Mounting Volumes
Whilst containers have their own immutable filesystem, it is possible for containers to "mount" volumes that are outside the container’s filesystem. This opens up opportunities for persisting state on those mounted filesystems or sharing that state with processes outside the container.
This can also open a number of security concerns for our containers as we’ll see later on! |
Going back to our website, let’s see how we can run our webserver in such a way that we can persist our visitor_info.txt. Our strategy will be to have the container write to a file that is local to our VM filesystem instead of into the container’s filesystem.
-
First, let’s remove (and stop) any container that we might have running (such as the container based on
container-workshop-commit
):podman rm -a \ --force (1)
1 This is a bit of a violent way to stop and remove a running container. It’s a little bit like using kill -9
to stop a linux process. -
Since we’re going to use the VM’s filesystem for persistence, we don’t need to use our committed image (
container-workshop-commit
) anymore, especially now that we’ve copied off of it thevisitor_info.txt
we’d like to use. Let’s remove that image from our machine[1]podman rmi \(1) localhost/container-workshop-commit (2)
1 rmi
stands for remove image. Don’t confuse this withrm
which has to do with removing containers that are stopped2 We’re removing based on the image name. We could also remove by IMAGE ID
-
If the command worked, you should see output like the following:
Untagged: localhost/container-workshop-commit:latest Deleted: f154f395c55ed7192f180502495b96cb3c223d9ce50273cda41bb63e272be7d8
-
Next, we’ll run our initial
quay.io/bfarr/container-workshop-httpd:0.0.6
image, but this time with an additional-v
optionpodman run \ --privileged \ -d \ -p 8081:80/tcp \ --name my-web-server \ -v /home/%USER%/container-workshop:/var/log/www:Z \(1) quay.io/bfarr/container-workshop-httpd:0.0.6
1 The format of the volume mount option is <host_path>:<container_path>:<options>. In our case, we’re mounting /home/%USER%/container-workshop
at/var/log/www
in the container. TheZ
option is for SELinux it tells podman to relabel the volume’s content to match the label inside the container
Testing the Volume Mount
Now that the container is running mounted to the /home/%USER%/container-workshop
on the host, we should be able to test out its effects
-
Make sure you have the
visitor_info.txt
open in VSCode in an editor pane next to the Browser Preview pane as shown -
Next, navigate to the guestbook URL by navigating pasting this in the Browser Preview
localhost:8081/hello.html
-
Once there, enter a name (such as Danny) into the name field and press Submit
-
You should now see Danny (or whatever name you entered) added to the
visitor_info.txt
on the host in real timeFigure 1. See visitors on the host