Deploy a Containerized App on EKS

Build, push, and deploy a Docker container to Kubernetes on Amazon EKS.

Introduction

30 Second Summary

Shipping containers revolutionized global trade by packaging goods into a standard format that works on any ship, truck, or crane. Software containers do the same thing for applications, packaging your code so it runs identically on any machine.

In this project, you will build a custom Docker container, push it to a cloud registry, and deploy it to a production-grade Kubernetes cluster on Amazon EKS.

What You'll Build

A custom web application packaged as a Docker container, pushed to Amazon ECR, and deployed to a Kubernetes cluster on Amazon EKS that is publicly accessible via a load balancer.

By the end of this project, you'll have:

  • A custom Docker image stored in Amazon ECR.
  • An EKS cluster with 2 worker nodes running your application.
  • A Kubernetes Deployment managing 3 replicas of your container, exposed to the internet through an AWS Load Balancer.
  • Secret Mission: Scale your deployment and perform a zero-downtime rolling update with a new image version.

Are there any prerequisites?

This project assumes you already have an AWS account with admin permissions, Docker, AWS CLI, eksctl, and kubectl installed on your machine. Step 1 will verify everything is working correctly before you build anything.

Verify Your Tools and Configure AWS

Deploying containers to Amazon EKS requires several tools working together. Before building anything, you need to confirm that each tool is installed, accessible, and properly configured.

In this step, you will verify all four CLI tools, configure your AWS credentials, confirm Docker is running, and create a project directory.

In this step, get ready to:
  • Confirm all four tools are installed and responding.
  • Configure AWS CLI with valid credentials.
  • Create a project directory for your container files.
Verify your tool installations

You need four tools for this project: docker to build container images, aws to interact with AWS services, eksctl to create EKS clusters, and kubectl to manage Kubernetes resources.

  • Confirm all four tools are accessible by running these commands one at a time:
docker --version
aws --version
eksctl version
kubectl version --client

What should I see?

Each command should print a version number. For example, docker --version prints something like Docker version 27.x.x. The exact version numbers will vary based on your installations.

For eksctl, you need version 0.215.0 or later. If your version is older, update eksctl before proceeding.

Command not found?

If any command returns "command not found", the tool is either not installed or not on your system PATH. Revisit the installation instructions for that tool and make sure you followed the steps for your operating system.

help me troubleshoot why one of my CLI tools is not found when I run it in the terminal

Now confirm your AWS CLI is configured with valid credentials.

  • Check your AWS identity by running:
aws sts get-caller-identity

✔️ I see my account details

You should see JSON output with your UserId, Account, and Arn fields. Your AWS CLI is ready to go.

ⓧ I see an error

If you see an error about credentials or tokens, your AWS CLI is not configured yet. This is expected if you have not set up credentials before.

  • Configure your credentials by running:
aws configure

The command prompts you for four values. Enter them one at a time:

  • Enter your Access Key ID when prompted.
  • Enter your Secret Access Key when prompted.
  • Enter us-east-1 for the default region.
  • Enter json for the output format.

Where do I find my Access Key ID and Secret Access Key?

These credentials come from your AWS IAM user. In the AWS Console, go to IAM > Users > your user > Security credentials tab. You can create a new access key there if you do not have one.

  • After configuring, verify it worked by running:
aws sts get-caller-identity

You should now see JSON output with your Account ID, UserId, and Arn.

Verify Docker is running

Having Docker installed is not enough. The Docker daemon must be actively running for you to build and run containers.

  • Confirm the Docker daemon is active by running:
docker info

✔️ I see system information

If you see details about your Docker installation (server version, storage driver, number of containers), Docker is running and ready.

ⓧ Cannot connect to the Docker daemon

If you see an error like "Cannot connect to the Docker daemon", Docker is installed but not running.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Docker Desktop and press Enter to open it.
  • Wait for Docker Desktop to finish starting. You will see the whale icon in your menu bar (macOS) or system tray (Windows) turn solid.
  • Run docker info again to confirm it is now working.
Create a project directory

You need a dedicated folder to hold your application files, Dockerfile, and Kubernetes manifests.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir eks-demo
cd eks-demo
  • Confirm you are in the new folder by running:
ls

The output should be empty since you have not created any files yet. Your terminal prompt should also show eks-demo as the current directory.

Directory not found?

If cd ~/Desktop fails, your system may use a different path for the Desktop. On some Linux distributions, try cd ~/desktop (lowercase). Alternatively, use any location you prefer and adjust the path accordingly.

help me find my Desktop directory path on my operating system

Your environment is ready. All tools are verified, AWS is configured, and you have a clean project directory. Next up, you will build a Docker container with a custom web page inside it.

Build a Docker Container

Your tools are verified and your AWS credentials are ready. Now it's time to create something to deploy.

In this step, you'll build a custom web page and package it inside a Docker container. This container becomes the portable unit you'll eventually ship to your Kubernetes cluster on Amazon EKS.

In this step, get ready to:
  • Create a custom web page and a Dockerfile to package it.
  • Build a Docker image and run it locally.
  • Verify the app works in your browser before shipping it to the cloud.
Create the application files

Every Docker container starts with application code and a Dockerfile that tells Docker how to package it. You'll create a simple HTML page and then write the instructions Docker needs to bundle it into a portable image.

  • In your code editor, create a new file called index.html inside your eks-demo folder.
  • Paste the following code into index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EKS Demo App</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            text-align: center;
            padding: 2rem;
        }
        h1 {
            font-size: 2.5rem;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.2rem;
            opacity: 0.9;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Hello from EKS!</h1>
        <p>This app is running in a Docker container on Amazon EKS.</p>
        <p>Version: 1.0</p>
    </div>
</body>
</html>

What does this code do?

This is a simple HTML page with inline CSS styling. It displays a heading, a description, and a version number against a purple gradient background.

The version number is important. Later in the Secret Mission, you'll update it to 2.0 and perform a rolling deployment.

  • Save index.html.

You won't see a change yet. The next file (your Dockerfile) tells Docker how to serve this page.

✔️ Awesome, I've got everything!

Great. Double check you've saved your file.

ⓧ I'd like to double check the full code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EKS Demo App</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            text-align: center;
            padding: 2rem;
        }
        h1 {
            font-size: 2.5rem;
            margin-bottom: 1rem;
        }
        p {
            font-size: 1.2rem;
            opacity: 0.9;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Hello from EKS!</h1>
        <p>This app is running in a Docker container on Amazon EKS.</p>
        <p>Version: 1.0</p>
    </div>
</body>
</html>
  • Create another new file in the same eks-demo folder called Dockerfile (no file extension).
  • Paste the following code into your Dockerfile:
# Use the official nginx image from Amazon ECR Public Gallery
FROM public.ecr.aws/nginx/nginx:1.27
# Copy your web page into the container's default serving directory
COPY index.html /usr/share/nginx/html/index.html
# Document that the container listens on port 80
EXPOSE 80

What does this Dockerfile do?

  • FROM public.ecr.aws/nginx/nginx:1.27 starts from the official nginx web server image hosted on Amazon's public container registry. This avoids Docker Hub rate-limiting issues.
  • COPY index.html /usr/share/nginx/html/index.html places your HTML file where nginx expects to serve content from.
  • EXPOSE 80 documents that the container listens on port 80 (the standard HTTP port).
  • Save Dockerfile.
  • Confirm both files exist by running:
ls

You should see Dockerfile and index.html listed in the output.

Don't see both files?

  • Make sure you saved both files inside the eks-demo folder, not a parent or child directory.
  • Check that your Dockerfile has no extension. It should be Dockerfile not Dockerfile.txt.
  • Confirm your terminal is inside the eks-demo directory by running pwd.

Why aren't my project files showing up in the right directory?

✔️ Awesome, I've got everything!

Great. Double check you've saved your Dockerfile.

ⓧ I'd like to double check the full code

FROM public.ecr.aws/nginx/nginx:1.27
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
Build and test the container locally

With your application files ready, it's time to build a Docker image. An image is a snapshot of your app and all its dependencies, frozen into a single portable package.

  • Build the Docker image by running this command:
docker build -t eks-demo-app:v1 .

What does this command do?

  • docker build reads your Dockerfile and creates an image from it.
  • -t eks-demo-app:v1 tags the image with a name (eks-demo-app) and version (v1).
  • The . at the end tells Docker to look for the Dockerfile in the current directory.

The build should complete in a few seconds. You'll see Docker pull the nginx base image and then copy your HTML file into it.

Seeing a build error?

  • If you see a "no such file" error, make sure your terminal is inside the eks-demo folder where your Dockerfile lives.
  • If Docker can't pull the base image, check your internet connection. The first build downloads the nginx image (about 70 MB).
  • If you see "Cannot connect to the Docker daemon", make sure Docker Desktop is running.

Why is my Docker build failing?

  • Run the container locally to test it:
docker run -d -p 8080:80 eks-demo-app:v1

What does this command do?

  • -d runs the container in detached mode (in the background).
  • -p 8080:80 maps port 8080 on your machine to port 80 inside the container. This means requests to localhost:8080 reach the nginx server in your container.
  • Open your browser and navigate to http://localhost:8080.

You should see your custom web page with a purple gradient background, the heading "Hello from EKS!" and "Version: 1.0" at the bottom.

Page not loading at localhost:8080?

  • If you see "This site can't be reached", wait a few seconds and refresh. The container may still be starting.
  • If port 8080 is already in use, stop whatever is using it or change 8080 to another port like 8081 in the command.
  • Run docker ps to confirm the container is actually running. If it's not listed, it may have exited immediately due to an error in your Dockerfile.

Why isn't my Docker container serving the page at localhost:8080?

  • Stop the running container by running this command:
docker stop $(docker ps -q --filter ancestor=eks-demo-app:v1)

What does this command do?

The inner command docker ps -q --filter ancestor=eks-demo-app:v1 finds the container ID running your image. The outer docker stop gracefully shuts it down. You stop it now because you'll soon push this image to the cloud instead of running it locally.

Your Docker image is built, tested, and ready to ship. Next up, you'll push it to Amazon ECR so your Kubernetes cluster can pull it from a cloud registry.

Push to Amazon ECR

Your Docker image is built and tested locally. Now you need to store it somewhere your future Kubernetes cluster can pull it from.

Amazon Elastic Container Registry (ECR) is AWS's managed container registry. Think of it as a private storage vault for your Docker images. In this step, you'll create a repository in ECR and push your image to it.

In this step, get ready to:
  • Create an ECR repository to store your container image.
  • Authenticate Docker with ECR, tag your image, and push it to the cloud.
Create an ECR repository

Before you can push an image, you need a repository in ECR to hold it. Each repository stores images for a single application.

  • Create your ECR repository by running this command:
aws ecr create-repository --repository-name eks-demo-app --region us-east-1

What does this command do?

This creates a new private container image repository called eks-demo-app in the us-east-1 region. It's where your Docker image will live in the cloud.

  • Look for the repositoryUri value in the JSON output. It follows this format:
[[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/eks-demo-app
  • Copy this URI and save it somewhere handy. You'll use it in the next commands.

Find your account ID

Your 12-digit AWS account ID is the number at the start of the repositoryUri. You can also find it by running aws sts get-caller-identity and looking at the Account field.

Getting an access denied error?

Make sure your AWS CLI credentials have permissions to create ECR repositories. If you used an admin IAM user in Step 1, this should work without issues.

help me fix ECR access denied errors

Authenticate, tag, and push your image

ECR is a private registry, so Docker needs permission to push images to it. You'll authenticate Docker with ECR, tag your local image with the full ECR URI, then push it.

  • Authenticate Docker to your ECR registry by running this command:
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin [[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com

What does this command do?

This command has two parts joined by a pipe (|). The first part fetches a temporary authentication token from AWS. The second part passes that token to Docker so it can push images to your private registry.

The token is valid for 12 hours, so you won't need to re-authenticate during this project.

  • You should see Login Succeeded in your terminal output.

Login failed or connection refused?

Make sure Docker Desktop is still running. The Docker daemon must be active for this command to work.

Double check that you replaced the account ID placeholder with your actual 12-digit AWS account ID.

help me fix Docker ECR login issues

  • Tag your local image with the full ECR repository URI by running:
docker tag eks-demo-app:v1 [[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/eks-demo-app:v1

Why do I need to tag the image?

Docker uses the image name to determine where to push it. By tagging your image with the full ECR URI, you're telling Docker exactly which registry and repository to push to.

  • Push the tagged image to ECR by running:
docker push [[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/eks-demo-app:v1

You'll see progress bars as each layer of your image uploads. This may take a minute depending on your internet speed.

  • Verify the image is in ECR by running:
aws ecr list-images --repository-name eks-demo-app --region us-east-1
  • You should see a JSON response containing an imageIds array with your image tag v1 listed.

Push failed or image not showing up?

If the push failed with an authorization error, your login token may have expired. Re-run the authenticate command above and try the push again.

If the push succeeded but list-images shows nothing, make sure the --repository-name matches exactly: eks-demo-app.

help me troubleshoot my ECR push

Your container image is now stored securely in the cloud. Next up, you'll create a Kubernetes cluster on Amazon EKS to run it.

Create an EKS Cluster

Your container image is stored in ECR, ready to be pulled and run. Now you need the infrastructure to actually run it at scale.

Amazon EKS (Elastic Kubernetes Service) is AWS's managed Kubernetes service. You'll use a tool called eksctl to create your cluster with a single command, instead of manually configuring networking, IAM roles, and compute resources one by one.

In this step, get ready to:
  • Create a cluster configuration file.
  • Launch an EKS cluster using eksctl.
  • Verify your worker nodes are running and healthy.
Create the cluster with eksctl

Instead of passing dozens of flags to a CLI command, eksctl lets you define your cluster in a YAML configuration file. This makes your cluster setup repeatable and version-controllable.

  • Create a file named cluster.yaml in your eks-demo folder with the following content:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-demo
  region: us-east-1

managedNodeGroups:
  - name: ng-1
    instanceType: t3.small
    desiredCapacity: 2
    minSize: 1
    maxSize: 3

What does this configuration do?

  • apiVersion and kind tell eksctl this is a cluster configuration file using its schema format.
  • metadata sets your cluster name to eks-demo and places it in the us-east-1 region.
  • managedNodeGroups defines the worker machines. You're requesting 2 t3.small EC2 instances that can scale between 1 and 3 nodes. AWS manages patching and lifecycle for managed node groups automatically.

Why t3.small instead of the default?

The default eksctl instance type is m5.large, which costs $0.096/hr per node. A t3.small at $0.0209/hr is more than sufficient for a demo nginx container and keeps your total project cost well under $2.

  • Save cluster.yaml.
  • Confirm the file exists by running:
ls cluster.yaml

You should see cluster.yaml in the output.

Don't see cluster.yaml?

  • Make sure you saved the file in the eks-demo directory, not a parent or nested folder.
  • Check that the filename is exactly cluster.yaml with no extra extension like .txt.

Why isn't my cluster.yaml file showing up?

✔️ Awesome, I've got everything!

Great. Double check you've saved cluster.yaml and let's create the cluster.

ⓧ I'd like to double check the full code

Here is the complete cluster.yaml file:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eks-demo
  region: us-east-1

managedNodeGroups:
  - name: ng-1
    instanceType: t3.small
    desiredCapacity: 2
    minSize: 1
    maxSize: 3
  • Launch the cluster by running this command:
eksctl create cluster -f cluster.yaml

What does this command do?

This single command triggers a massive amount of work behind the scenes. eksctl creates a VPC with public and private subnets, security groups, IAM roles for the control plane and nodes, the EKS control plane itself, and your worker nodes.

Without eksctl, you would need to configure each of these resources manually. That's 20+ steps in the AWS Console.

This takes 15-20 minutes

Cluster creation typically takes 15-20 minutes. This is normal. eksctl provisions real cloud infrastructure including networking, compute, and control plane components. You'll see progress updates in your terminal as each resource is created.

Do not close your terminal or interrupt the process. Grab a coffee and come back when you see the success message.

When the command finishes, you should see a message confirming your cluster is ready. eksctl also automatically configures your kubectl context to point at your new cluster.

Seeing an error during cluster creation?

  • If you see a permissions error, confirm your AWS CLI credentials have admin access by running aws sts get-caller-identity.
  • If eksctl reports a version error, make sure you have eksctl version 0.215.0 or later installed.
  • If you hit a service quota limit (e.g., VPC or EC2 instance limits), you may need to request a quota increase in the AWS Console under Service Quotas.

Help me troubleshoot my eksctl cluster creation error.

Verify the cluster

Once eksctl finishes, you need to confirm that your worker nodes are online and ready to accept workloads.

  • Check that your nodes are running by running this command:
kubectl get nodes

You should see 2 nodes listed, both with a STATUS of Ready. This means your EC2 instances have joined the cluster and can run containers.

  • Confirm the default Kubernetes namespaces exist by running:
kubectl get namespaces

You should see four namespaces: default, kube-node-lease, kube-public, and kube-system. These are created automatically on every Kubernetes cluster.

What are Kubernetes namespaces?

Namespaces are a way to divide a single cluster into isolated sections. The default namespace is where your app will be deployed. The kube-system namespace holds Kubernetes internal components like DNS and the API server.

kubectl get nodes shows no nodes or NotReady?

  • If you see no nodes at all, your kubectl context may not be pointing at the right cluster. Run aws eks update-kubeconfig --name eks-demo --region us-east-1 to reconfigure it.
  • If nodes show NotReady, wait 1-2 minutes. Nodes sometimes need extra time to initialize after eksctl reports completion.

Help me fix my kubectl connection to my EKS cluster.

Your EKS cluster is live with two healthy worker nodes. Next up, you'll deploy your container image from ECR onto this cluster and expose it to the internet.

Deploy to Kubernetes

Your EKS cluster is running with 2 healthy worker nodes. Now it is time to tell Kubernetes what to run on those nodes.

Kubernetes uses YAML configuration files called manifests to describe your desired state. You will create two manifests: a Deployment (which tells Kubernetes how many copies of your container to run) and a Service (which exposes those containers to the internet through a Load Balancer).

In this step, get ready to:
  • Create Kubernetes manifest files for your Deployment and Service.
  • Apply the manifests to your EKS cluster.
  • Access your application via a public load balancer URL.
Create Kubernetes manifests

Kubernetes manifests are YAML files that describe what you want running in your cluster. You will create two files: one for the Deployment (your running containers) and one for the Service (how traffic reaches them).

  • Create a file called deployment.yaml in your eks-demo folder with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: eks-demo-deployment
  labels:
    app: eks-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: eks-demo
  template:
    metadata:
      labels:
        app: eks-demo
    spec:
      containers:
        - name: eks-demo
          image: [[ACCOUNT_ID="your AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/eks-demo-app:v1
          ports:
            - containerPort: 80

What does this manifest do?

This Deployment tells Kubernetes to run 3 copies (replicas) of your container. Each replica is called a pod.

  • replicas: 3 ensures 3 pods run at all times. If one crashes, Kubernetes automatically replaces it.
  • selector and labels connect the Deployment to its pods using the label app: eks-demo.
  • The image field points to your container image in ECR. Replace the account ID with your own (from aws sts get-caller-identity).
  • Save deployment.yaml.

Not sure what your account ID is?

Run aws sts get-caller-identity in your terminal. The 12-digit number in the Account field is your AWS account ID. Use it in the image line of deployment.yaml.

Help me find my AWS account ID for the deployment manifest.

✔️ Awesome, I've got everything!

Great. Double check you have saved deployment.yaml in your eks-demo folder.

ⓧ I'd like to double check the full code

apiVersion: apps/v1
kind: Deployment
metadata:
  name: eks-demo-deployment
  labels:
    app: eks-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: eks-demo
  template:
    metadata:
      labels:
        app: eks-demo
    spec:
      containers:
        - name: eks-demo
          image: [[ACCOUNT_ID="your AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/eks-demo-app:v1
          ports:
            - containerPort: 80
  • Create a second file called service.yaml in your eks-demo folder with the following content:
apiVersion: v1
kind: Service
metadata:
  name: eks-demo-service
spec:
  type: LoadBalancer
  selector:
    app: eks-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

What does this Service do?

A Kubernetes Service gives your pods a stable network address. The type: LoadBalancer setting tells AWS to create an Elastic Load Balancer that routes internet traffic to your pods.

The selector field matches the app: eks-demo label on your pods. This is how the Service knows which pods to send traffic to.

  • Save service.yaml.
  • Confirm both files exist by running:
ls

You should see deployment.yaml and service.yaml alongside your existing files (index.html, Dockerfile, cluster.yaml).

Don't see both files?

Make sure you saved each file in the eks-demo directory, not a subdirectory or your home folder. Check that you are in the correct directory by running pwd.

Help me find where my YAML files were saved.

✔️ Awesome, I've got everything!

Great. Double check you have saved service.yaml in your eks-demo folder.

ⓧ I'd like to double check the full code

apiVersion: v1
kind: Service
metadata:
  name: eks-demo-service
spec:
  type: LoadBalancer
  selector:
    app: eks-demo
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
Apply the manifests

With your manifests written, you can now submit them to your cluster. Kubernetes reads the YAML and creates the resources you described.

  • Deploy your application by running:
kubectl apply -f deployment.yaml
  • You should see output confirming the Deployment was created.
  • Create the LoadBalancer Service by running:
kubectl apply -f service.yaml
  • You should see output confirming the Service was created.
  • Verify your 3 pods are running by running:
kubectl get pods

You should see 3 pods with STATUS showing Running and READY showing 1/1. It may take 30-60 seconds for all pods to reach Running status.

  • Check the Service and get your load balancer URL by running:
kubectl get service eks-demo-service

Look at the EXTERNAL-IP column. It may show <pending> at first while AWS provisions the load balancer. Wait 2-3 minutes and run the command again until a URL appears.

Why is EXTERNAL-IP pending?

When you create a LoadBalancer Service on EKS, AWS needs to provision a Classic Load Balancer in the background. This takes 2-3 minutes. Once ready, the EXTERNAL-IP column updates to show the load balancer hostname (a long URL ending in .amazonaws.com).

Pods not reaching Running status?

If your pods show ImagePullBackOff or ErrImagePull, the cluster cannot pull your image from ECR. Check that the image field in deployment.yaml has your correct 12-digit account ID and the region matches us-east-1.

Help me debug why my pods cannot pull the container image from ECR.

Access your application

Once the EXTERNAL-IP is no longer pending, your application is live on the internet.

  • Run the command again to see your load balancer URL:
kubectl get service eks-demo-service
  • Copy the full EXTERNAL-IP value from the output (it looks like a long hostname ending in .amazonaws.com).
  • Paste the URL into your browser's address bar and press Enter.

You should see your custom web page with the purple gradient background, the heading "Hello from EKS!", and the version number. This page is now accessible from anywhere on the internet.

What just happened?

Traffic flows from your browser to the AWS Load Balancer, which distributes it across your 3 pods running on the EKS worker nodes. Each pod runs your nginx container with your custom HTML page. If one pod fails, Kubernetes automatically restarts it and the load balancer routes around it.

Page not loading in the browser?

Make sure you are using http:// (not https://) when pasting the URL. The Service only exposes port 80 (HTTP). Also, the load balancer can take up to 5 minutes to become fully healthy after the EXTERNAL-IP appears.

Help me troubleshoot why my EKS load balancer URL is not loading in the browser.

Your containerized app is now running in production on Amazon EKS. You have a fully automated setup: if a pod crashes, Kubernetes replaces it. If traffic spikes, the load balancer distributes it. Next up, you will take on the Secret Mission and perform a zero-downtime rolling update.

Secret mission

Scale and Rolling Update

Your app is running. But in real production, you need more copies for reliability and the ability to ship updates without downtime. Can you scale your deployment and push a new version with zero-downtime rolling updates?

Clean Up Your Resources

Clean Up Your Resources

This project uses cloud resources that cost money while they remain running. Decide whether to keep your resources, pause them, or delete them entirely.

Cost warning

Your EKS cluster costs approximately $0.21/hr while running. That breaks down to $0.10/hr for the EKS control plane, ~$0.04/hr for the two t3.small nodes, and $0.045/hr for the NAT Gateway. Left overnight, you could accumulate ~$5/day in charges.

Deleting everything is strongly recommended once you have finished the project.

Resources you used:

  • EKS cluster eks-demo (includes VPC, subnets, NAT Gateway, and 2 t3.small worker nodes).
  • Classic Load Balancer (created by the Kubernetes LoadBalancer Service).
  • ECR repository eks-demo-app (stores your container images tagged v1 and v2).
  • Local project folder eks-demo on your Desktop.

Keep everything running

No action needed. Choose this if you plan to continue building on this cluster immediately.

  • Your EKS cluster, load balancer, and ECR repository remain active.
  • Costs accumulate at approximately $5/day while the cluster runs.
  • Your application remains accessible at the same load balancer URL.

Pause - I'll come back to this later

EKS clusters cannot be truly paused. The control plane continues to charge $0.10/hr even with zero worker nodes. For a learning project, the most practical approach is to delete the cluster but keep your ECR images and local files so you can redeploy quickly later.

  • Delete the Kubernetes service (removes the load balancer) by running:
  • Delete the cluster and all associated AWS resources by running:
kubectl delete -f service.yaml
eksctl delete cluster -f cluster.yaml

Wait 5-10 minutes for eksctl to confirm deletion.

  • Keep your ECR repository (storage cost is negligible for a few images).
  • Keep your local eks-demo folder with all project files intact.
  • When you are ready to return, recreate the cluster with eksctl create cluster -f cluster.yaml and reapply your manifests.

Delete - I don't want to use this again

Remove all project resources completely. This is recommended for a learning project you have finished.

  • Delete the Kubernetes service first (this cleanly removes the load balancer) by running:
kubectl delete -f service.yaml
  • Delete the EKS cluster and all associated AWS resources (VPC, subnets, NAT Gateway, nodes) by running:
eksctl delete cluster -f cluster.yaml

Wait 5-10 minutes for eksctl to confirm the cluster has been fully deleted.

  • Delete the ECR repository and all stored images by running:
aws ecr delete-repository --repository-name eks-demo-app --region us-east-1 --force
  • Delete your local project folder by running:

macOS

cd ~/Desktop
rm -rf eks-demo

Windows

cd ~\Desktop
rmdir /s /q eks-demo
  • Confirm all resources are gone by running:
aws ecr describe-repositories --region us-east-1 --query "repositories[?repositoryName=='eks-demo-app']"

You should see an empty list, confirming the repository no longer exists.

That's a Wrap!

That's a Wrap!

Nice work! You just built, shipped, and deployed a containerized web application on Amazon EKS.

You've learned how to:

  • Built a custom Docker container image and pushed it to Amazon ECR as your private container registry.
  • Created a production-grade Kubernetes cluster on Amazon EKS using eksctl with managed node groups.
  • Deployed your application using Kubernetes Deployments and exposed it to the internet through an AWS Load Balancer.
  • Secret Mission: Scaled your deployment to 5 replicas and performed a zero-downtime rolling update with a new image version.

Ready to quiz yourself?