📖 Estimated reading time: 4 min
It’s not as complicated as you might think. Automating infrastructure with Ansible can save time and eliminate manual setup errors.
If you’re new to Ansible, a great first project is deploying a web server in a container. In this tutorial, you’ll learn how to create an Ansible playbook that installs Podman, launches an Alpine Linux container, sets up Apache, and serves a simple “Hello World” page.
All this is done in 5 simple steps. Don’t believe me? Read on.
By the end of this guide, you’ll have a fully functional web server running on port 8080, accessible from your browser. All with just a single Ansible command.
Let’s get started! 🚀
In this lab I’ll be using Ubuntu. But you can use any Linux distribution. The result will be the same.
Before running the playbook, ensure you have:
*
Ansible installed on your machine
*
A target system with Podman installed (or let the playbook install it)
*
SSH access to the target system
Create a new file named apache_container.yml
and add the following content:
- name: Deploy Apache in a Podman Container
hosts: servers
become: yes
tasks:
- name: Install Podman
package:
name: podman
state: present
- name: Create an Apache container
containers.podman.podman_container:
name: apache_container
image: docker.io/httpd:alpine
state: started
recreate: yes
restart_policy: always
detach: true
ports:
- "8080:80"
- name: Copy index.html to the container
command: podman cp index.html apache_container:/usr/local/apache2/htdocs/index.html
✅ I know you could just use the “copy” module. However, the example only uses command
to show how the reader could do more activities in this example playbook.
1)
Install Ansible
$ apt install ansible-core
2)
Configure Ansible Inventory
Ensure your target server is listed under the [servers]
group in your inventory file.
*
If you’re running the Ansible playbook on localhost, your inventory file (inventory.ini
) should look like this:
[servers]
localhost ansible_connection=local
3)
Create the Web Server index.html
page.
I’ve made this neat page for you. 😎
$ cat index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My First Ansible Page</title>
<style>
body {
text-align: center;
font-family: Arial, sans-serif;
}
img {
margin-bottom: 20px;
}
img {
max-width: 100%;
height: auto;
}
.info {
margin-top: 20px;
font-size: 1.2em;
}
</style>
</head>
<body>
<img src="https://raw.githubusercontent.com/ansible/logos/refs/heads/main/community-logo/Ansible-Community-Logo-RGB-Black.png" alt="Ansible Logo">
<h1>Hello World! This is my first Ansible Playbook!</h1>
<div class="info">
<p><strong>Current Date and Time:</strong> <span id="datetime">Loading...</span></p>
</div>
<script>
function updateDateTime() {
var currentDate = new Date();
var dateStr = currentDate.toLocaleString();
document.getElementById('datetime').innerText = dateStr;
}
setInterval(updateDateTime, 1000);
</script>
</body>
</html>
By the way, you can find all these files on our public github.
4)
Run the Playbook using the following command:
$ ansible-playbook -i inventory.ini apache_container.yml
Running the playbook generates messages similar to these:
5)
Access Your Web Server
Open a browser and go to:
http://<server-ip>:8080
You should see your “Hello World! This is my first Ansible Playbook!” message displayed. 🎉
It was easier than you thought, wasn’t it? 😃
You can see the resources created and running using commands like these:
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6375dce19dde docker.io/library/httpd:alpine httpd-foreground 12 minutes ago Up 12 minutes 0.0.0.0:8080->80/tcp apache_container
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/httpd alpine fcd9ece3a2cc 4 weeks ago 66.2 MB
$ podman logs apache_container | tail -10
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.31. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.31. Set the 'ServerName' directive globally to suppress this message
[Sun Feb 23 21:43:41.514018 2025] [mpm_event:notice] [pid 1:tid 1] AH00489: Apache/2.4.63 (Unix) configured -- resuming normal operations
[Sun Feb 23 21:43:41.514061 2025] [core:notice] [pid 1:tid 1] AH00094: Command line: 'httpd -D FOREGROUND'
X.X.X.X - - [23/Feb/2025:21:43:45 +0000] "GET / HTTP/1.1" 200 1192
X.X.X.X - - [23/Feb/2025:21:44:54 +0000] "GET / HTTP/1.1" 200 1192
X.X.X.X - - [23/Feb/2025:21:44:55 +0000] "GET /favicon.ico HTTP/1.1" 404 196
10.88.0.1 - - [23/Feb/2025:21:51:13 +0000] "GET / HTTP/1.1" 200 1192
To remove the resources you have created:
$ podman stop apache_container
$ podman rm apache_container
$ podman image rm docker.io/library/httpd:alpine
Untagged: docker.io/library/httpd:alpine
Deleted: fcd9ece3a2cca157cc637f914abf56d62aba9884aa1ee3a9b3c94dc88904874e
Congratulations! You’ve successfully automated the deployment of an Apache web server using Ansible and Podman. This is just the beginning!
Explore more advanced Ansible features to manage your infrastructure efficiently. 🚀
If you want more Ansible automation examples, let us know in the comments! 🎫
Did you like the content? Check out these other interesting articles! 🔥
✅ Leave a message with your questions! Share this material with your network!
Do you like what you find here? With every click on a banner, you help keep this site alive and free. Your support makes all the difference so that we can continue to bring you the content you love. Thank you very much! 😊