Use storage with Podman containers


This lab shows how to use different container storage types to access the host filesystem, or persist files.


In this lab, you’ll run several exercises that:

What Do You Need?

(Hands-on Lab) Connect to the Compute Instance

Note: This step is specific to the Oracle provided free lab environment.

The Desktop environment will display before the instance(s) are ready. Deployment of this environment can take two to five minutes, depending on the number of resources and provisioning steps needed.

First, to access the lab compute instance(s), connect to the Oracle Cloud Console and copy the compute instance Public IP address.

  1. Sign in to Oracle Cloud Console, and select your Compartment.

  2. Click Instances.

  3. Copy the Public IP to a temporary location (such as a text file) on your computer.

    copy public ip

    To copy, highlight the IP address with the mouse and press Ctrl+C.

  4. Right-click the Virtual Desktop and select Open Terminal Here.

  5. Connect to the instance.

    ssh -i ../.ssh/id_rsa oracle@<IP_ADDRESS_OF_COMPUTE_INSTANCE>

    Where <IP_ADDRESS_OF_COMPUTE_INSTANCE> is the IP address copied from the Oracle Cloud Console.

  6. Accept the ECDSA key fingerprint by typing yes at the prompt.

  7. You are now connected to the compute instance for this lab.

If the connection fails with the Permission denied (publickey,gssapi-keyex,gssapi-with-mic) message, wait a bit longer for the provisioning process to complete and try making the ssh connection again.

Use a Bind Mount for Webserver Data Storage

This example demonstrates using a bind mount as the document root for a containerized Python HTTP server.

  1. Open a terminal and make a directory.

    sudo mkdir /opt/data; sudo chown opc. /opt/data

    mkdir data

    The use of sudo is necessary as elevated privileges are required to write to the /opt directory.

    Using chown changes ownership of the directory to the opc user and group, and ensures read and write access to the directory created.

  2. Create a Dockerfile.

    echo "FROM os/oraclelinux:8
    WORKDIR /opt
    RUN dnf -y module install python38 && \
        dnf clean all
    ENTRYPOINT /bin/python3 -m http.server 8000" > Dockerfile
    cat ./Dockerfile


    The FROM pulls the oraclelinux:8 image.

    The WORKDIR sets the working directory when the container runs.

    The RUN executes the command in a shell.

    The ENTRYPOINT configures the container to run the Simple Python HTTP server.

  3. Build the image.

    podman build --tag oraclelinux:pyhttp .

    build start

    build end

    --tag specifies the name which will be assigned to the resulting image if the build process completes successfully.

    If imageName does not include a registry name, the registry name localhost will be prepended to the image name.

  4. Show the new image.

    podman images

    list img

  5. Start a container based on the new image.

    podman run -d -p 8080:8000 --name webapp1 -v /opt/data:/opt oraclelinux:pyhttp

    start container

    The -d starts the container as a daemon process.

    The -p creates a port forward from 8080 on the host to 8000 in the container.

    The --name option assigns the name webapp1 to the container.

    -v maps the bind mount /opt/data/ on the host to /opt in the container.

  6. Verify the container is running.

    podman ps -a

    container running

    The container shows a status of UP.

  7. On the host system, show that the /opt/data directory is empty.

    ll /opt/data

    list dir

  8. Show the /opt directory within the container empty by using curl.

    curl localhost:8080

    curl list

    This works because the /opt directoy within the container is a bind mount to /opt/data on the host system.

    The HTTP server root directory is set to /opt as that is with working diretory where the server was started.

  9. Add files to the host system’s /opt/data directory.

    for i in {1..10}; do touch /opt/data/file${i}; done

    Using the script creates 10 empty files.

  10. Verify the script created the files successfully.

    ll /opt/data

    list dir 2

  11. Verify that the HTTP server within the container also sees the newly created files.

    curl localhost:8080

    curl list 2

    The steps show the successful use of a bind mount to allow reading and writing to the host from within a container. Any data written to the host persists after a container stops or gets removed.

  12. Stop and remove the containers.

    podman ps -a
    podman stop <CONTAINER_NAME>
    podman rm <CONTAINER_NAME>

    stop remove containers

Using Volumes with Containers

A volume is a storage device cretaed and managed by Podman. Volumes are created directly using the podman volume command or during container creation.

  1. Create a volume using podman volume.

    podman volume create my_vol

    vol create

  2. List volumes.

    podman volume ls

    vol list

  3. Remove a volume.

    podman volume rm my_vol

    vol remove

  4. Start a container and create a volume attached to it.

    podman run -it -v my_data:/data --name box1 oraclelinux:8

    vol create with container

    The container starts an interactive shell and presents a prompt.

    The -v creates the volume my_data and mounts within the container at /data.

    If the name my_data was not passed to the volume, an anonymous volume gets created. An anonymous volume does not have a name for reference, and is identified only by its unique id.

  5. Get a listing of files in /data.

    ls -l /data

    dir listing

  6. Create a test file in the volume and verify it exists.

    touch /data/sample.txt
    ls -l /data

    create and list test file

  7. Leave and exit the container.


    leave container

  8. Show the container has stopped.

    podman ps -a

    show containers

  9. Inspect the container and get a list of volumes used.

    podman inspect -f '' box1

    inspect mounts on container

    The -f formats the output and shows only the container volume details.

  10. Restart the container, and check if the file still exists.

    podman restart box1
    podman exec box1 ls -l /data

    container restart

    The command exec runs the requested command against the restarted container.

  11. Stop and then remove the container.

    podman stop box1
    podman rm box1

    stop remove container

  12. Check the volume still exists.

    podman ps -a
    podman volume ls

    check volume

    podman ps -a shows the container is removed, while podman volume ls shows the volume remains.

  13. Mount the existing volume to a new container.

    podman run -it --mount 'type=volume,src=my_data,dst=/data2' --name box2 oraclelinux:8

    mount to new container

    --mount takes the following key-value pairs when mounting an existing volume.

    • type: the type of storage being mounted
    • src: the name or unique id of a volume
    • dst: the mount point within the container

    Selected the container mount point /data2 to show the new containers mount point does not need to match the original container mount point.

  14. The data in the volume persists.

    ls -l /data2

    check data persists

  15. Leave the container.


    exit container

  16. Remove the container and all unused volume storage.

    podman rm -v box2
    podman ps -a
    podman volume ls
    podman volume prune
    podman volume ls

    remove container and volumes

    The podman volume prune removes all volumes not used by at least one container. If you only want to remove a single volume, use podman volume rm <VOLUME_NAME>.

More Learning Resources

Explore other labs on or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.