AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Deploy Apache HTTPD Container with Podman via Ansible

By Luca Berton · Published 2024-01-01 · Category: installation

Automate the deployment of Apache HTTPD in a Podman container using Ansible. Set up web root, custom index.html, and manage container settings.

Deploy Apache HTTPD Container with Podman via Ansible

How to Setup Apache Web Server in a Podman Container for RedHat-like systems with Ansible?

I'm going to show you a live Playbook with some simple Ansible code. I'm Luca Berton and welcome to today's episode of Ansible Pilot.

See also: Deploy Apache HTTPD with Podman Using Ansible Playbook

Setup Apache Web Server in a Podman Container for RedHat-like systems

• install packages => ansible.builtin.yum • custom index.html => ansible.builtin.copy • 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 four steps that you could automate with different Ansible modules. Firstly you need to verify that podman and it dependency is successfully installed on the target system using the ansible.builtin.yum Ansible module. Secondly, you need to create the custom index.html with ansible.builtin.copy Ansible module. You could upgrade this step using the template module. Thirdly, 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_container Ansible module.

Links

containers.podman.podman_imagecontainers.podman.podman_containerhttpd image

## Playbook

How to Setup Apache Web Server in a Podman Container for RedHat-like systems with Ansible Playbook.

code

---
- name: deploy httpd container
  hosts: all
  become: true
  gather_facts: false
  vars:
    webroot: "/webroot"
  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: webroot present ansible.builtin.file: path: "{{ webroot }}" state: directory owner: "root" group: "root" mode: '0777' setype: "container_share_t"

- name: custom index.html ansible.builtin.copy: dest: "{{ webroot }}/index.html" content: | Custom Web Page setype: "container_share_t"

- name: run httpd container containers.podman.podman_container: name: webserver image: httpd state: started detach: true expose: - 80 ports: - 8080:80 volume: - "{{ webroot }}:/usr/local/apache2/htdocs/:exec"

execution

ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory container/podman_httpd_redhat2.yml

PLAY [deploy httpd on container] ******************************************************************

TASK [podman installed] *************************************************************************** changed: [demo.example.com]

TASK [pull image] ********************************************************************************* changed: [demo.example.com]

TASK [webroot present] **************************************************************************** changed: [demo.example.com]

TASK [custom index.html] ************************************************************************** changed: [demo.example.com]

TASK [run httpd container] ************************************************************************ changed: [demo.example.com]

PLAY RECAP **************************************************************************************** demo.example.com : ok=5 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

ansible-pilot $

idempotency

ansible-pilot $ ansible-playbook -i virtualmachines/demo/inventory container/podman_httpd_redhat2.yml

PLAY [deploy httpd on container] ******************************************************************

TASK [podman installed] *************************************************************************** ok: [demo.example.com]

TASK [pull image] ********************************************************************************* ok: [demo.example.com]

TASK [webroot present] **************************************************************************** changed: [demo.example.com]

TASK [custom index.html] ************************************************************************** ok: [demo.example.com]

TASK [run httpd container] ************************************************************************ changed: [demo.example.com]

PLAY RECAP **************************************************************************************** demo.example.com : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

ansible-pilot $

before execution

ansible-pilot $ ssh devops@demo.example.com
Last login: Thu Mar 10 13:26:52 2022 from 192.168.0.59
[devops@demo ~]$ 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"
[devops@demo ~]$ podman images
-bash: podman: command not found
[devops@demo ~]$ podman ps -a
-bash: podman: command not found
[devops@demo ~]$ 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
[devops@demo ~]$

after execution

ansible-pilot $ ssh devops@demo.example.com
Last login: Thu Mar 24 17:39:48 2022 from 192.168.0.59
[devops@demo ~]$ sudo su
[root@demo devops]# 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" [root@demo devops]# podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/httpd latest b9bd7e513e0f 7 days ago 148 MB [root@demo devops]# podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 804debe95694 docker.io/library/httpd:latest httpd-foreground 58 seconds ago Up 58 seconds ago 0.0.0.0:8080->80/tcp webserver [root@demo devops]# dnf info podman Updating Subscription Management repositories. Last metadata expiration check: 0:12:45 ago on Thu 24 Mar 2022 05:28:22 PM UTC. Installed Packages Name : podman Epoch : 1 Version : 3.4.2 Release : 9.module+el8.5.0+13852+150547f7 Architecture : x86_64 Size : 48 M Source : podman-3.4.2-9.module+el8.5.0+13852+150547f7.src.rpm Repository : @System From repo : 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

[root@demo devops]# podman inspect webserver [ { "Id": "804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688", "Created": "2022-03-24T17:39:49.78841153Z", "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": 5066, "ConmonPid": 5057, "ExitCode": 0, "Error": "", "StartedAt": "2022-03-24T17:39:50.278583744Z", "FinishedAt": "0001-01-01T00:00:00Z", "Healthcheck": { "Status": "", "FailingStreak": 0, "Log": null } }, "Image": "b9bd7e513e0fc49bd6703bde67cf6526033a9bade13a34b7be04e0e7339f6d2e", "ImageName": "docker.io/library/httpd:latest", "Rootfs": "", "Pod": "", "ResolvConfPath": "/run/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/resolv.conf", "HostnamePath": "/run/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/hostname", "HostsPath": "/run/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/hosts", "StaticDir": "/var/lib/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata", "OCIConfigPath": "/var/lib/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/config.json", "OCIRuntime": "runc", "ConmonPidFile": "/run/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/conmon.pid", "PidFile": "/run/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/userdata/pidfile", "Name": "webserver", "RestartCount": 0, "Driver": "overlay", "MountLabel": "system_u:object_r:container_file_t:s0:c305,c750", "ProcessLabel": "system_u:system_r:container_t:s0:c305,c750", "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/d558e2996c1e8e8eb14a6b1dff8be88d0e7c56c9b99d872265a98b5760741335/diff:/var/lib/containers/storage/overlay/707eeb55ebc2c5600ff8a80cd7657f5c0ff2913f763b2eb0eaa4cc079ebadbb9/diff:/var/lib/containers/storage/overlay/f1f0f964583ace4b905b7e33ccea241ce070ba53c9af547a9748c4b11b70bb30/diff:/var/lib/containers/storage/overlay/0cc07aba0259fc6e4b7b57685491e97b6f9de9d9b77fa27954c14b199017d333/diff:/var/lib/containers/storage/overlay/3a626bb08c24b5cc968d312bf5694aa87b6d9961c5f182c6bc138d8ca8ac13ee/diff", "MergedDir": "/var/lib/containers/storage/overlay/18bb651c4d12c4058c6f05339ba2b7a70d599bea91681f160fe5f450b395b52c/merged", "UpperDir": "/var/lib/containers/storage/overlay/18bb651c4d12c4058c6f05339ba2b7a70d599bea91681f160fe5f450b395b52c/diff", "WorkDir": "/var/lib/containers/storage/overlay/18bb651c4d12c4058c6f05339ba2b7a70d599bea91681f160fe5f450b395b52c/work" } }, "Mounts": [ { "Type": "bind", "Source": "/webroot", "Destination": "/usr/local/apache2/htdocs/", "Driver": "", "Mode": "", "Options": [ "exec", "rbind" ], "RW": true, "Propagation": "rprivate" } ], "Dependencies": [], "NetworkSettings": { "EndpointID": "", "Gateway": "10.88.0.1", "IPAddress": "10.88.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "0e:f3:ac:75:bb:6c", "Bridge": "", "SandboxID": "", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "80/tcp": [ { "HostIp": "", "HostPort": "8080" } ] }, "SandboxKey": "/run/netns/cni-e8744179-964b-b311-651e-dbe108773e0a", "Networks": { "podman": { "EndpointID": "", "Gateway": "10.88.0.1", "IPAddress": "10.88.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "0e:f3:ac:75:bb:6c", "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", "804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688" ], "Namespace": "", "IsInfra": false, "Config": { "Hostname": "804debe95694", "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_SHA256=d0bbd1121a57b5f2a6ff92d7b96f8050c5a45d3f14db118f64979d525858db63", "HTTPD_PATCHES=", "HTTPD_PREFIX=/usr/local/apache2", "HTTPD_VERSION=2.4.53", "HOME=/root", "HOSTNAME=804debe95694" ], "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-24T17:39:49.78841153Z", "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", "--volume", "/webroot:/usr/local/apache2/htdocs/:exec", "--publish", "8080:80", "httpd" ], "Umask": "0022", "Timeout": 0, "StopTimeout": 10 }, "HostConfig": { "Binds": [ "/webroot:/usr/local/apache2/htdocs/:exec,rw,rprivate,rbind" ], "CgroupManager": "systemd", "CgroupMode": "host", "ContainerIDFile": "", "LogConfig": { "Type": "k8s-file", "Config": null, "Path": "/var/lib/containers/storage/overlay-containers/804debe95694391a50b4e597cda2cbe7d5e88bc89da9efaf2325c871fc3c1688/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 } } ] [root@demo devops]#

Apache Web Server in a Docker Container for RedHat-like systems

code with ❤️ in GitHub

See also: Configure Apache Vhost on RedHat Using Ansible Playbook

Conclusion

Now you know how to set up Apache Web Server in a Podman Container for RedHat-like systems with Ansible.

Related Articles

Ansible template guideDocker Compose with Ansibleinventory configuration in Ansiblethe Ansible become referencethe ansible.builtin.file reference

Category: installation

Watch the video: Deploy Apache HTTPD Container with Podman via Ansible — Video Tutorial

Browse all Ansible tutorials · AnsiblePilot Home