Container Deployment using Azure Virtual Machine (IaaS) and Azure Container Instance (PaaS)
Lesson 22. Introduction
This project is a complete hands-on lab on containerizing web applications with Docker and then deploying them to the cloud using Microsoft Azure.
It covers the full journey from building Docker images locally for both a static website (HTML/CSS/JS) and a dynamic PHP application, publishing them to Docker Hub, and finally deploying the same images in Azure using two different methods:
- Azure Virtual Machine (IaaS) — full control
- Azure Container Instance (PaaS) — fully managed
Tools & Technologies Used
Project Workflow
Local Development
├── Download / Extract web application source code
├── Write Dockerfile (Nginx for static site / PHP-Apache for dynamic app)
├── Build Docker image
├── Run container locally and test
└── Tag & Push image to Docker Hub
2. Cloud Deployment — Method 1: Azure Virtual Machine (IaaS)
├── Create Ubuntu Virtual Machine in Azure
├── Download SSH private key and connect via SSH
├── Install Docker on the VM
├── Pull the Docker image from Docker Hub
├── Run the container and map port 80
├── Access the website using the VM Public IP
└── Delete the resource group when finished (cost control)
3. Cloud Deployment — Method 2: Azure Container Instance (PaaS)
├── Create a Container Instance in Azure Portal
├── Select the Docker Hub image
├── Configure public DNS name and port 80
├── Deploy the container
└── Access the website using the Azure-provided DNS name
Lab
Deploy Docker Images on Azure VM — IaaS
Deploy Docker Images on Azure VM — PaaS
Steps
> Log in to the Azure portal
> Search for Virtual Machine and click Create.
> Create a new resource group
> Resource Group: create or select one
> VM Name
> Region: closest to you (e.g., West US 3
> Image: Ubuntu Server 24.04 LTS
> Size: B1s (cheap and fine for testing)
This screenshot shows the creation of a new Virtual Machine in the Azure portal. Key settings include selecting an Ubuntu Server 24.04 LTS image, choosing the West US 3 region, and creating a new resource group.
> Use SSH key (recommended) or password
> Inbound Ports: Allow SSH (22). HTTP (80) ← if your app is web-based. Custom port (e.g. 3000/5000) if your container uses it.
> Click Review + Create, then Create.
Deployment Verification
Screenshot showing the virtual machine deployment has completed successfully. The user is directed to click “Go to resource” to access the newly created VM. Note: Remember to download your SSH key and create the resource.
Azure is generating an SSH key pair for secure access to the virtual machine. A warning reminds the user that the private key will only be available for download once.
Connect to the VM
> Once deployed, click Go to resource
> Open the folder you are working in in VS Code and open a new terminal
This screenshot page shows the VM Connect page; Azure shows the public IP address and SSH connection details. A warning indicates that the private key file path is missing and needs to be configured.
> Run ssh -i <private-key-file-path> azureuser@<public-ip>
Note: To get the KFP. Select the downloaded key, right-click, and select Copy as path
> Alternatively, you can connect via Azure portal → “Connect → SSH”
ssh -i <private-key-file-path> azureuser@<public-ip>Here, the screenshot shows the successful connection to the Ubuntu virtual machine via SSH using the private key. The terminal prompt azureuser@VM1:~$ confirms a successful login.
Install Docker on the VM
> Run the command sudo apt update
> Run the command sudo apt install -y docker.io
sudo apt update
sudo apt install -y docker.ioInside the VM, the command sudo apt update is executed to refresh the package lists before installing new software.
Docker is installed on the virtual machine using the command sudo apt install -y docker.io. The system downloads and installs the required packages.
Get Emele Chijioke’s stories in your inbox
Join Medium for free to get updates from this writer.
Start and enable Docker:
> Run the command sudo systemctl enable docker
> Run the command sudo systemctl start docker
> Verify the docker installed by running the command docker — -version
Note: This is equivalent to opening the Docker Desktop application.
sudo systemctl enable docker
sudo systemctl start docker
docker --versionThis screenshot shows that Docker is enabled and started as a service. Running docker — version confirms that Docker version 29.1.3 is successfully installed and ready for use.
Pull Image from Docker Hub
> Log in to Docker Hub and sign in.
> Click the repository and pull the image of the project you are working on. (emelecj/Hopewell) I used the v2 tag.
> On your terminal, run sudo docker pull emelecj/hopewell:v2
sudo docker pull emelecj/hopewell:v2The previously published Docker image emelecj/hopewell:v2 is pulled from Docker Hub onto the Azure virtual machine.
Run the Docker Container
> Run the command “sudo docker run -d -p 80:80 emelecj/hopewell:v2”.
sudo docker run -d -p 80:80 emelecj/hopewell:v2The Hopewell container is started in detached mode and mapped to port 80 using the command sudo docker run -d -p 80:80 emelecj/hopewell:v2
Test in Browser
Open: http://<public-ip> eg http://20.172.65.11
The Hopewell charity website is now accessible over the internet using the virtual machine’s public IP address (20.172.65.11), confirming the container is running correctly in the cloud.
Verify the Container is Running
> Run the command: docker images
> Run the command: docker ps — This helps you list all the running containers
> Check logs if needed: Run docker logs <container-id>
docker images
docker ps
docker logs <container-id>The commands docker images and docker ps verify that the Hopewell image is present and the container is actively running and serving traffic on port 80.
Clean Up.
> Run the command az group list -o table
> Run the command az group delete -n VM1_group
az group list -o table
az group delete -n VM1_groupUsing the Azure CLI, the user lists all resource groups to identify the one associated with the virtual machine (VM1_group).
The virtual machine resource group is deleted using az group delete -n VM1_group to clean up resources and avoid ongoing costs.
Charitize App: Deployment with Azure PaaS
> Log in to the Azure portal
> Search and select the container instance
In the Azure portal, the user searches for and selects “Container instances” to deploy a container directly without managing a full virtual machine.
> Click Create
> Create a resource group, e.g newRG
> Container name — my-container
> Regions — West US 3
> Availability zones — None.
> SKU: Standard
> Image source: other registry
> Image type: Public
> Image: emelecj/charitize — This was obtained from Docker Hub
> OS Type: Linux
> Size: This can be changed to 1 GiB.
A new Azure Container Instance is being created. The image is set to the public Docker Hub image emelecj/charitize, and basic settings such as region and size are configured.
> Under DNS name label: charitize
The Azure Container Instance deployment completes successfully, and the user is prompted to go to the resource.
> Click Review + Create, then Create.
Deployment Verification
The Azure Container Instance deployment completes successfully, and the user is prompted to go to the resource.
> Click Go to Resource
> Click on the deployed resource
> Click Settings and select Containers
The container instance overview confirms that my-container is running with the image emelecj/charitize and is in a healthy “Running” state.
> Under the overview page, copy the FQDN and run it in any browser using http:// e.g., http://charitize.ddhmhaf4bhh9gxcv.westus3.azurecontainer.io, or run with the public IP http://4.236.39.245
The Charitize website is successfully accessed over the internet using the Azure-provided DNS name (charitize.xxxxxx.westus3.azurecontainer.io), proving the PHP application is live in the cloud.
IaaS Vs PaaS
Challenges and Resolution.
Conclusion
This project successfully demonstrated how to take Docker images previously built and published to Docker Hub and deploy them in the cloud using Microsoft Azure. Two different approaches were used: first, running a container on a self-managed Ubuntu Virtual Machine, and second, deploying a container directly as an Azure Container Instance. Both the static Hopewell website and the dynamic Charitize PHP application were made publicly accessible over the internet. The lab also covered essential cloud practices such as secure SSH access, installing Docker on a cloud VM, managing resources with the Azure CLI, and cleaning up resources to control costs. Overall, this hands-on exercise shows the full journey from local Docker containers to production-ready cloud deployment.
Thank you
#LearnWithCeejay








