DevOps Practice Lab Automating Nginx Installation Using Docker and Ansible
- Project Goal
The goal of this practice was to simulate a real DevOps environment where:
- A control node runs Ansible
- Multiple target nodes are created using Docker containers
- Ansible connects to these nodes using SSH
- Nginx is installed automatically using an Ansible playbook
This setup helps understand how configuration management tools automate infrastructure.
- Architecture
+----------------------+
| Ansible Control Node |
| (Host Machine) |
+----------+-----------+
|
| SSH
|
-------------------------------------
| |
+---------------+ +---------------+
| Docker Target | | Docker Target |
| Container | | Container |
| target1 | | target2 |
| | | |
| SSH + Nginx | | SSH + Nginx |
+---------------+ +---------------+
Docker Network: ansible-net
- Tools Used
- Docker
- Ansible
- NGINX
- Ubuntu Linux
- Project Directory Structure
ansible-docker-lab
│
├── Dockerfile
├── inventory
├── install-nginx.yaml
└── README.md
- Target Node Dockerfile
This Dockerfile creates a container that:
- Runs SSH server
- Allows Ansible to connect
- Has Nginx installed
- Exposes required ports
Dockerfile
FROM ubuntu:22.04
RUN apt update && \
apt install -y openssh-server sudo nginx && \
mkdir /var/run/sshd
RUN useradd -m ansible && \
echo "root:admin" | chpasswd && \
adduser ansible sudo
EXPOSE 22
EXPOSE 80
CMD ["/usr/sbin/sshd", "-D"]- Build the Docker Image
docker build -t ansible-target .
Verify image: docker images
- Create Docker Network
Creating a custom network helps containers communicate easily.
docker network create ansible-net
Verify network:
docker network ls
- Run Master & Target Containers
Master node
docker run -dit \
--name master \
--network ansible-net \
ubuntu:latestCreate one target nodes.
Target1
docker run -dit \
--name target1 \
--network ansible-net \
-p 2223:22 \
-p 8082:80 \
ansible-targetVerify containers:
docker ps -aGo into the Master container and install Ansible
docker exec -it master bash
sudo -i
apt update
apt install python-is-python3 vim iputils-ping openssh-client -y ## Geographical area 6 city 44
apt install software-properties-common
add-apt-repository --yes --update ppa:ansible/ansible
apt install ansible
To test Ansible is installed or not
ansible --version
```
---
generate the ssh key from the ssh-keygen command
ssh-keygen
provide 3 times enter (1 location verification + 2 time for passwd )
copy the generated ssh keys from ansible_master to target machine and check the connectivity
Copy the generated key from ansible_master to remote target
ssh-copy-id root@target1
yes
- Test SSH Connectivity
Test SSH connection manually.
ping target1
ssh ansible@localhost -p 2222
Password:
admin
- Create Ansible Inventory OR edit host file
edit ansible host file and provide the target IP’s
cd /etc/ansible/
ls
Go to hosts file
provide the IP of the target machines like target1
Step 14 verify as you are able to ping target machine from ansible_master
ping
Create a file called inventory
[target]
target1 ansible_host=localhost ansible_port=2222 ansible_user=ansible ansible_password=ansible
target2 ansible_host=localhost ansible_port=2223 ansible_user=ansible ansible_password=ansible
Test connectivity:
ansible -i inventory target -m ping
ansible all -m ping Expected output:
target1 | SUCCESS
target2 | SUCCESS
File name:
install-nginx.yaml
---
- hosts: target
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Start nginx
service:
name: nginx
state: startedansible-playbook -i inventory install-nginx.yaml
ansible-playbook install-nginx.yaml if we have not created inventory file
- Verify Nginx Installation
Open browser:
http://localhost:8081
and
http://localhost:8082
You should see the NGINX welcome page.
Check containers
docker psStop container
docker stop target1Start container
docker start target1Remove container
docker rm target1Enter container
docker exec -it target1 bashCheck logs
docker logs target1While performing this lab, several issues occurred:
Containers get new IPs when recreated.
Solution:
Use Docker network + container names
Initially port 80 was not exposed, so Nginx was not reachable.
Solution:
EXPOSE 80
SSH failed because:
- Port not mapped
- SSH service not running
Solution:
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
Example mistake while using sed:
sed -e "s/^target/target1"
Correct command:
sed -e "s/^target/target1/"
✔ Use Docker networks instead of static IPs ✔ Always expose required ports in Dockerfile ✔ Use SSH keys instead of passwords ✔ Automate configuration using Ansible playbooks ✔ Maintain infrastructure using version-controlled code (Git)
Through this practice I learned:
- How Ansible connects to remote machines
- How Docker containers can simulate infrastructure
- How to automate package installation
- How to troubleshoot configuration issues
- Importance of automation in DevOps workflows
Next steps for improving this lab:
- Add Ansible control node container
- Use Docker Compose
- Deploy application containers
- Integrate with CI/CD pipeline
- Move setup to Kubernetes cluster
If you want, I can also give you a much more advanced GitHub project version (the kind that impresses DevOps interviewers) with:
- Docker Compose setup
- 3 Ansible target nodes
- Automatic SSH key setup
- Production-style folder structure
- Architecture diagram
That kind of project can seriously strengthen your DevOps resume.