Deploy Apache Web Server in a Podman Container for RedHat-like systems - Ansible modules podman_image and podman_container
How to automate the setup of a detached Apache httpd Web Server tag:latest in a Podman Container pass-throw of port 8080 to 80 for RedHat-like systems.


How to Setup Apache Web Server in a Podman Container for RedHat-like systems with Ansible?
I’m going to show you a live demo with some simple Ansible code. I’m Luca Berton and welcome to today’s episode of Ansible Pilot.
Setup Apache Web Server in a Podman Container for RedHat-like systems
- install packages =>
ansible.builtin.yum
- pull image =>
containers.podman.podman_image
- run container =>
containers.podman.podman_container
Today we’re talking about how to Deploy a web server apache httpd in a Podman Container for RedHat-like Linux systems.
The full process requires three steps that you could automate with different Ansible modules.
Firstly you need to verify that podman
and its dependency is successfully installed on the target system using the ansible.builtin.yum
Ansible module.
Secondly, you need to pull the image for the container hub registry using the containers.podman.podman_image
Ansible module.
Finally, you could run the webserver
container setting the right port and settings using the containers.podman.podman_image
Ansible module.
Links
The Best Resources For Ansible
Video Course
Printed Book
eBooks
- Ansible by Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps
- Ansible For Windows By Examples: 50+ Automation Examples For Windows System Administrator And DevOps
- Ansible For Linux by Examples: 100+ Automation Examples For Linux System Administrator and DevOps
- Ansible Linux Filesystem By Examples: 40+ Automation Examples on Linux File and Directory Operation for Modern IT Infrastructure
- Ansible For Containers and Kubernetes By Examples: 20+ Automation Examples To Automate Containers, Kubernetes and OpenShift
- Ansible For Security by Examples: 100+ Automation Examples to Automate Security and Verify Compliance for IT Modern Infrastructure
- Ansible Tips and Tricks: 10+ Ansible Examples to Save Time and Automate More Tasks
- Ansible Linux Users & Groups By Examples: 20+ Automation Examples on Linux Users and Groups Operation for Modern IT Infrastructure
- Ansible For PostgreSQL by Examples: 10+ Examples To Automate Your PostgreSQL database
- Ansible For Amazon Web Services AWS By Examples: 10+ Examples To Automate Your AWS Modern Infrastructure
demo
How to Setup Apache Web Server in a Podman Container for RedHat-like systems with Ansible Playbook.
code
---
- name: deploy httpd on container
hosts: all
become: true
gather_facts: false
tasks:
- name: podman installed
ansible.builtin.yum:
name: podman
state: latest
- name: pull image
containers.podman.podman_image:
name: httpd
pull: true
tag: latest
- name: run httpd container
containers.podman.podman_container:
name: webserver
image: httpd
state: started
detach: true
expose:
- 80
ports:
- 8080:80
execution
ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory container/podman_httpd_redhat.yml
PLAY [deploy httpd on container] ******************************************************************
TASK [podman installed] ***************************************************************************
changed: [demo.example.com]
TASK [pull image] *********************************************************************************
changed: [demo.example.com]
TASK [run httpd container] ************************************************************************
changed: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible-pilot $
idempotency
ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory container/podman_httpd_redhat.yml
PLAY [deploy httpd on container] ******************************************************************
TASK [podman installed] ***************************************************************************
ok: [demo.example.com]
TASK [pull image] *********************************************************************************
ok: [demo.example.com]
TASK [run httpd container] ************************************************************************
ok: [demo.example.com]
PLAY RECAP ****************************************************************************************
demo.example.com : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansible-pilot $
before execution
ansible-pilot $ ssh [email protected]
Last login: Thu Mar 10 13:26:52 2022 from 192.168.0.59
[[email protected] ~]$ cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="8.5 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.5"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.5 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8::baseos"
HOME_URL="https://www.redhat.com/"
DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/8/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.5"
[[email protected] ~]$ podman images
-bash: podman: command not found
[[email protected] ~]$ podman ps -a
-bash: podman: command not found
[[email protected] ~]$ dnf info podman
Not root, Subscription Management repositories not updated
This system is not registered with an entitlement server. You can use subscription-manager to register.
Extra Packages for Enterprise Linux 8 - x86_64 4.0 MB/s | 11 MB 00:02
Extra Packages for Enterprise Linux Modular 8 - x86_64 1.1 MB/s | 979 kB 00:00
Red Hat Enterprise Linux 8 for x86_64 - AppStream (RPMs) 5.2 MB/s | 39 MB 00:07
Red Hat Enterprise Linux 8 for x86_64 - BaseOS (RPMs) 5.1 MB/s | 43 MB 00:08
Last metadata expiration check: 0:00:01 ago on Thu 10 Mar 2022 01:49:01 PM UTC.
Available Packages
Name : podman
Epoch : 1
Version : 3.4.2
Release : 9.module+el8.5.0+13852+150547f7
Architecture : x86_64
Size : 12 M
Source : podman-3.4.2-9.module+el8.5.0+13852+150547f7.src.rpm
Repository : rhel-8-for-x86_64-appstream-rpms
Summary : Manage Pods, Containers and Container Images
URL : https://podman.io/
License : ASL 2.0 and GPLv3+
Description : podman (Pod Manager) is a fully featured container engine that is a simple
: daemonless tool. podman provides a Docker-CLI comparable command line that
: eases the transition from other container engines and allows the management of
: pods, containers and images. Simply put: alias docker=podman.
: Most podman commands can be run as a regular user, without requiring
: additional privileges.
:
: podman uses Buildah(1) internally to create container images.
: Both tools share image (not container) storage, hence each can use or
: manipulate images (but not containers) created by the other.
:
: Manage Pods, Containers and Container Images
: podman Simple management tool for pods, containers and images
[[email protected] ~]$
after execution
ansible-pilot $ ssh [email protected]
Last login: Thu Mar 10 13:51:51 2022 from 192.168.0.59
[[email protected] ~]$ dnf list podman
Not root, Subscription Management repositories not updated
This system is not registered with an entitlement server. You can use subscription-manager to register.
Last metadata expiration check: 0:03:14 ago on Thu 10 Mar 2022 01:49:01 PM UTC.
Installed Packages
podman.x86_64 1:3.4.2-9.module+el8.5.0+13852+150547f7 @rhel-8-for-x86_64-appstream-rpms
[[email protected] ~]$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
[[email protected] ~]$ sudo su
[[email protected] devops]# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd latest faed93b28859 9 days ago 148 MB
[[email protected] devops]# podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7cc5542c1315 docker.io/library/httpd:latest httpd-foreground About a minute ago Up About a minute ago 0.0.0.0:8080->80/tcp webserver
[[email protected] devops]# podman inspect webserver
[
{
"Id": "7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f",
"Created": "2022-03-10T13:51:35.775768438Z",
"Path": "httpd-foreground",
"Args": [
"httpd-foreground"
],
"State": {
"OciVersion": "1.0.2-dev",
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 31163,
"ConmonPid": 31153,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-03-10T13:51:36.588506647Z",
"FinishedAt": "0001-01-01T00:00:00Z",
"Healthcheck": {
"Status": "",
"FailingStreak": 0,
"Log": null
}
},
"Image": "faed93b2885914426b66f1a7d09d93dce9e532fa64f4ab269494f4f954a424ef",
"ImageName": "docker.io/library/httpd:latest",
"Rootfs": "",
"Pod": "",
"ResolvConfPath": "/run/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/resolv.conf",
"HostnamePath": "/run/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/hostname",
"HostsPath": "/run/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/hosts",
"StaticDir": "/var/lib/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata",
"OCIConfigPath": "/var/lib/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/config.json",
"OCIRuntime": "runc",
"ConmonPidFile": "/run/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/conmon.pid",
"PidFile": "/run/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/pidfile",
"Name": "webserver",
"RestartCount": 0,
"Driver": "overlay",
"MountLabel": "system_u:object_r:container_file_t:s0:c451,c643",
"ProcessLabel": "system_u:system_r:container_t:s0:c451,c643",
"AppArmorProfile": "",
"EffectiveCaps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETFCAP",
"CAP_SETGID",
"CAP_SETPCAP",
"CAP_SETUID",
"CAP_SYS_CHROOT"
],
"BoundingCaps": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FOWNER",
"CAP_FSETID",
"CAP_KILL",
"CAP_NET_BIND_SERVICE",
"CAP_NET_RAW",
"CAP_SETFCAP",
"CAP_SETGID",
"CAP_SETPCAP",
"CAP_SETUID",
"CAP_SYS_CHROOT"
],
"ExecIDs": [],
"GraphDriver": {
"Name": "overlay",
"Data": {
"LowerDir": "/var/lib/containers/storage/overlay/1345c2cbce29ac4359dcfe1b4a3190e53b5aac31a935d18b4baed4c8768c28eb/diff:/var/lib/containers/storage/overlay/b0d92095f16bf5442a30bab61a2f6975edd31e1975d0ae7be7678fc130bf0021/diff:/var/lib/containers/storage/overlay/d937211382861385f5d76295eefd9c55d1001a76659d7c5bba6202986812efcc/diff:/var/lib/containers/storage/overlay/bdde0e7a150aae757505c58b36544af32717eec2c27bc702d87927e3df6e62ad/diff:/var/lib/containers/storage/overlay/1401df2b50d5de5a743b7bac3238ef3b7ce905ae39f54707b0ebb8eda3ab10bc/diff",
"MergedDir": "/var/lib/containers/storage/overlay/67a15d124b540bf322968edf705d80f476e0d6dee518a30cf4997f7af1e6337b/merged",
"UpperDir": "/var/lib/containers/storage/overlay/67a15d124b540bf322968edf705d80f476e0d6dee518a30cf4997f7af1e6337b/diff",
"WorkDir": "/var/lib/containers/storage/overlay/67a15d124b540bf322968edf705d80f476e0d6dee518a30cf4997f7af1e6337b/work"
}
},
"Mounts": [],
"Dependencies": [],
"NetworkSettings": {
"EndpointID": "",
"Gateway": "10.88.0.1",
"IPAddress": "10.88.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "e6:05:a4:f4:2a:f2",
"Bridge": "",
"SandboxID": "",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
]
},
"SandboxKey": "/run/netns/cni-9d3a11f4-aa99-1b9a-cb35-e215d72d584d",
"Networks": {
"podman": {
"EndpointID": "",
"Gateway": "10.88.0.1",
"IPAddress": "10.88.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "e6:05:a4:f4:2a:f2",
"NetworkID": "podman",
"DriverOpts": null,
"IPAMConfig": null,
"Links": null
}
}
},
"ExitCommand": [
"/usr/bin/podman",
"--root",
"/var/lib/containers/storage",
"--runroot",
"/run/containers/storage",
"--log-level",
"warning",
"--cgroup-manager",
"systemd",
"--tmpdir",
"/run/libpod",
"--runtime",
"runc",
"--storage-driver",
"overlay",
"--storage-opt",
"overlay.mountopt=nodev,metacopy=on",
"--events-backend",
"file",
"container",
"cleanup",
"7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f"
],
"Namespace": "",
"IsInfra": false,
"Config": {
"Hostname": "7cc5542c1315",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm",
"container=podman",
"HTTPD_PREFIX=/usr/local/apache2",
"HTTPD_VERSION=2.4.52",
"HTTPD_SHA256=0127f7dc497e9983e9c51474bed75e45607f2f870a7675a86dc90af6d572f5c9",
"HTTPD_PATCHES=",
"HOME=/root",
"HOSTNAME=7cc5542c1315"
],
"Cmd": [
"httpd-foreground"
],
"Image": "docker.io/library/httpd:latest",
"Volumes": null,
"WorkingDir": "/usr/local/apache2",
"Entrypoint": "",
"OnBuild": null,
"Labels": null,
"Annotations": {
"io.container.manager": "libpod",
"io.kubernetes.cri-o.Created": "2022-03-10T13:51:35.775768438Z",
"io.kubernetes.cri-o.TTY": "false",
"io.podman.annotations.autoremove": "FALSE",
"io.podman.annotations.init": "FALSE",
"io.podman.annotations.privileged": "FALSE",
"io.podman.annotations.publish-all": "FALSE",
"org.opencontainers.image.stopSignal": "28"
},
"StopSignal": 28,
"CreateCommand": [
"podman",
"container",
"run",
"--name",
"webserver",
"--detach=True",
"--expose",
"80",
"--publish",
"8080:80",
"httpd"
],
"Umask": "0022",
"Timeout": 0,
"StopTimeout": 10
},
"HostConfig": {
"Binds": [],
"CgroupManager": "systemd",
"CgroupMode": "host",
"ContainerIDFile": "",
"LogConfig": {
"Type": "k8s-file",
"Config": null,
"Path": "/var/lib/containers/storage/overlay-containers/7cc5542c13150a122b2adc025f3c14c312f48d8955492378e0dbab43ffc0048f/userdata/ctr.log",
"Tag": "",
"Size": "0B"
},
"NetworkMode": "bridge",
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
]
},
"RestartPolicy": {
"Name": "",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": [],
"CapDrop": [
"CAP_AUDIT_WRITE",
"CAP_MKNOD"
],
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": [],
"GroupAdd": [],
"IpcMode": "private",
"Cgroup": "",
"Cgroups": "default",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "private",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": [],
"Tmpfs": {},
"UTSMode": "private",
"UsernsMode": "",
"ShmSize": 65536000,
"Runtime": "oci",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": 0,
"OomKillDisable": false,
"PidsLimit": 2048,
"Ulimits": [
{
"Name": "RLIMIT_NOFILE",
"Soft": 1048576,
"Hard": 1048576
},
{
"Name": "RLIMIT_NPROC",
"Soft": 4194304,
"Hard": 4194304
}
],
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"CgroupConf": null
}
}
]
[[email protected] devops]#
Recap
Now you know how to set up Apache Web Server in a Podman Container for RedHat-like systems with Ansible. Subscribe to the YouTube channel, Medium, Website, Twitter, and Substack to not miss the next episode of the Ansible Pilot.
Academy
Learn the Ansible automation technology with some real-life examples in my
My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps
Donate
Want to keep this project going? Please donate