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.

  1. 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.
  2. 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 the visitor_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 with rm which has to do with removing containers that are stopped
    2 We’re removing based on the image name. We could also remove by IMAGE ID
  3. If the command worked, you should see output like the following:

    Untagged: localhost/container-workshop-commit:latest
    Deleted: f154f395c55ed7192f180502495b96cb3c223d9ce50273cda41bb63e272be7d8
  4. Next, we’ll run our initial quay.io/bfarr/container-workshop-httpd:0.0.6 image, but this time with an additional -v option

    podman 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. The Z 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

  1. Make sure you have the visitor_info.txt open in VSCode in an editor pane next to the Browser Preview pane as shown

    mounted visitor info setup
  2. Next, navigate to the guestbook URL by navigating pasting this in the Browser Preview

    localhost:8081/hello.html
  3. Once there, enter a name (such as Danny) into the name field and press Submit

  4. You should now see Danny (or whatever name you entered) added to the visitor_info.txt on the host in real time

    mounted visitor info
    Figure 1. See visitors on the host

1. You can keep images around if you’d like, but like VM snapshots they take of space on the host filesystem. Generally it’s good practice to remove images from your system that you are no longer using