EX180 Series: Deploying a Rootless Multi-Container WordPress Application with Podman

Part 3 of the EX180 series.

The Plan

We’ve covered most of the exam objectives related to Podman in the previous article. What we’re going to do today is to take a look at how to use environment variables, set up persistent storage and perform a multi-container deployment of a WordPress application.

Note that tasks 1-4 can be found in the previous post.

Podman Task 5: Deploy a WordPress Application

Use podman to deploy a new WordPress application with persistent database storage to meet all of the following requirements:

  1. You must run Podman containers as a non-root user (rootless).
  2. Create a new $HOME/wpdb_podman directory on the host.
  3. Apply the correct SELinux context type to the $HOME/wpdb_podman directory (and all subdirectories) to allow containers to access to all of its content.
  4. Create a new pod named wp.
  5. Create a new MySQL container named wpdb in detached mode.
  6. Use the tag 5.7-49 of the container image registry.access.redhat.com/rhscl/mysql-57-rhel7.
  7. The user that the MySQL container runs as is UID=27 and GID=27 (you can use podman inspect command to verify this).
  8. Set the following environment variables in the wpdb container:
    1. MYSQL_ROOT_PASSWORD=ex180AdminPassword
    2. MYSQL_USER=wpuser
    3. MYSQL_PASSWORD=ex180UserPassword
    4. MYSQL_DATABASE=wordpress
  9. Mount the host directory $HOME/wpdb_podman to the wpdb container path /var/lib/mysql/data.
  10. Create a new WordPress container named wpapp in detached mode.
  11. Use the latest version of the docker.io/library/wordpress container image.
  12. Set the following environment variables in the wpapp container:
    1. WORDPRESS_DB_HOST=127.0.0.1
    2. WORDPRESS_DB_USER=wpuser
    3. WORDPRESS_DB_PASSWORD=ex180UserPassword
    4. WORDPRESS_DB_NAME=wordpress
  13. Port forward from host port 8080 to the wpapp container port 80.
  14. Both wpapp and wpdb containers should belong to the wp pod.

Solution to Podman Task 5

Create a directory to use for persistent storage:

$ mkdir -p $HOME/wpdb_podman

Check the current SELinux context of the directory:

$ ls -Zd $HOME/wpdb_podman
unconfined_u:object_r:user_home_t:s0 /home/user/wpdb_podman

Use man pages if you don’t remember semanage syntax:

$ man semanage-fcontext

Set the new SELinux context:

$ sudo semanage fcontext -a -t container_file_t "$HOME/wpdb_podman(/.*)?"
$ sudo restorecon -Rv $HOME/wpdb_podman

Verify that the SELinux context has been applied:

$ ls -Zd $HOME/wpdb_podman
unconfined_u:object_r:container_file_t:s0 /home/user/wpdb_podman

Let us quickly verify the user of the MySQL container by inspecting the image:

$ podman inspect registry.access.redhat.com/rhscl/mysql-57-rhel7:5.7-49 | grep User
"User": "27",
"User": "27",

Because we have to use rootless containers, we need to change the UID/GID of the volume directory $HOME/wpdb_podman in the rootless Podman user namespace to match the UID/GID of the MySQL container user.

We can see below that the $HOME/wpdb_podman directory is owned by the UID/GID of 0, which is not the same UID/GID as the MySQL container 27.

$ podman unshare ls -aln $HOME/wpdb_podman
total 4
drwxrwxr-x.  2 0 0    6 Nov 24 21:36 .
drwx------. 11 0 0 4096 Nov 24 21:33 ..

This means that the database container will fail to write to the directory. We need to fix it:

$ podman unshare chown -R 27:27 $HOME/wpdb_podman

Verify:

$ podman unshare ls -aln $HOME/wpdb_podman
total 4
drwxrwxr-x.  2 27 27    6 Nov 24 21:36 .
drwx------. 11  0  0 4096 Nov 24 21:33 ..

Create a new pod called wp with port forwarding and verify:

$ podman pod create --name wp -p 8080:80
$ podman pod ps
POD ID        NAME        STATUS      CREATED            INFRA ID      # OF CONTAINERS
44b9f3ce2b47  wp          Running     About an hour ago  6026e0eda6c0  1

Run a new MySQL container in an existing wp pod with persistent storage:

$ podman run -d \
  --pod wp \
  --name database \
  -e MYSQL_ROOT_PASSWORD="ex180AdminPassword" \
  -e MYSQL_USER="wpuser" \
  -e MYSQL_PASSWORD="ex180UserPassword" \
  -e MYSQL_DATABASE="wordpress" \
  --volume $HOME/wpdb_podman:/var/lib/mysql/data \
  registry.access.redhat.com/rhscl/mysql-57-rhel7:5.7-49

Make sure that the database container is running, and that the data directory has been populated with data:

$ podman logs --tail=1 database
Version: '5.7.24'  socket: '/var/lib/mysql/mysql.sock'  port: 3306  MySQL Community Server (GPL)
$ ls -ln $HOME/wpdb_podman/
total 41036
-rw-r-----. 1 100026 100026       56 Nov 24 21:42 auto.cnf
-rw-------. 1 100026 100026     1680 Nov 24 21:42 ca-key.pem
-rw-r--r--. 1 100026 100026     1112 Nov 24 21:42 ca.pem
-rw-r--r--. 1 100026 100026     1112 Nov 24 21:42 client-cert.pem
-rw-------. 1 100026 100026     1676 Nov 24 21:42 client-key.pem
-rw-r-----. 1 100026 100026      673 Nov 24 21:42 ib_buffer_pool
-rw-r-----. 1 100026 100026 12582912 Nov 24 21:42 ibdata1
-rw-r-----. 1 100026 100026  8388608 Nov 24 21:42 ib_logfile0
-rw-r-----. 1 100026 100026  8388608 Nov 24 21:42 ib_logfile1
-rw-r-----. 1 100026 100026 12582912 Nov 24 21:57 ibtmp1
drwxr-x---. 2 100026 100026     4096 Nov 24 21:42 mysql
-rw-r--r--. 1 100026 100026        6 Nov 24 21:42 mysql_upgrade_info
drwxr-x---. 2 100026 100026     8192 Nov 24 21:42 performance_schema
-rw-------. 1 100026 100026     1676 Nov 24 21:42 private_key.pem
-rw-r--r--. 1 100026 100026      452 Nov 24 21:42 public_key.pem
-rw-r--r--. 1 100026 100026     1112 Nov 24 21:42 server-cert.pem
-rw-------. 1 100026 100026     1680 Nov 24 21:42 server-key.pem
drwxr-x---. 2 100026 100026     8192 Nov 24 21:42 sys
drwxr-x---. 2 100026 100026       20 Nov 24 21:42 wordpress
-rw-r-----. 1 100026 100026        2 Nov 24 21:42 wp.pid

Run a new WordPress container in an existing wp pod:

$ podman run -d \
 --pod wp \
 --name application \
 -e WORDPRESS_DB_HOST="127.0.0.1" \
 -e WORDPRESS_DB_USER="wpuser" \
 -e WORDPRESS_DB_PASSWORD="ex180UserPassword" \
 -e WORDPRESS_DB_NAME="wordpress" \
  docker.io/library/wordpress:latest

Check to see if both containers are running:

$ podman ps
CONTAINER ID  IMAGE                                                   COMMAND               CREATED            STATUS                PORTS                 NAMES
6026e0eda6c0  localhost/podman-pause:4.1.1-1666713358                                       About an hour ago  Up About an hour ago  0.0.0.0:8080->80/tcp  44b9f3ce2b47-infra
c064b4fe26c9  registry.access.redhat.com/rhscl/mysql-57-rhel7:5.7-49  run-mysqld            29 minutes ago     Up 29 minutes ago     0.0.0.0:8080->80/tcp  database
947d4296255a  docker.io/library/wordpress:latest                      apache2-foregroun...  16 minutes ago     Up 16 minutes ago     0.0.0.0:8080->80/tcp  application

Check the number of containers in the pod:

$ podman pod ps
POD ID        NAME        STATUS      CREATED            INFRA ID      # OF CONTAINERS
44b9f3ce2b47  wp          Running     About an hour ago  6026e0eda6c0  3

Use curl to access the WordPress website:

$ curl -L http://127.0.0.1:8080

The task is complete.

What’s Next?

We will look into deploying various applications to our OpenShift cluster.

6 thoughts on “EX180 Series: Deploying a Rootless Multi-Container WordPress Application with Podman

  1. Hi Tomas,
    this looks like a great example for EX180, it helps my study. Thank you!
    I’m getting ready for my exam tomorrow. Have you already done yours? How did it go? Any tips to share?
    Best regards, Eliska.

    • Hi Eliska, thank you. I’ve not taken the exam yet as I still need to go through the OpenShift objectives, but it should not take more than a week I estimate. Good luck with your exam tomorrow.

  2. thank u, i was try to run wordpress on docker-compose (podman-compose) but no luck
    your method work excellent for me (podman)

Leave a Reply

Your email address will not be published.