Using Buildah to build containers for Docker and Podman

One of my colleagues pointed me to an article on using Buildah to create container images: How rootless Buildah works: Building containers in unprivileged environments.

I decided to test it out! In this case, I just wanted to build a container using the shell script method described in the article, rather than using a Dockerfile. Although the rootless aspect is interesting to me, I believe that requires newer versions of Buildah than what is available by default on CentOS 7. A project for another day!

First, I needed a test case. I decided to use my NLTK chatbot container image, which can be found at:

Continue reading Using Buildah to build containers for Docker and Podman

Running WordPress on Docker

Similar to the previous post, Running Joomla on Docker, I was interested in spinning up a temporary WordPress installation so that I could target it with various scanning and reconnaissance tools. There is an official WordPress Docker image at https://hub.docker.com/_/wordpress/.

The steps were more-or-less the same. Note that if you followed the steps in the previous post, you will likely want to stop and remove the existing MySQL container before attempting to start a new one with the same name:

docker stop some-mysql
docker rm some-mysql

Start the MySQL Docker container:

docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=passW0rd -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wordpress -e MYSQL_PASSWORD=wpP455 -d mysql:5

Start the WordPress Docker container:

docker run --name some-wordpress --link some-mysql:mysql -e WORDPRESS_DB_HOST=172.17.0.2 -e WORDPRESS_DB_USER=wordpress -e WORDPRESS_DB_PASSWORD=wpP455 -e WORDPRESS_DB_NAME=wordpress -p 8080:80 -d wordpress

I was then able to visit http://localhost:8080 and complete the web-based setup tasks.

Note that the MySQL container, as launched, does not have any shared volumes. Everything stored there is ephemeral and will be lost if the container is removed. To my surprise, however, the content survived stopping and restarting the container. The volumes for each container are located in the following directory:

/var/lib/docker/volumes/

Using docker inspect some-wordpress I could see that there was a mounted volume at:

/var/lib/docker/volumes/be3d54591da609e911a1ec3f0615a564990b37da184a67fab0ac0e75cc711c7f/_data

Indeed, the usual WordPress files, such as wp-config.php, were located there.

I did the same for the MySQL container and found the .frm and .ibd files for each of the tables in the WordPress database.

These files persist when the container is stopped, and persist even when the container is removed! In fact, when I removed all containers, I discovered there were still 22 volumes in /var/lib/docker/volumes from previous container projects and experiments.

The command to view these volumes is:

docker volume ls

To remove unused volumes, use:

docker volume prune

Container volumes are not as ephemeral as I originally thought!

Running Joomla on Docker

I was looking for a well-known CMS (Content Management System) that I could easily run in a Docker container as a target for information security reconnaissance tools, such as WhatWeb.

I found an official Docker image for Joomla, a CMS that I had used previously some years ago: https://hub.docker.com/_/joomla
Continue reading Running Joomla on Docker

Using Docker to get root access

In my previous post I mentioned that I am learning about Podman, a tool for running containers that does not require a daemon process (like the Docker daemon) or root privileges.

In this post I would like to demonstrate why running containers with root privileges could be dangerous.
Continue reading Using Docker to get root access

Docker versus Podman and iptables

I have recently been learning about podman, a tool for running containers that has a command syntax that matches Docker, but that does not require a Docker daemon and which does not require root privileges.

I ran into some unexpected problems publishing ports with Podman, which had to do with my default DROP policy on the iptables FORWARD chain. Below I will demonstrate some of the differences between Docker and Podman in terms of iptables changes, and provide a workaround for Podman.
Continue reading Docker versus Podman and iptables

Running a Python Flask application in a Docker container

I’ve played with Docker containers but haven’t really done anything, useful or otherwise, with them. I decided to create a Docker image that includes a web-based chatbot. You can find the Git repository for this (including the finished Dockerfile) at https://github.com/cherdt/docker-nltk-chatbot

Continue reading Running a Python Flask application in a Docker container

Kitchen CI – using the Vagrant driver

I’d previously been using the Docker driver with Kitchen CI and kitchen-ansible to test my Ansible playbooks. I really like using Kitchen CI. Test-driven infrastructure development! Regression testing! It’s great.

There were several reasons I decided to switch from the Docker driver to Vagrant. My target hosts are all either VMs or bare metal servers, so Vagrant VMs more closely resemble that environment. In particular, there are a couple areas where Docker containers don’t perform well for this purpose:

  • Configuring and testing SELinux settings
  • Configuring and testing systemd services

Continue reading Kitchen CI – using the Vagrant driver

Using a Dockerfile to modify a container

In the previous post I modified a CentOS Docker container image to include the man application as a simple example. But it was not obvious looking at the container what modifications, if any, had been made. I wanted instead to specify the installation of man via a Dockerfile so that the modifications to the base OS would be more clear to another user.

First, I create a new empty directory and create a Dockerfile within the directory:

$ mkdir man-centos
$ cd man-centos
$ vi Dockerfile

In the Dockerfile, I specify that I want to use the publicly-available CentOS 7 base image, and then install the man package via yum:

# Start with CentOS 7
FROM centos:7

# Install the man yum module
RUN yum -y install man

Then build and run the container:

$ docker build -t man-centos .
$ docker run -i -t man-centos
[root@6f597c97d72d /]# man man
No manual entry for man

It works!

Running CentOS in a Docker container

I’m just getting started with Docker. I’ve thought for years that containerization is a great idea, but I haven’t actually done anything with containers yet. Time to get started.

I ran through a couple tutorials on the Docker docs site and created a cloud.docker.com account to get some basic familiarity.

I found the CentOS container repository on Docker Hub: https://hub.docker.com/_/centos/

Let’s try running it!

$ docker pull centos
$ docker run centos

Did it do anything? It looks like it did something. At least, it didn’t give me an error. What did it do? How do I access it?

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

Nothing is actively running. That makes sense, because we’re not telling the containerized OS to do anything — it starts, it doesn’t have anything to do, and so it shuts down immediately. Instead we can tell it to run interactively and with a terminal by specifying a couple options:

-i, --interactive
-t, --tty
(“allocate a pseudo-TTY”, i.e. a terminal)
(see docker run --help for details)

$ docker run -i -t centos
[root@4f0b435cdbd7 /]#

I’m in!

What if I want to modify the container? Right now it is pretty bare-bones. For example, this doesn’t even have man installed:

[root@4f0b435cdbd7 /]# man man
bash: man: command not found

[root@4f0b435cdbd7 /]# yum install man
...
[root@4f0b435cdbd7 /]# man man
No manual entry for man

Quite the improvement! Now we need to save our change:

[root@4f0b435cdbd7 /]# exit

$ docker commit 4f0b435cdbd7 man-centos
$ docker run -i -t man-centos

[root@953c512d6707 /]# man man
No manual entry for man

Progress! Now we have a CentOS container where man is already installed. Exciting.

I can’t (that I know of) inspect the container and know whether or not man is installed without running it. That’s fine for many cases, but next I will attempt to figure out how specify via a Dockerfile that man is installed.