Deploy an App with Docker

Containerize a web app with Docker and deploy it live on AWS Elastic Beanstalk.

Introduction

30 Second Summary

Every app you use lives on a computer somewhere. Containers solve the headache of moving apps between machines by packaging everything an app needs into one portable unit.

In this project, you will build a Docker container that serves your personal web page. You will then deploy it to AWS Elastic Beanstalk so your app is live on the internet with a public URL anyone can visit.

What You'll Build

Open your browser to see your own web page running from a container on your machine, then share a public URL so anyone in the world can see it too.

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

  • A personal web page running inside a Docker container on your local machine, visible at localhost in your browser.
  • Your containerized app deployed to AWS Elastic Beanstalk, accessible to anyone on the internet via a public URL.
  • The ability to run, stop, and remove Docker containers from the command line.
  • Secret Mission: Deploy an updated version of your app through Elastic Beanstalk and watch the changes go live.

Are there any prerequisites?

This project assumes you already have an AWS account, Docker Desktop, VS Code, and Git installed on your machine. You should also have a GitHub account ready to go. Step 1 verifies your Docker setup before you start building.

Before We Start

In this project, you will build a Docker container image from scratch and deploy it to the cloud using AWS Elastic Beanstalk. Before diving in, take a moment to commit to what you are building and why it matters.

Verify Docker and Run Your First Container

Docker is installed on your machine, but you haven't confirmed it actually works yet. Before building your own container image, you need to prove the Docker engine can start and run containers.

The fastest way to test is to run a pre-built container. You'll pull an official Nginx web server image from Docker Hub and watch it serve a live web page in your browser.

In this step, get ready to:
  • Confirm Docker is installed and the daemon is running.
  • Pull and run an official Nginx container on your machine.
  • View the Nginx welcome page at http://localhost.
Open VS Code and confirm Docker is running

Docker commands need Docker Desktop running in the background. Let's make sure it's active before anything else.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Docker Desktop and press Enter to launch it.
  • Check that the Docker whale icon appears in your system tray (Windows) or menu bar (macOS). This confirms the Docker engine is ready.
  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar again.
  • Type VS Code and press Enter to open it.
  • Click Terminal in the top menu bar.
  • Select New Terminal.
  • Confirm Docker is installed by running this command:
docker --version

You should see a version number printed back, confirming the Docker CLI is ready.

Don't see a version number?

  • Make sure Docker Desktop is fully started. The whale icon should be steady, not animating.
  • If your terminal doesn't recognize the docker command, Docker Desktop may not be installed correctly. Reinstall it from the official Docker website.
  • Docker isn't responding to my commands. How do I fix this?
Run the Nginx container

Now that Docker is confirmed working, you can run your first container. This single command pulls a pre-built web server image and starts it on your machine.

  • Pull and start an Nginx container by running this command:
docker run -d -p 80:80 nginx

What does this command do?

  • docker run creates and starts a new container from an image.
  • -d runs the container in detached mode so it runs in the background without blocking your terminal.
  • -p 80:80 maps port 80 on your machine to port 80 inside the container. Requests to http://localhost go straight to the container.
  • nginx is the image name. Docker checks for it locally first, then pulls it from Docker Hub if it's not found.

Since this is your first time using the nginx image, Docker pulls it from Docker Hub. You'll see download progress bars as each layer downloads.

When it finishes, Docker prints a long string of characters. That's your container ID, confirming the container started successfully.

Seeing an error instead of a container ID?

  • If you see an error about connecting to the Docker daemon, make sure Docker Desktop is fully running. Open Docker Desktop and wait for the whale icon to stop animating.
  • If you see a port binding error, another application is already using port 80. Close that application (common culprits include Apache, IIS, or another web server) and try the command again.
  • My docker run command failed. How do I fix the error?
See the Nginx welcome page in your browser

Your container is running in the background. Before you check it, what do you think you'll see when you open http://localhost in your browser?

  • Open your web browser.
  • Navigate to http://localhost.

You see the "Welcome to nginx!" default page. This page is being served directly from the Docker container running on your machine.

What just happened?

When you typed http://localhost, your browser sent a request to port 80 on your machine. Docker forwarded that request into the Nginx container, which served back its default welcome page.

The web page is not a file on your Desktop. It lives inside the container. If you stop the container, the page disappears.

🙋‍♀️ Don't see the welcome page?

  • Make sure you're using http://localhost (not https). The container only serves over HTTP.
  • If the page won't load, the container may not be running. Go back to your terminal and re-run the docker run command from the previous substep.
  • I don't see the Nginx welcome page at localhost. What went wrong?

Docker is up and running, and you've served your first web page from a container. Next, you'll build a custom Docker image with your own HTML content baked in.

Build a Custom Docker Image

In the last step, you pulled the official Nginx image and ran it as a container. The welcome page at http://localhost proves Docker is working on your machine.

That page belongs to Nginx, though. To serve your own content, you need to build a custom Docker image with your own files baked in.

In this step, get ready to:
  • Create a project folder with a Dockerfile and an index.html file.
  • Write a custom HTML page and a Dockerfile that packages it into an Nginx image.
  • Build a custom Docker image named my-web-app.
  • Initialize a Git repository and push your project to GitHub.
Create the project folder and files

Your custom image needs two files: a Dockerfile that tells Docker how to assemble the image, and an index.html page with your content. First, create a folder to hold them.

  • Move to your Desktop by running this command:
cd ~/Desktop

Desktop synced to OneDrive?

If your Desktop folder is synced to OneDrive, creating a Git repo there can cause sync conflicts. Run this instead to create the folder in your home directory:

cd ~

On Windows, your home directory is typically C:\Users\ followed by your username.

  • Create your project folder by running this command:
mkdir Compute
  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the Compute folder.
  • Click Open (macOS) or Select Folder (Windows).

Seeing a trust dialog?

VS Code may ask "Do you trust the authors of the files in this folder?" Click Trust the folder to continue. This lets VS Code run code and extensions normally inside the folder.

VS Code now shows the empty Compute folder in the Explorer sidebar on the left. Next, create the two files you need.

  • In the Explorer sidebar, hover over the COMPUTE heading and click the New File icon that appears.
  • Type Dockerfile (with no file extension) and press Enter.
  • Click the New File icon again.
  • Type index.html and press Enter.

You should see both Dockerfile and index.html listed in the Explorer sidebar under Compute.

Don't see the New File icon?

Make sure you are hovering over the COMPUTE folder heading in the Explorer sidebar. The icon row only appears on hover.

If the sidebar is closed, press Cmd+Shift+E (macOS) or Ctrl+Shift+E (Windows) to open it.

help me find the New File button in VS Code

Write the Dockerfile and HTML page

A Dockerfile is a recipe that tells Docker exactly how to build an image. Yours will start from the official Nginx image and swap in your own HTML page.

  • Click on Dockerfile in the Explorer sidebar to open it, then add the following code:
# Start from the official Nginx image
FROM nginx:latest
# Replace the default welcome page with your HTML file
COPY index.html /usr/share/nginx/html/
# Declare that this container listens on port 80
EXPOSE 80

What does this code do?

  • FROM nginx:latest tells Docker to use the official Nginx image as the starting point. Everything in that image (the web server, its config) comes along for free.
  • COPY index.html /usr/share/nginx/html/ copies your HTML file into Nginx's default document root. This replaces the generic welcome page with your own content.
  • EXPOSE 80 documents that the container listens on port 80, the standard port for web traffic.
  • Save Dockerfile by pressing Cmd+S (macOS) or Ctrl+S (Windows).

✔️ Awesome, I've got everything!

Great. Make sure you have saved Dockerfile before moving on.

ⓧ I'd like to double check the full code

Here is the complete Dockerfile. Make sure yours matches exactly:

# Start from the official Nginx image
FROM nginx:latest
# Replace the default welcome page with your HTML file
COPY index.html /usr/share/nginx/html/
# Declare that this container listens on port 80
EXPOSE 80

Now write the HTML page that your image will serve instead of the Nginx default.

  • Click on index.html in the Explorer sidebar to open it, then add the following code:
<!doctype html>
<html>
  <head>
    <!-- Set the page title shown in the browser tab -->
    <title>My Web App</title>
  </head>
  <body>
    <!-- Display a personalized heading with your name -->
    <h1>Hello from [[YOURNAME="Your Name"]]'s custom Docker image!</h1>
  </body>
</html>

What does this code do?

This is a simple HTML page with a personalized heading. Replace Your Name with your actual name so you can tell at a glance that Docker is serving your content, not the default Nginx page.

  • Save index.html.
  • Open the Compute folder on your Desktop in Finder (macOS) or File Explorer (Windows), then double-click index.html to open it in your browser.

You should see your personalized heading (e.g. "Hello from Nhi's custom Docker image!") displayed in the browser.

Seeing a blank page?

Make sure you saved index.html in VS Code before opening it. An unsaved file still has a white dot on its tab.

Check that your HTML includes the opening <html> and <body> tags. A missing tag can prevent the browser from rendering your content.

help me fix my blank HTML page

✔️ Awesome, I've got everything!

Great. Make sure both files are saved before moving on to the build step.

ⓧ I'd like to double check the full code

Here is the complete index.html. Make sure yours matches (with your own name in place of Your Name):

<!doctype html>
<html>
  <head>
    <title>My Web App</title>
  </head>
  <body>
    <h1>Hello from [[YOURNAME="Your Name"]]'s custom Docker image!</h1>
  </body>
</html>
Build the custom Docker image

Your files are ready. Now you will feed them to Docker so it can package everything into a reusable image.

  • In VS Code, click Terminal in the top menu bar, then click New Terminal.

Why a new terminal?

You may still have a terminal open from Step 1. That terminal might not be inside the Compute folder. Opening a new terminal starts it in the folder VS Code has open, which is Compute.

  • Confirm you are in the Compute folder and your files are ready by running:
ls

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

  • Build your custom Docker image by running this command:
docker build -t my-web-app .

What does this command do?

  • docker build reads the Dockerfile in the current directory and creates an image from it.
  • -t my-web-app tags (names) the image my-web-app so you can refer to it later.
  • . tells Docker to use the current directory as the build context. Docker looks here for the Dockerfile and any files it references (like index.html).

You should see Docker step through each instruction in your Dockerfile. The final line confirms the image was built and tagged successfully.

Before you run the next command, think about what images you expect to see listed. How many should there be?

  • Verify your image was created by running:
docker images

You should see my-web-app listed alongside the nginx image you pulled in Step 1.

Build failed?

If you see an error mentioning the Dockerfile not being found, make sure your terminal is inside the Compute folder. Run ls to check.

Check that the file is named exactly Dockerfile with a capital D and no file extension. On Windows, File Explorer may have added .txt without showing it. Rename it in VS Code if needed.

If you see a connection error, make sure Docker Desktop is running. Look for the Docker whale icon in your system tray or menu bar.

help me fix my Docker build error

Push your project to GitHub

Your Docker image is built, but the source files behind it only exist on your machine. Tracking your project with Git and pushing it to GitHub means you have a backup, a version history, and a portfolio piece to show recruiters.

  • Initialize a Git repository in your Compute folder by running this command:
git init

You should see a message confirming the repository was initialized.

Before you add files, create a .gitignore to keep ZIP files (which you'll create later for deployment) out of your repo.

  • Create a .gitignore file by running this command:
echo "*.zip" > .gitignore
  • Stage all your files and make your first commit by running these commands:
git add .
git commit -m "Initial commit: Dockerfile and index.html"

What does this do?

git add . stages every file in the folder. git commit saves a snapshot of those files with a descriptive message. You now have a local version history you can roll back to at any time.

Now push this repo to GitHub so it lives online.

  • Open your browser and go to github.com/new.
  • Enter nextwork-docker as the Repository name.
  • Leave the repository set to Public.
  • Do not check any of the initialization options (README, .gitignore, or license). Your repo already has files.
  • Click Create repository.

GitHub shows a quick setup page with commands. You need the two lines under the heading that says "push an existing repository from the command line."

  • Connect your local repo to GitHub and push your code by running these commands:
git remote add origin https://github.com/[[GITHUB_USERNAME="your GitHub username"]]/nextwork-docker.git
git branch -M main
git push -u origin main
  • Refresh the GitHub page in your browser.

You should see Dockerfile, index.html, and .gitignore listed in your repository.

Push failed or asked for credentials?

If Git asks for a username and password, GitHub no longer accepts passwords for HTTPS pushes. Use a personal access token or switch to SSH. You set this up in the Git series.

If you see an error about the remote already existing, you may have run the git remote add command twice. Run git remote -v to check, then try the push again.

Help me push my project to GitHub.

Your custom Docker image is built, and the project is tracked on GitHub. Next up, you will run it as a container and see your personalized page in the browser.

Run Your Custom Container

Your custom Docker image is built and listed in docker images. An image alone is just a blueprint on disk that does not serve any web traffic.

In this step, you will run your image as a container and see your personalized HTML page live at http://localhost.

In this step, get ready to:
  • Run your custom Docker image as a container.
  • Manage running containers with docker ps and docker stop.
  • View your custom HTML page at http://localhost.
Run your custom image as a container

Before you run the next command, what do you think will happen? Will your custom page show up at http://localhost right away?

  • Start your custom container by running this command:
docker run -d -p 80:80 my-web-app

Docker returns an error about the port already being in use. This is exactly the problem you need to solve.

Why did this happen?

The Nginx container from Step 1 is still running and has claimed port 80 on your machine. Two containers cannot listen on the same port at the same time.

To free up port 80 for your custom container, you need to stop the Nginx container first.

Find and stop the old container
  • List all running containers by running this command:
docker ps

You see a table of all running containers on your machine.

What does docker ps show?

Each row represents a running container. The CONTAINER ID column shows a unique identifier for each container. The IMAGE column shows which image the container was built from.

Look for the row where the IMAGE column shows nginx. Copy the value in the CONTAINER ID column for that row. You will need it in the next command.

  • Stop the Nginx container by running this command, replacing the container ID with the one you just copied:
docker stop [[NGINX_CONTAINER_ID="your nginx container ID from docker ps"]]
  • Confirm the container has stopped by running:
docker ps

The nginx container no longer appears in the list. Port 80 is now free.

Container still showing up?

  • Make sure you copied the correct value from the CONTAINER ID column. It is the first value in each row of the docker ps output.
  • Check that you stopped the right container. The row you target should have nginx in the IMAGE column.
  • Why is the nginx container still running after docker stop?
Run your container again
  • Now that port 80 is free, start your custom container by running this command:
docker run -d -p 80:80 my-web-app

This time, Docker prints a long string of characters. That is the container ID for your newly running container.

What does this command do?

  • -d runs the container in detached mode, so it stays running in the background while you use your terminal.
  • -p 80:80 maps port 80 on your machine to port 80 inside the container. This is how your browser reaches the web server running inside Docker.
  • my-web-app is the name of the custom image you built in the previous step.

What do you expect to see when you open http://localhost now?

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

You see your personalized heading from index.html. Your custom web page is now being served from your Docker container.

Don't see your custom page?

  • If you still see the default Nginx welcome page, try a hard refresh. Press Cmd+Shift+R (macOS) or Ctrl+Shift+R (Windows) to clear your browser cache.
  • If you see an error about the port being in use, run docker ps to check whether another container is still running on port 80.
  • Make sure Docker Desktop is still running. If it was closed, reopen it and try the docker run command again.
  • Help me debug why my custom Docker page is not showing at localhost.

Your custom web page is live in a Docker container on your machine. Next, you will log in to AWS and get your app ready to go live on the internet.

Log In to AWS

Your custom Docker container is serving your personal web page at http://localhost. The next goal is getting that page live on the internet where anyone can access it.

Deploying to the cloud requires AWS. Before you can use Elastic Beanstalk to host your container, you need to log in to the AWS Management Console with the right kind of account.

In this step, get ready to:
  • Log in to the AWS Management Console.
  • Confirm you are using an IAM user for security best practices.
Log in to the AWS Management Console

Your containerized app needs a cloud home. AWS has different types of accounts, and the one you use for everyday work matters.

Why use an IAM user instead of the root user?

Your root account has unrestricted access to everything in your AWS account. If those credentials are compromised, an attacker could do anything.

An IAM user lets you work with only the permissions you need. AWS recommends using an IAM user for everyday tasks and reserving the root account for rare administrative actions.

✔️ I already have an IAM user

  • Log in with your IAM user credentials (account ID or alias, username, and password).

You should see your IAM user name displayed in the top-right corner of the console.

ⓧ I need to create an IAM user

Log in as the root user first, using the email and password you used to create your AWS account.

Once you are in the console, navigate to the IAM service to create a new user.

  • In the search bar at the top of the console, type IAM.
  • Select IAM from the results.
  • In the left navigation panel, click Users.
  • Click Create user.

The Create user wizard opens. Configure your new user with console access.

  • Enter a username such as yourname-IAM-Admin, replacing "yourname" with your actual name.
  • Select the checkbox for Provide user access to the AWS Management Console.
  • Set a custom password you will remember.
  • Click Next.

Now set the permissions for your user so they can manage AWS resources.

  • Select Attach policies directly.
  • In the search bar, type AdministratorAccess.
  • Select the checkbox next to AdministratorAccess.
  • Click Next.
  • Review the details and click Create user.

Your IAM user is created. Download your credentials and sign in with the new account.

  • Click Download .csv file to save your login credentials.
  • Click your account name in the top-right corner of the console.
  • Click Sign out.

Now sign back in as your new IAM user.

  • Open the .csv file you downloaded.
  • Copy the Console sign-in URL from the .csv file and paste it into your browser.
  • Enter the IAM username and password from the .csv file.
  • Click Sign in.

You should see your new IAM user name displayed in the top-right corner of the console.

Don't see your IAM user name?

Make sure you logged in with IAM credentials, not the root account email. The root account displays an email address in the top-right corner, while an IAM user displays the username.

If you just created an IAM user, confirm you signed out of the root account and signed back in using the Console sign-in URL from the .csv file.

Help me figure out if I'm signed in as an IAM user or the root user.

You are logged into AWS and ready to deploy. Next up, you will upload your Docker project to Elastic Beanstalk and get a public URL for your web app.

Deploy to AWS Elastic Beanstalk

You're logged into AWS and your custom Docker container is running locally. Right now, your web page lives on your machine and nobody else can see it.

In this step, you'll deploy your containerized app to AWS Elastic Beanstalk. Elastic Beanstalk handles the servers, networking, and scaling for you. By the end, you'll have a public URL that anyone in the world can visit.

In this step, get ready to:
  • Update your HTML with a second heading line and package it into a ZIP file for deployment.
  • Create an Elastic Beanstalk application with a Docker environment.
  • Deploy your app and access it via a public URL on the internet.
Update your HTML and create a deployment ZIP

Before uploading to Elastic Beanstalk, you'll add a second heading to your page. This way, when the app goes live, you'll know it's truly your latest code running in the cloud.

  • Switch back to VS Code with your index.html file open.
  • Find this line inside the <body> tags:
    <h1>Hello from Your Name's custom Docker image!</h1>
  • Add a new <h1> line directly below it, so both lines sit together:
    <h1>Hello from Your Name's custom Docker image!</h1>
    <h1>If I can see this, it means Elastic Beanstalk has deployed an image with my work.</h1>
  • Save index.html.

✔️ Awesome, I've got everything!

Great. Make sure you've saved the file before moving on.

ⓧ I'd like to double check the full code

Here is the complete index.html at this point:

<!doctype html>
<html>
  <head>
    <title>My Web App</title>
  </head>
  <body>
    <h1>Hello from Your Name's custom Docker image!</h1>
    <h1>If I can see this, it means Elastic Beanstalk has deployed an image with my work.</h1>
  </body>
</html>

Before you package the ZIP, commit and push this change to GitHub so your repo stays up to date.

  • In your VS Code terminal, commit and push the updated HTML by running these commands:
git add .
git commit -m "Add second heading for Elastic Beanstalk deployment"
git push

You should see Git confirm the push to your nextwork-docker repository on GitHub.

Now you need to package your project files into a ZIP that Elastic Beanstalk can read. The ZIP must contain Dockerfile and index.html at the root level, not inside a subfolder.

macOS

  • Open Finder and navigate to the Compute folder on your Desktop.
  • Click on Dockerfile, then hold Cmd and click index.html so both files are selected.
  • Right-click the selection and choose Compress 2 Items.
  • A file called Archive.zip appears in the Compute folder.

Windows

  • Open File Explorer and navigate to the Compute folder on your Desktop.
  • Click on Dockerfile, then hold Ctrl and click index.html so both files are selected.
  • Right-click the selection and choose Compress to ZIP file.
  • A .zip file appears in the Compute folder.

ZIP file not working later?

The most common mistake is right-clicking the Compute folder itself instead of the files inside it. If the ZIP contains a Compute/ subfolder wrapping the files, Elastic Beanstalk will not find the Dockerfile. Select the two files directly, not their parent folder.

Help me fix my ZIP file structure for Elastic Beanstalk.

Create an Elastic Beanstalk application

Elastic Beanstalk is an AWS service that takes your application code and automatically provisions the infrastructure to run it. You upload your ZIP, and it handles the rest.

  • Switch to your browser with the AWS Management Console.
  • In the search bar at the top, type Elastic Beanstalk and select the service from the results.
  • Click Create application.
  • Enter NextWork App as the Application name.
  • Under Platform, select Docker. The platform branch Docker running on 64bit Amazon Linux 2023 is auto-selected for you.
  • Under Application code, select Upload your code.
  • Click Local file, then click Choose file and upload the ZIP file you just created.
  • Under Presets, select Single instance (free tier eligible).
  • Click Next.

What does Elastic Beanstalk set up for you?

When you submit this application, Elastic Beanstalk automatically provisions an EC2 instance (a virtual server), a security group (firewall rules), and an S3 bucket to store your application versions. It also assigns a public domain name so anyone can reach your app.

The Single instance (free tier eligible) preset means AWS runs just one server with no load balancer. This keeps your deployment inside the Free Tier.

Configure service access and deploy

The next page asks you to set up IAM roles that give Elastic Beanstalk permission to manage AWS resources on your behalf. Depending on whether you've used Elastic Beanstalk before, you may already have these roles.

✔️ I see existing roles in the dropdowns

  • Select the existing role for Service role.
  • Select the existing role for EC2 instance profile.
  • Click Skip to Review.

ⓧ The dropdowns are empty

You need to create two IAM roles. Each one is created through a link that opens the IAM console in a new browser tab.

First, create the service role:

  • Next to Service role, click the Create role link. This opens the IAM console in a new tab.
  • For Trusted entity type, select AWS service.
  • For Use case, choose Elastic Beanstalk - Environment.
  • Confirm that the policies AWSElasticBeanstalkEnhancedHealth and AWSElasticBeanstalkManagedUpdatesCustomerRolePolicy are included.
  • Click Create role.
  • Close this IAM tab and return to the Elastic Beanstalk tab. Refresh the Service role dropdown to see your new role.

Next, create the EC2 instance profile:

  • Next to EC2 instance profile, click the Create role link. This opens the IAM console in a new tab again.
  • For Trusted entity type, select AWS service.
  • For Use case, choose Elastic Beanstalk - Compute.
  • Confirm that the policies AWSElasticBeanstalkWebTier, AWSElasticBeanstalkWorkerTier, and AWSElasticBeanstalkMulticontainerDocker are included.
  • Click Create role.
  • Close this IAM tab and return to the Elastic Beanstalk tab. Refresh the EC2 instance profile dropdown to see your new role.
  • Click Skip to Review.

What are these IAM roles for?

The Service role lets Elastic Beanstalk monitor your environment's health and apply updates. The EC2 instance profile lets the virtual server running your app interact with other AWS services like S3.

  • On the Review page, scan through your settings to make sure the application name is NextWork App, the platform is Docker, and the preset is Single instance (free tier eligible).
  • Click Submit.

Elastic Beanstalk now creates your environment. This takes several minutes. You'll see a stream of events in the console as it provisions the EC2 instance, configures the security group, and deploys your Docker container.

Wait for green health

Keep the page open and wait until the environment health indicator turns green. This means your app is running and ready to receive traffic.

Before you click the Domain link, what do you expect to see on the page? Think about which version of your HTML Elastic Beanstalk received in the ZIP.

  • Once health is green, click the URL next to Domain at the top of the environment overview page.

You see your personalized heading along with the second heading: "If I can see this, it means Elastic Beanstalk has deployed an image with my work." Your containerized app is now live on the internet.

Page not loading or showing an error?

If health stays grey or red, check the Events tab in the Elastic Beanstalk console for error details. The most common cause is a ZIP file with the wrong structure (files inside a subfolder instead of at the root level). Re-create the ZIP by selecting Dockerfile and index.html directly, then use Upload and deploy on the environment page to upload the corrected ZIP.

If you see the default Nginx welcome page instead of your custom heading, your Dockerfile may be missing the COPY instruction. Double check your Dockerfile matches the one from Step 2.

Help me troubleshoot my Elastic Beanstalk deployment.

Secret mission

Deploy an App Update

Real-world apps are updated constantly. Can you deploy a new version of your web page through Elastic Beanstalk and watch the changes go live on the internet?

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project uses an EC2 instance through Elastic Beanstalk, which consumes AWS Free Tier hours if left running.

Cost warning

Your Elastic Beanstalk environment runs an EC2 instance that consumes Free Tier hours (750 hours per month for the first 12 months of your AWS account). If you leave the environment running beyond those limits, you will be charged.

Choose Pause or Delete below to avoid unexpected costs.

Resources you used:

  • Elastic Beanstalk environment and application (NextWork App). Includes an EC2 instance and security group that incur charges.
  • S3 bucket (auto-created by Elastic Beanstalk, name starts with elasticbeanstalk). Stores application version ZIP files.
  • IAM roles (Elastic Beanstalk service role and EC2 instance profile). No cost.
  • Docker containers and images on your local machine.
  • Local Compute folder on your Desktop containing project files.

Keep everything running

No action needed. Choose this if you are still actively building or want to keep your app live at its public Domain URL.

  • Your Elastic Beanstalk environment stays live and your app remains accessible on the internet.
  • The EC2 instance consumes Free Tier hours (750 hours per month for the first 12 months of your AWS account).
  • Your Docker container continues running locally on port 80.
  • Your IAM roles remain in your account at no cost.

Pause - I'll come back to this later

Shut down cloud resources to stop charges, but keep local files so you can redeploy later.

  • In the Elastic Beanstalk console, navigate to Environments, select your environment, choose Actions, then Terminate Environment. Enter the environment name to confirm. This stops the EC2 instance and ends charges.
  • Keep the Elastic Beanstalk application (NextWork App) and S3 bucket so you can create a new environment later.
  • Stop your local Docker container. Open your terminal and run:
docker ps
  • Find the container running the my-web-app image and note its container ID. Then stop it by running:
docker stop [[CONTAINER_ID="your container ID from the list above"]]
  • Keep your Compute folder and Docker images on your machine so you can rebuild and redeploy later.

Delete - I don't want to use this again

Remove all project resources from AWS and your local machine. Follow each step below in order.

Terminate the Elastic Beanstalk environment
  • In the Elastic Beanstalk console, navigate to Environments.
  • Select your environment, choose Actions, then choose Terminate Environment.
  • Enter the environment name to confirm, then choose Terminate.
Delete the Elastic Beanstalk application
  • In the Elastic Beanstalk console, go to Applications.
  • Select NextWork App, choose Actions, then choose Delete application.
  • Enter the application name to confirm, then choose Delete.
Empty and delete the S3 bucket
  • Open the S3 console. Find the bucket with a name starting with elasticbeanstalk.
  • Select the bucket and choose Empty.
  • Type permanently delete to confirm, then choose Empty.
  • After the bucket is emptied, select the bucket again and choose Delete.
  • Enter the bucket name to confirm, then choose Delete bucket.

Bucket won't delete?

If you see a permissions error, check the bucket's Permissions tab for a bucket policy. Delete the policy first, then retry the bucket deletion.

Delete the IAM roles
  • Open the IAM console. In the left navigation pane, choose Roles.
  • Search for the Elastic Beanstalk service role you created during Step 5.
  • Select the checkbox next to the role name and choose Delete.
  • Enter the role name to confirm, then choose Delete.
  • Repeat for the EC2 instance profile role you created for Elastic Beanstalk.
Clean up Docker containers and images
  • Return to your VS Code terminal and list all containers by running:
docker ps -a
  • For each container in the list, stop and remove it by running:
docker stop [[CONTAINER_ID="your container ID from the list above"]]
docker rm [[CONTAINER_ID="your container ID from the list above"]]
  • List all Docker images by running:
docker images
  • Remove each image by running:
docker rmi [[IMAGE_ID="your image ID from the list above"]]
Delete local project files
  • Delete the Compute folder from your Desktop. On macOS or Linux, run:
rm -rf ~/Desktop/Compute
  • On Windows, open PowerShell and run:
Remove-Item -Recurse -Force ~\Desktop\Compute

Nice Work!

Nice Work!

Nice work! You just built a custom Docker container from scratch and deployed it to the cloud using AWS Elastic Beanstalk. Your personalized web page is live on the internet with a public URL anyone can visit.

You've learned how to:

  • Build a custom Docker image from a Dockerfile that serves your own personalized web page inside an Nginx container.
  • Manage the container lifecycle from the command line. You diagnosed a port conflict, stopped a running container, and launched your own in its place.
  • Deploy a containerized application to AWS Elastic Beanstalk and access it via a public URL on the internet that anyone in the world can visit.
  • Secret Mission: Updated your app and deployed a new version through Elastic Beanstalk, following the same workflow development teams use in production.

Ready to quiz yourself?