π My First End-to-End Containerised Deployment: AWS EC2 β Docker β Docker Hub β Kubernetes
I recently completed a hands-on DevOps project where I8 deployed a simple web application through the complete container workflow β from writing the application to running it inside a Kubernetes Pod.
This project helped me understand how Docker and Kubernetes fit together in a real deployment workflow.
π οΈ What I Built
The deployment flow looked like this:
HTML Application β Dockerfile β Docker Image β Docker Hub β Kubernetes Pod β NodePort Service β Web Browser
πΉ Technologies Used
- βοΈ AWS EC2
- π³ Docker
- π¦ Docker Hub
- βΈοΈ Kubernetes
- π Kubernetes NodePort
- π» HTML
- π§ Linux
1οΈβ£ Created a Simple Web Application
I started with a basic "index.html" file containing the web application's content.
The goal wasn't to build a complex application.
Instead, I wanted to focus on understanding the deployment and containerisation process.
2οΈβ£ Provisioned an AWS EC2 Instance
I created an Amazon EC2 instance to provide the Linux environment for the project.
After connecting to the instance through SSH, I prepared the environment required for Docker and Kubernetes.
3οΈβ£ Created a Dockerfile
Next, I created a "Dockerfile" to package the web application into a Docker image.
A simple example:
FROM nginx:latest
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
Here:
- "FROM" specifies the base image.
- "COPY" places my HTML file inside the Nginx web server directory.
- "EXPOSE" documents the port used by the application.
4οΈβ£ Built the Docker Image
Once the Dockerfile was ready, I built the image using:
docker build -t my-web-app .
This converted the application and its required environment into a reusable Docker image.
I could then verify the image using:
docker images
5οΈβ£ Tested the Container Locally
Before moving to Kubernetes, I tested the Docker container:
docker run -d -p 8080:80 my-web-app
This mapped:
EC2 Port 8080 β Container Port 80
I then accessed the application through the EC2 instance's public IP and port.
6οΈβ£ Pushed the Image to Docker Hub
After confirming that the container worked correctly, I pushed the image to Docker Hub.
First, I tagged the image:
docker tag my-web-app /my-web-app:latest
Then logged in:
docker login
And pushed the image:
docker push /my-web-app:latest
This gave me a central container image that Kubernetes could pull and deploy.
7οΈβ£ Deployed the Application on Kubernetes
Next, I created a Kubernetes Pod configuration.
Example:
apiVersion: v1
kind: Pod
metadata:
name: my-web-app
spec:
containers:
- name: my-web-app
image: /my-web-app:latest
ports:
- containerPort: 80
I applied it using:
kubectl apply -f pod.yaml
Then checked the Pod:
kubectl get pods
8οΈβ£ Exposed the Pod Using a NodePort Service
A Pod alone isn't the most convenient way to expose an application externally.
So I created a Kubernetes Service using NodePort.
apiVersion: v1
kind: Service
metadata:
name: my-web-app-service
spec:
type: NodePort
selector:
app: my-web-app
ports:
- port: 80
targetPort: 80
nodePort: 30080
I then applied it:
kubectl apply -f service.yaml
And verified it with:
kubectl get services
9οΈβ£ Accessed the Application
Once the NodePort Service was running, I accessed the application through the EC2 instance's public IP and NodePort.
For example:
http://:30080
This allowed me to access the web application from my browser.
π Complete Deployment Flow
Web Application
β
βΌ
index.html
β
βΌ
Dockerfile
β
βΌ
Docker Image
β
βΌ
Docker Hub
β
βΌ
Kubernetes Pod
β
βΌ
NodePort Service
β
βΌ
EC2 Network
β
βΌ
Web Browser
π§ What I Learned
This project helped me understand several important DevOps concepts practically:
π³ Containerisation
Instead of running the application directly on the server, Docker packages the application into a portable container image.
π¦ Container Registries
Docker Hub provides a place to store and distribute container images.
βΈοΈ Kubernetes Pods
A Pod provides the basic execution environment for containers in Kubernetes.
π Kubernetes Services
Services provide a stable way to expose applications running inside Kubernetes.
π NodePort
NodePort allows a service to be accessed through a port on the Kubernetes node.
π Container Lifecycle
I also got a better understanding of the flow:
Build β Package β Push β Pull β Deploy β Expose β Access
π§ What's Next?
This is only the beginning of my Kubernetes learning journey.
My next steps are to move from manually managing a Pod to using Kubernetes resources designed for real deployments:
- Deployments
- ReplicaSets
- Rolling Updates
- ConfigMaps
- Secrets
- Ingress
- Persistent Volumes
- Kubernetes Networking
- Horizontal Pod Autoscaling
- CI/CD with GitHub Actions
- AWS EKS
The goal is to gradually move from a simple single-container deployment towards a more production-oriented architecture.
π‘ Final Takeaway
This may be a small project, but it gave me something more valuable than just theory β hands-on understanding of how an application moves from source code to a running container and finally into Kubernetes.
I'm continuing to learn by building, breaking, troubleshooting, and rebuilding.
One project at a time. π
Top comments (0)