Deploy a Docker Container with ECS

Build and deploy a containerized web app to AWS using ECS Express Mode.

Introduction

30 Second Summary

Every app you use online runs on a server somewhere in the world. Getting your own code from your laptop to one of those servers is one of the most valuable skills in tech.

In this project, you will build a Docker container with a simple web app inside, push it to AWS's container registry, and deploy it live to the internet using ECS Express Mode.

What You'll Build

You'll containerize a web application using Docker and deploy it to AWS with a single command using ECS Express Mode, AWS's newest and simplest container deployment service.

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

  • A Docker image built from a custom Dockerfile, tested locally on your machine.
  • A private Amazon ECR repository storing your container image in the cloud.
  • A live web application running on ECS Express Mode with automatic HTTPS, load balancing, and auto-scaling.
  • Secret Mission: Customize your container to serve a dynamic app with environment variables and a custom health check endpoint.

Are there any prerequisites?

You'll need an AWS account to complete this project. A free tier account works, but note that Fargate (the compute engine behind ECS Express Mode) is not part of the AWS free tier. The total cost for this project is approximately $0.05 to $0.10, and full cleanup instructions are included so you won't be charged after you're done.

Set Up Your Tools

Before you can deploy a container to AWS, you need two tools installed on your machine.

Docker lets you build and run containers locally. The AWS CLI lets you talk to AWS services from your terminal. Together, they form the bridge between your laptop and the cloud.

In this step, get ready to:
  • Install Docker Desktop and confirm it's running.
  • Install and configure the AWS CLI with your credentials.
  • Verify both tools can communicate with AWS.
Install Docker Desktop

Docker Desktop is a desktop application that runs the Docker engine on your Mac. It handles the Linux virtual machine that containers need under the hood.

  • Open your browser and go to the Docker Desktop download page:

https://www.docker.com/products/docker-desktop/

  • Click the download button for your Mac (Apple chip or Intel chip).
  • Double-click the downloaded Docker.dmg file to open the installer.
  • Drag the Docker icon to the Applications folder.
  • Open Docker Desktop by double-clicking Docker.app in your Applications folder.
  • Accept the Docker Subscription Service Agreement when prompted.
  • Wait for Docker Desktop to finish starting up. You'll see the Docker whale icon appear in your menu bar at the top of the screen.

What is Docker Desktop?

Docker Desktop bundles everything you need to build and run containers on macOS. It includes the Docker engine, the docker CLI, and a lightweight Linux VM where your containers actually run.

Now let's confirm Docker is working. Check the installed version by running this command in your terminal:

  • Press Cmd+Space to open Spotlight Search.
  • Type Terminal and press Enter to open it.
  • Check Docker's version by running:
docker --version

✔️ I see a version number

Docker is installed and working. You should see output like Docker version 27.x.x or similar.

ⓧ Command not found

Docker Desktop isn't running or wasn't installed correctly.

  • Check that Docker Desktop is open and fully started. Look for the whale icon in your menu bar.
  • If you don't see the whale icon, open Docker Desktop from your Applications folder and wait for it to finish loading.
  • Try running docker --version again after the whale icon appears.
  • Confirm the Docker daemon is fully running by running:
docker info

What does this command do?

The docker info command shows detailed information about your Docker installation, including the number of containers and images, the storage driver, and the operating system. If it returns without errors, the Docker daemon is healthy.

Seeing an error about the Docker daemon?

If you see a message about the Docker daemon not running, give Docker Desktop another minute to start up. The first launch can take a while as macOS performs security checks.

help me troubleshoot Docker Desktop not starting on my Mac

Install and configure the AWS CLI

The AWS CLI is a command-line tool that lets you create, manage, and delete AWS resources directly from your terminal.

  • Download the AWS CLI v2 installer for macOS by opening this link in your browser:

https://awscli.amazonaws.com/AWSCLIV2.pkg

  • Double-click the downloaded AWSCLIV2.pkg file to run the installer.
  • Follow the on-screen prompts. Select Continue through each step and Install when prompted.
  • Enter your Mac password when macOS asks for permission.
  • Click Close when the installer finishes.

Verify the installation by running this in your terminal:

  • Check the AWS CLI version by running:
aws --version

✔️ I see aws-cli/2.x.x

AWS CLI v2 is installed. The output starts with aws-cli/2. followed by version numbers. You're good to continue.

ⓧ I see aws-cli/1.x.x

You have an older version of the AWS CLI installed. This project requires version 2.

  • Download and install the v2 package from the link above. The installer will replace version 1 automatically.
  • Close your terminal, open a new one, and run aws --version again. You should now see aws-cli/2. in the output.

ⓧ Command not found

The AWS CLI is not installed yet.

Now you need to configure the AWS CLI with your credentials so it can access your AWS account.

  • Run the configuration wizard by running:
aws configure

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

In the AWS Management Console, go to IAM and select your user. Under the Security credentials tab, click Create access key. Copy both the Access Key ID and Secret Access Key that appear.

Store your Secret Access Key somewhere safe. AWS only shows it once at creation time.

  • The CLI prompts you for four values. Enter them one at a time, pressing Enter after each:
  • AWS Access Key ID: paste your Access Key ID.
  • AWS Secret Access Key: paste your Secret Access Key.
  • Default region name: type us-east-1 and press Enter.
  • Default output format: type json and press Enter.

Verify your credentials are working by running:

  • Confirm the CLI can reach your AWS account by running:
aws sts get-caller-identity

You should see JSON output containing your account ID, user ARN, and user ID.

Seeing an access denied or credentials error?

Make sure you pasted the Access Key ID and Secret Access Key correctly. Run aws configure again to re-enter them.

Also confirm your IAM user has permissions for ECR, ECS, and IAM. An account with AdministratorAccess will work for this project.

help me fix my AWS CLI credentials or permissions error

Verify both tools work together

Let's do a final check to make sure Docker and the AWS CLI are both ready for the deployment steps ahead.

  • Confirm Docker can list containers by running:
docker ps

You should see an empty table with column headers like CONTAINER ID and IMAGE. This means Docker is running and ready to manage containers.

  • Confirm the AWS CLI can reach Amazon ECR by running:
aws ecr describe-repositories --region us-east-1

What does this command do?

This command asks AWS to list all private container image repositories in your account. If you haven't created any yet, you'll see an empty repositories array. That's perfectly fine. The important thing is that the command succeeds without an error.

You should see output like {"repositories": []} or a list of any existing repositories. Both results confirm your setup is working.

Getting an AccessDeniedException?

Your IAM user may not have ECR permissions. Attach the AmazonEC2ContainerRegistryFullAccess policy to your user in the IAM console, or use a user with AdministratorAccess.

help me fix ECR permissions for my IAM user

Your tools are ready to go. Next up, you'll build your first Docker image with a custom web page inside it.

Build Your Docker Image

Your tools are ready. Now it's time to create the actual application you'll deploy to AWS.

In this step, you'll write a Dockerfile that packages a simple web page into a Docker image. Then you'll build and test it locally to make sure everything works before pushing it to the cloud.

In this step, get ready to:
  • Create a project folder and write a Dockerfile.
  • Build a Docker image from the Dockerfile.
  • Test the container locally in your browser.
Create your project files

Every Docker project starts with a Dockerfile. This is a text file that tells Docker exactly how to build your image, step by step.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir hello-aws
cd hello-aws
  • Confirm the folder was created by running:
ls

You should see the hello-aws folder listed in the output. Since you already moved into it, your terminal prompt should also show hello-aws as your current directory.

  • Create your Dockerfile by running this command:
cat > Dockerfile << 'EOF'
FROM public.ecr.aws/amazonlinux/amazonlinux:latest

# Install dependencies
RUN yum update -y && \
    yum install -y httpd

# Create the web page
RUN echo '<html><head><title>Hello from Docker on AWS!</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;text-align:center;}.container{background:rgba(255,255,255,0.1);padding:3rem;border-radius:1rem;backdrop-filter:blur(10px);}</style></head><body><div class="container"><h1>Hello from Docker on AWS!</h1><p>This page is served from a Docker container running on Amazon ECS Express Mode.</p><p>Deployed with Fargate, load-balanced, auto-scaled, and HTTPS-secured.</p></div></body></html>' > /var/www/html/index.html

# Configure apache
RUN echo 'mkdir -p /var/run/httpd' >> /root/run_apache.sh && \
    echo 'mkdir -p /var/lock/httpd' >> /root/run_apache.sh && \
    echo '/usr/sbin/httpd -D FOREGROUND' >> /root/run_apache.sh && \
    chmod 755 /root/run_apache.sh

EXPOSE 80

CMD /root/run_apache.sh
EOF

What does this Dockerfile do?

  • FROM pulls the Amazon Linux base image from the public AWS registry. This is the same operating system that runs on many AWS services.
  • RUN yum install -y httpd installs Apache (the httpd web server) inside the image.
  • The second RUN creates an HTML page at /var/www/html/index.html. This is what visitors will see when they access your app.
  • The third RUN creates a startup script that launches Apache in the foreground. Running in the foreground keeps the container alive.
  • EXPOSE 80 documents that the container listens on port 80.
  • CMD tells Docker what command to run when the container starts.
  • Confirm the Dockerfile was created by running:
ls

You should see Dockerfile listed in the output.

Don't see the Dockerfile?

Make sure you ran the full cat command including the EOF line at the end. If your terminal is still waiting for input (showing >), the heredoc didn't close properly. Press Ctrl+C and try pasting the full command again.

Also confirm you're inside the hello-aws folder by running pwd. You should see a path ending in /hello-aws.

Help me troubleshoot my Dockerfile creation

✔️ Awesome, I've got everything!

Great. Double check you can see Dockerfile when you run ls in your hello-aws folder.

ⓧ I'd like to double check the full code

Your Dockerfile should look exactly like this:

FROM public.ecr.aws/amazonlinux/amazonlinux:latest

# Install dependencies
RUN yum update -y && \
    yum install -y httpd

# Create the web page
RUN echo '<html><head><title>Hello from Docker on AWS!</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;text-align:center;}.container{background:rgba(255,255,255,0.1);padding:3rem;border-radius:1rem;backdrop-filter:blur(10px);}</style></head><body><div class="container"><h1>Hello from Docker on AWS!</h1><p>This page is served from a Docker container running on Amazon ECS Express Mode.</p><p>Deployed with Fargate, load-balanced, auto-scaled, and HTTPS-secured.</p></div></body></html>' > /var/www/html/index.html

# Configure apache
RUN echo 'mkdir -p /var/run/httpd' >> /root/run_apache.sh && \
    echo 'mkdir -p /var/lock/httpd' >> /root/run_apache.sh && \
    echo '/usr/sbin/httpd -D FOREGROUND' >> /root/run_apache.sh && \
    chmod 755 /root/run_apache.sh

EXPOSE 80

CMD /root/run_apache.sh

You can view your file's contents by running cat Dockerfile in your terminal and comparing.

Build the Docker image

A Dockerfile is just a recipe. To turn it into something Docker can actually run, you need to build it into an image.

  • Build your Docker image by running this command:
docker build -t hello-aws .

What does this command do?

  • docker build reads your Dockerfile and executes each instruction to produce an image.
  • -t hello-aws tags (names) the image hello-aws so you can reference it later.
  • . tells Docker to look for the Dockerfile in the current directory.

This will take a minute or two. Docker downloads the Amazon Linux base image, installs Apache, and creates your web page. You'll see each step printed in the terminal as it runs.

  • Wait for the build to finish. You should see a line like Successfully tagged hello-aws:latest at the end.

Build failed or stuck?

Make sure Docker Desktop is running. You can check by looking for the Docker whale icon in your menu bar. If it's not there, open Docker Desktop and wait for it to fully start.

If you see a "no such file or directory" error, confirm you're inside the hello-aws folder by running pwd. The output should end with /hello-aws.

Help me fix my Docker build error

Test your container locally

Before deploying to AWS, you should test the image on your own machine. This confirms your web server and HTML page work correctly.

  • Run your container locally by running this command:
docker run -p 80:80 hello-aws

What does this command do?

  • docker run creates and starts a container from your hello-aws image.
  • -p 80:80 maps port 80 on your machine to port 80 inside the container. This lets you access the web server from your browser.

Your terminal will appear to "hang" with no new prompt. That's normal. Apache is running in the foreground, which keeps the container alive.

  • Open your browser and go to http://localhost.

You should see a purple gradient page with a heading that says "Hello from Docker on AWS!" in white text.

  • Once you've confirmed the page loads, go back to your terminal and press Ctrl+C to stop the container.

Don't see the web page?

If the browser shows "connection refused" or a blank page, check that port 80 isn't being used by another application. Run lsof -i :80 to check. If something else is using port 80, stop that process first.

If you see "address already in use" in your terminal, a previous container might still be running. Run docker ps to list running containers, then stop any old ones with docker stop followed by the container ID.

Help me get my container running locally

Your Docker image is built and tested. Next up, you'll push this image to Amazon ECR so AWS can access it for deployment.

Push Your Image to Amazon ECR

Your Docker image is built and tested locally. Right now it only exists on your machine, which means AWS has no way to access it.

To deploy your container to the cloud, you need to store your image in a container registry that AWS can pull from. Amazon ECR (Elastic Container Registry) is AWS's private container registry, designed specifically for this purpose.

In this step, get ready to:
  • Create a private ECR repository for your image.
  • Authenticate your Docker client to push to ECR.
  • Tag and push your local image to the cloud.
Create an ECR repository

Before you can push an image, you need a repository to store it in. Think of an ECR repository like a folder in the cloud dedicated to a single application's images.

  • Create a private ECR repository called hello-aws by running this command:
aws ecr create-repository --repository-name hello-aws --region us-east-1

What does this command do?

This creates a private repository named hello-aws in your AWS account. Private means only your account can push and pull images from it.

The output includes a repositoryUri field. This is the full address of your repository in the cloud. It follows the format: <account-id>.dkr.ecr.us-east-1.amazonaws.com/hello-aws.

  • Look at the JSON output in your terminal. Find the repositoryUri value and note the 12-digit number at the beginning. This is your AWS account ID, and you will need it for the next commands.

Find your account ID quickly

Your account ID is the 12-digit number in the repositoryUri (everything before .dkr.ecr). You can also retrieve it anytime by running aws sts get-caller-identity.

Seeing an AccessDeniedException?

Your AWS CLI user needs permissions to create ECR repositories. Make sure the IAM user you configured in Step 1 has admin-level access or at minimum the ecr:CreateRepository permission.

If you see a repository already exists error, that means you already created it. You can continue to the next substep.

help me fix ECR permission errors in my AWS CLI

Authenticate Docker to ECR

Your ECR repository is private, so Docker needs a temporary access token to push images to it. The token is valid for 12 hours.

  • Authenticate your Docker client to ECR 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?

  • aws ecr get-login-password fetches a temporary authentication token from AWS.
  • The | pipe passes that token directly into the next command.
  • docker login uses the token to authenticate your Docker client with your private ECR registry.
  • Confirm you see Login Succeeded in your terminal output.

Login failed or timed out?

Double check that you replaced the account ID placeholder with your actual 12-digit AWS account ID. The full address must match the repositoryUri from the previous step (without the /hello-aws part at the end).

Also confirm Docker Desktop is still running. If it was closed, reopen it and wait for the engine to start.

help me fix my Docker ECR login issue

Tag and push your image

Docker needs to know where to send your image. You do this by tagging your local image with the full ECR repository address.

  • Tag your local hello-aws image with your ECR repository URI by running this command:
docker tag hello-aws:latest [[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/hello-aws:latest

What does tagging do?

Tagging does not create a copy of your image. It adds a second name (an alias) that points to the same image data. The new tag tells Docker exactly which registry and repository to push to.

  • Push your tagged image to ECR by running this command:
docker push [[AWS_ACCOUNT_ID="your 12-digit AWS account ID"]].dkr.ecr.us-east-1.amazonaws.com/hello-aws:latest
  • Wait for the push to complete. You will see each layer uploading with progress indicators. The push is done when you see a digest: sha256:... line followed by a latest: digest: summary.

What just happened?

Your Docker image is now stored in the cloud. AWS services like ECS can pull this image to run your container. The image is versioned with the latest tag, which always points to the most recently pushed version.

Push stuck on retrying?

If you see layers stuck on Retrying or Waiting, your authentication may have expired or the repository name doesn't match. Run the docker login command from the previous substep again, then retry the push.

Make sure the repository name in your tag (hello-aws) matches exactly what you created with aws ecr create-repository.

help me fix my Docker push to ECR

Your image is now safely stored in AWS. Next up, you will create the IAM roles that give ECS permission to pull your image and set up the infrastructure for deployment.

Create IAM Roles for ECS Express Mode

Your Docker image is pushed to ECR and ready to deploy. Before ECS Express Mode can launch your container, it needs permission to act on your behalf.

AWS uses IAM roles to grant services specific permissions. ECS Express Mode requires two roles: one that allows it to pull your container image and write logs, and another that allows it to provision infrastructure like load balancers and security groups.

In this step, get ready to:
  • Create the Task Execution Role for pulling images and writing logs.
  • Create the Infrastructure Role for provisioning load balancers, security groups, and auto-scaling.
  • Verify both roles are ready for ECS Express Mode.
Create the Task Execution Role

The Task Execution Role lets ECS pull your container image from ECR and send logs to CloudWatch. Without this role, ECS cannot access your private image.

  • Create the Task Execution Role by running this command:
aws iam create-role --role-name ecsTaskExecutionRole \
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "ecs-tasks.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'

What does this command do?

This creates an IAM role named ecsTaskExecutionRole with a trust policy. The trust policy tells AWS that only the ecs-tasks.amazonaws.com service is allowed to assume (use) this role.

The role itself has no permissions yet. You will attach a managed policy next to give it the permissions it needs.

  • Attach the managed policy that grants image-pull and logging permissions by running:
aws iam attach-role-policy --role-name ecsTaskExecutionRole \
    --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

What is a managed policy?

A managed policy is a pre-built set of permissions maintained by AWS. The AmazonECSTaskExecutionRolePolicy policy includes permissions to pull images from ECR and write logs to CloudWatch. Using a managed policy saves you from writing individual permission statements by hand.

  • You should see JSON output showing the role details (RoleName, Arn, etc.) after the first command. The second command produces no output on success.

Seeing an access denied error?

Your AWS CLI user needs IAM permissions to create roles and attach policies. Make sure your configured user has admin-level access or at minimum iam:CreateRole and iam:AttachRolePolicy permissions.

If you see an "EntityAlreadyExists" error, the role already exists in your account from a previous project. That is fine. Skip to the attach-policy command.

help me fix IAM permission errors when creating ECS roles

Create the Infrastructure Role

The Infrastructure Role gives ECS permission to provision the load balancer, security groups, SSL certificates, and auto-scaling configuration that make your app production-ready.

  • Create the Infrastructure Role by running this command:
aws iam create-role --role-name ecsInfrastructureRoleForExpressServices \
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowAccessInfrastructureForECSExpressServices",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ecs.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'

Why is this trust policy different?

Notice the principal here is ecs.amazonaws.com (the ECS service itself), not ecs-tasks.amazonaws.com (the task agent). The infrastructure role is used by ECS during service creation and updates to manage AWS resources. The task execution role is used during task startup to pull images and write logs.

  • Attach the Express Mode infrastructure policy by running:
aws iam attach-role-policy --role-name ecsInfrastructureRoleForExpressServices \
    --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRoleforExpressGatewayServices

What does this policy allow?

The AmazonECSInfrastructureRoleforExpressGatewayServices policy gives ECS permission to create and manage Application Load Balancers, target groups, VPC security groups, SSL/TLS certificates, and auto-scaling configurations. These are the building blocks of a production deployment that ECS Express Mode sets up automatically for you.

  • You should see JSON output with the role details. The attach-policy command produces no output on success.

Seeing an EntityAlreadyExists error?

This means the role already exists in your AWS account. This is fine. Skip the create-role command and run only the attach-role-policy command to make sure the correct policy is attached.

help me resolve IAM role creation errors for ECS Express Mode

Verify both roles are ready
  • Confirm both roles exist by running:
aws iam get-role --role-name ecsTaskExecutionRole --query 'Role.Arn' --output text
aws iam get-role --role-name ecsInfrastructureRoleForExpressServices --query 'Role.Arn' --output text
  • You should see two ARN values printed, one per line. They follow the format arn:aws:iam::<your-account-id>:role/ecsTaskExecutionRole and arn:aws:iam::<your-account-id>:role/ecsInfrastructureRoleForExpressServices.

Save these ARNs for the next step

You will need both role ARNs in the next step when you deploy your container. Keep your terminal open so you can scroll back to copy them.

Both roles are set up and ready to go. Next up, you will use them to deploy your container to the internet with a single command.

Deploy with ECS Express Mode

In the previous step, you created the IAM roles that give ECS permission to manage infrastructure on your behalf.

Now for the big moment: deploying your container to the internet with a single command. Normally, deploying a container to production requires configuring a VPC, load balancer, security groups, target groups, and auto-scaling policies separately. ECS Express Mode handles all of this automatically.

In this step, get ready to:
  • Deploy your container to AWS using a single CLI command.
  • Monitor the deployment until the service status reaches ACTIVE.
  • Access your live web app at a public HTTPS URL.
Deploy your container

ECS Express Mode needs three things: your container image URI, the task execution role ARN, and the infrastructure role ARN. You have all three ready from previous steps.

  • Deploy your container to ECS Express Mode by running this command:
aws ecs create-express-gateway-service \
    --primary-container "image"="[[AWS_ACCOUNT_ID="123456789012"]].dkr.ecr.us-east-1.amazonaws.com/hello-aws:latest" \
    --execution-role-arn arn:aws:iam::[[AWS_ACCOUNT_ID="123456789012"]]:role/ecsTaskExecutionRole \
    --infrastructure-role-arn arn:aws:iam::[[AWS_ACCOUNT_ID="123456789012"]]:role/ecsInfrastructureRoleForExpressServices \
    --monitor-resources

What does this command do?

This single command tells ECS Express Mode to create a fully managed service with your container image.

  • --primary-container points to your Docker image stored in ECR.
  • --execution-role-arn gives ECS permission to pull your image and write logs.
  • --infrastructure-role-arn gives ECS permission to provision the load balancer, security groups, and auto-scaling.
  • --monitor-resources keeps the terminal open so you can watch the deployment progress in real time.

What does ECS Express Mode create for you?

Behind the scenes, this one command provisions an Application Load Balancer, target groups, security groups, Fargate tasks, auto-scaling policies, an ACM certificate for HTTPS, and CloudWatch logging.

Without Express Mode, you would configure each of these resources individually. That process typically takes 30+ minutes of manual setup.

Monitor the deployment

After you run the command, your terminal enters an interactive monitoring mode. You will see resources being provisioned in real time.

What should I see?

The terminal shows a real-time display of each resource being created: the load balancer, security groups, target groups, auto-scaling configuration, and Fargate tasks. Deployment time varies but typically takes 2-5 minutes.

You can use the up/down arrow keys to scroll through the resource list. Once the status changes to ACTIVE, your application is ready to receive traffic.

  • Wait until the deployment completes and the status shows ACTIVE.
  • Press q to exit the interactive monitor once the deployment is complete.

When you exit the monitor, the CLI returns JSON output including the service ARN and service name. It looks similar to this:

{
    "service": {
        "cluster": "arn:aws:ecs:us-east-1:123456789012:cluster/default",
        "serviceName": "hello-aws-a1b2",
        "serviceArn": "arn:aws:ecs:us-east-1:123456789012:service/default/hello-aws-a1b2",
        "infrastructureRoleArn": "arn:aws:iam::123456789012:role/ecsInfrastructureRoleForExpressServices",
        "status": {
            "statusCode": "ACTIVE"
        }
    }
}

Save your service ARN

Copy the serviceArn value from the output. You will need it later when cleaning up your resources in the Before You Go section.

Deployment stuck or showing errors?

  • If you see a permissions error, double-check that both IAM roles have the correct trust policies and managed policies attached from the previous step.
  • If the deployment times out, your Docker image may not have pushed successfully to ECR. Run aws ecr describe-images --repository-name hello-aws to verify your image exists.
  • If your terminal lost connection to the monitor, you can check the status separately by running aws ecs describe-express-gateway-service --service-arn followed by your service ARN.

Why is my ECS Express Mode deployment failing?

Access your live application

Your app is now live on the internet with HTTPS, load balancing, and auto-scaling built in. Time to visit it.

  • Find your application URL in the terminal output. It follows the format https://<service-name>.ecs.us-east-1.on.aws/ where <service-name> is the generated name from the output (like hello-aws-a1b2).
  • Copy the full URL and paste it into your browser.

You should see your "Hello from Docker on AWS!" web page with the purple gradient background, served from a Docker container running on Fargate.

What is ECS Express Mode giving you for free?

  • Automatic SSL/TLS termination so your app is served over HTTPS.
  • Load balancing across multiple Availability Zones for high availability.
  • Auto-scaling based on CPU utilization so your app handles traffic spikes.
  • CloudWatch logging and monitoring for observability.
  • Canary deployments with 5XX rollback alarms for safe future updates.

Page not loading?

  • Make sure you are using https:// (not http://) in the URL.
  • If you see a 503 error, the Fargate tasks may still be starting. Wait 30 seconds and refresh.
  • Confirm the service status is ACTIVE by running aws ecs describe-express-gateway-service --service-arn followed by your service ARN.

Why can't I access my ECS Express Mode application URL?

Secret mission

Upgrade Your App With Environment Variables and a Health Check

Your basic deployment works, but production apps need health checks and configuration via environment variables. Can you upgrade your container to respond dynamically and prove it's healthy?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running or delete them entirely. This project uses AWS Fargate and an Application Load Balancer, which cost approximately $0.06/hour combined while running.

Cost warning

ECS Express Mode has no pause option. Your service is either running (and costing money) or deleted. If you leave your service running, expect charges of approximately $1.50/day.

We recommend deleting all resources now. You can always rebuild the project later.

Resources you used:

  • ECS Express Mode service (Fargate compute + Application Load Balancer).
  • ECR repository (hello-aws).
  • IAM role ecsTaskExecutionRole.
  • IAM role ecsInfrastructureRoleForExpressServices.
  • Local project files (Dockerfile and project directory).

Keep everything running

No action needed. Choose this if you plan to continue experimenting with your ECS Express Mode service.

  • Your app stays live at its public HTTPS URL.
  • Expect charges of approximately $0.06/hour ($1.50/day) for Fargate compute and the Application Load Balancer.
  • Docker Desktop and the AWS CLI remain installed on your machine.

Pause - I'll come back to this later

ECS Express Mode does not support pausing a service. Your only options are to keep it running or delete it entirely.

If you want to stop charges but plan to redo the project later, follow the Delete tab to remove all resources. You can rebuild the project from scratch when you return.

Delete - I don't want to use this again

Remove all project resources to stop all charges immediately. This cannot be undone.

  • Delete the ECS Express Mode service by running this command (replace the ARN with your own service ARN from the deployment output):
aws ecs delete-express-gateway-service --service-arn [[SERVICE_ARN="your ECS Express Mode service ARN"]] --monitor-resources

Where do I find my service ARN?

Your service ARN was displayed in the terminal output when you first created the service. It looks like arn:aws:ecs:us-east-1:123456789012:service/cluster-name/service-name.

If you no longer have it, run the following command to find it:

aws ecs describe-express-gateway-service --service-arn $(aws ecs list-services --query 'serviceArns[0]' --output text)
  • Wait for the deletion to complete. The terminal will show resources being removed (load balancer, security groups, auto-scaling policies, and the cluster if no other services are using it).
  • Delete the ECR repository by running:
aws ecr delete-repository --repository-name hello-aws --force
  • Delete the IAM roles. First, detach the managed policies, then delete each role:
aws iam detach-role-policy --role-name ecsTaskExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
aws iam delete-role --role-name ecsTaskExecutionRole
aws iam detach-role-policy --role-name ecsInfrastructureRoleForExpressServices --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRoleforExpressGatewayServices
aws iam delete-role --role-name ecsInfrastructureRoleForExpressServices
  • Delete your local project files by running:
cd ~/Desktop
rm -rf hello-aws

All resources are now removed. You will not incur any further charges from this project.

That's a Wrap!

That's a Wrap!

Nice work! You just deployed a Docker container to AWS like a professional.

You took a simple web app from your laptop all the way to a live, internet-accessible URL with production-grade infrastructure. That's the exact workflow professional teams use to ship applications every day.

You learned how to:

  • Built a Docker image from a Dockerfile and tested it locally before pushing to the cloud.
  • Pushed your image to Amazon ECR and created IAM roles for secure container deployment.
  • Deployed a live application using ECS Express Mode with automatic HTTPS, load balancing, and auto-scaling.
  • Secret Mission: Added health checks and environment variables for production-ready container configuration.

Ready to quiz yourself?