AWS Builder Center

From Docker to AWS: What I Learned While Building a Production-Style DevOps Environment

In this article, I share my DevOps learning journey from Linux, Git, and Docker to AWS, Kubernetes, Terraform, CI/CD, and observability. I explain how I connected these technologies while building a production-style environment and the key lessons I learned about automation, deployment, troubleshooting, and monitoring along the way.

From Docker to AWS: What I Learned While Building a Production-Style DevOps Environment

When I started learning DevOps, I initially focused on understanding individual tools. I learned Linux commands, Git, Docker, networking, and AWS one topic at a time.
But after building projects, I realized that knowing individual tools is not enough.
The real challenge is understanding how these tools work together to build, deploy, monitor, and maintain an application.
In this article, I want to share what I learned while moving from a basic Docker-based application toward a more production-style DevOps environment using AWS and Kubernetes.

Starting with the Basics

My DevOps journey started with Linux, networking, and Git.
Linux helped me understand how applications actually run on servers. Instead of only learning commands, I started understanding processes, ports, files, permissions, networking, and resource utilization.
Git and GitHub helped me understand how development teams manage source code and collaborate.
Then I moved to Docker.
Docker changed the way I thought about application deployment.
Instead of installing every dependency directly on my machine, I could package an application and its dependencies into a container.
A simple flow looked like this:
1
2
3
4
5
6
7
Application
↓
Dockerfile
↓
Docker Image
↓
Docker Container
This solved one common problem:
"It works on my machine."
The application environment became much more consistent between development and deployment.

Understanding Docker Beyond Containers

Initially, I thought Docker was mainly about running containers.
Later, I learned that there is much more to it.
I started working with:
  • Docker images
  • Dockerfiles
  • Container networking
  • Volumes
  • Environment variables
  • Docker Compose
  • Multi-container applications
Docker Compose was particularly useful for understanding how multiple services communicate.
For example, a typical application could contain:
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──────────────┐
│ Frontend │
└──────┬───────┘
│
▼
┌──────────────┐
│ Backend │
└──────┬───────┘
│
▼
┌──────────────┐
│ Database │
└──────────────┘
Running these services together locally helped me understand concepts that later became important in Kubernetes.

Moving Toward AWS

After becoming comfortable with containers, I wanted to understand how these applications could run in the cloud.
AWS became an important part of my learning.
I started understanding services such as:
  • Amazon EC2
  • Amazon VPC
  • IAM
  • Amazon S3
  • Amazon ECR
  • Amazon EKS
  • CloudWatch
One of the biggest lessons for me was that AWS is not simply about launching an EC2 instance.
Networking, IAM, security, scalability, monitoring, and automation are equally important.
For example, before an application can communicate properly inside AWS, I need to understand concepts such as VPCs, subnets, route tables, security groups, and network connectivity.
That made networking knowledge much more valuable than I initially expected.

From Docker to Kubernetes

As applications become larger, manually managing containers becomes difficult.
This is where Kubernetes becomes useful.
Instead of manually starting containers and checking whether they are running, Kubernetes can manage workloads and maintain the desired state.
I started learning concepts such as:
  • Pods
  • Deployments
  • Services
  • ConfigMaps
  • Secrets
  • StatefulSets
  • Probes
  • Namespaces
  • Ingress/Gateway concepts
One concept that helped me understand Kubernetes better was the idea of desired state.
For example, if I define:
1
replicas: 3
I am telling Kubernetes that I want three replicas of the workload.
If one Pod fails, Kubernetes controllers can work toward bringing the system back to the desired state.
This is very different from manually managing individual containers.

Understanding Health Checks

Another important lesson was understanding the difference between application health and application readiness.
Kubernetes provides probes such as:
  • Liveness probe
  • Readiness probe
  • Startup probe
A liveness probe helps determine whether a container should be restarted.
A readiness probe determines whether the application is ready to receive traffic.
This distinction is important.
A Pod can be running but not ready.
For example:
1
2
3
4
Pod status: Running
Application: Still starting
Readiness: Failed
Traffic: Not sent
Understanding this helped me see why simply checking whether a Pod is running is not enough to determine whether an application is actually available.

Infrastructure as Code

As my environment became more complex, I also started learning Terraform.
Terraform changed my approach to infrastructure.
Instead of manually creating every AWS resource through the console, infrastructure can be defined as code.
For example:
1
2
3
4
5
6
7
8
9
Terraform configuration
↓
terraform plan
↓
Review changes
↓
terraform apply
↓
AWS infrastructure
The terraform plan step is especially useful because it allows me to review proposed infrastructure changes before applying them.
This introduced me to an important DevOps principle:
Infrastructure should be reproducible and changes should be reviewable.

CI/CD and Automation

The next step was understanding how code moves from a Git repository to a running application.
A simplified CI/CD pipeline can look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Developer
↓
Git Push
↓
CI Pipeline
↓
Build
↓
Test
↓
Security Scanning
↓
Docker Image
↓
Container Registry
↓
Deployment
↓
Kubernetes
GitHub Actions helped me understand how this automation can be implemented.
Instead of manually building and deploying an application after every change, the pipeline can perform these steps automatically.
This is where I started understanding why DevOps is more than just knowing Docker or Kubernetes.
The real value comes from connecting the tools into a reliable workflow.

Observability

Deploying an application is only part of the job.
We also need to know what is happening after deployment.
This led me to observability.
I started exploring:
  • Metrics
  • Logs
  • Traces
  • Prometheus
  • Grafana
  • Loki
  • OpenTelemetry
  • Tempo
A useful mental model is:
1
2
3
Metrics → What is happening?
Logs → What happened?
Traces → Where did the request go?
For example, if an application becomes slow, metrics might show increased latency, logs might reveal an application error, and traces can help identify which service is causing the delay.
This changed how I think about troubleshooting.
Instead of simply restarting a Pod when something fails, I try to understand the actual cause.

What I Learned

The biggest lesson from this journey is that DevOps is not a collection of tools.
It is a way of thinking about software delivery and operations.
Linux helped me understand the underlying system.
Networking helped me understand communication.
Git helped me manage changes.
Docker helped me package applications.
Kubernetes helped me manage workloads.
AWS helped me understand cloud infrastructure.
Terraform helped me automate infrastructure.
CI/CD helped me automate software delivery.
Observability helped me understand what happens after deployment.
The tools are connected.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────┐
│ Git │
└──────┬──────┘
↓
┌─────────────┐
│ CI Pipeline │
└──────┬──────┘
↓
┌─────────────┐
│ Docker │
└──────┬──────┘
↓
┌─────────────┐
│ AWS │
└──────┬──────┘
↓
┌─────────────┐
│ Kubernetes │
└──────┬──────┘
↓
┌─────────────┐
│ Observability│
└─────────────┘

Final Thoughts

I am still learning.
There are many areas of AWS, Kubernetes, networking, security, and infrastructure that I want to explore further.
My next focus is on improving my understanding of production-grade Kubernetes environments, cloud security, infrastructure automation, and observability.
One thing I have learned during this journey is that reading about a technology is only the beginning.
Building something, breaking it, troubleshooting it, and fixing it is where the real learning happens.
For anyone starting their DevOps journey, my advice would be simple:
Don't try to learn every tool at once.
Start with the fundamentals, build small projects, understand why each tool is being used, and gradually connect everything together.
That is how I am continuing my journey toward becoming a DevOps Engineer.
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article