Diagnose Docker Access on Amazon EC2
Deploy a Docker app to EC2 and trace why its public port is unreachable.
Introduction
30 Second Summary
An app can work perfectly on the computer hosting it while everyone outside sees a timeout. When several locked doors sit between the app and the internet, changing them all at once makes the real blocker harder to find.
In this project, you will deploy your existing Python app with Docker on Amazon EC2. You will trace an intentional timeout from the app outward until a security group rule restores access only for your current public IPv4 address.
What You'll Build
You will open your deployed app from your Mac and point to the logs that prove your request crossed every network boundary.
By the end of this project, you'll have:
- A Dockerized Python app that answers HTTP requests on your Mac and from its Amazon EC2 host.
- An inside-out troubleshooting trail that proves where traffic succeeds across the app, container, host, public route, and security group.
- A least-privilege public endpoint on port 8000 that only your current public IPv4 address can reach.
- Secret Mission: A loopback-only Docker host binding that recreates the timeout, proves why the security group cannot fix it, and restores the correct binding.
What do I need before I start?
You need a Mac with macOS Terminal and Docker Desktop.
Bring an AWS account with Amazon EC2 permissions plus an existing source folder containing Dockerfile, requirements.txt, and app/.
Before We Start
This checkpoint locks in the Python ASGI application you are about to deploy. It also anchors your reason for diagnosing an unreachable deployment from the inside out.
Validate the Local Container
An inside-out diagnosis needs a boundary you can already trust. A local HTTP response proves the application starts inside its container image.
You will check the tools on your Mac first. Then you will prove the image answers through published port 8000.
In this step, get ready to:
- Confirm the existing build context is complete.
- Verify every required command-line tool.
- Capture a local HTTP response as your known-good baseline.
Check the local prerequisites
The existing source folder is the build context that Docker Desktop reads. A quick tool check prevents a missing local command from looking like an application failure.
- Press Cmd+Space on your Mac to open system search.
- Type Terminal.
- Press Enter to open macOS Terminal.
- Move into your existing application folder by running this command:
cd "[[APPLICATION_FOLDER="path to your existing application folder"]]"
What does this command do?
The cd command changes Terminal's current folder. Quotation marks keep paths containing spaces together.
- List the folder contents by running this command:
ls
What does this command do?
The ls command lists the current folder's contents. This confirms that your next commands use the intended build context.
You should see Dockerfile, requirements.txt, and the app/ directory.
The bare scp check prints usage because no source or target is supplied. That usage text proves the command is available.
- Check the required local tools by running these commands:
docker version
ssh -V
scp
curl --version
What should these checks show?
- The docker output includes client information plus server information.
- The ssh output identifies the installed OpenSSH version.
- The scp output shows command usage.
- The curl output identifies the installed version.
Missing Docker server information?
- Start Docker Desktop through macOS system search.
- Repeat the tool check after Docker Desktop finishes starting.
- Help me diagnose my local Docker tool check.
Run the image locally
The build command turns the unchanged source into session4-app:local. This gives you an image that can be tested before any cloud networking exists.
- Build the local image from the existing source by running this command:
docker build -t session4-app:local .
What does this command do?
- The -t option assigns the image name session4-app:local.
- The final . sends the current folder to Docker as the build context.
- The existing Dockerfile defines how Docker assembles the application image.
You should see the build progress finish without an error. The image session4-app:local is now available on your Mac.
Did the image build fail?
- Use the folder listing above to confirm that Dockerfile is in the current folder.
- Confirm Docker Desktop is still running.
- Help me diagnose this local image build.
A container is a running instance of the image. Publishing port 8000 gives your Mac a path to the application's port inside that container.
- Start the temporary local container by running this command:
docker run -d --name session4-local -p 8000:8000 session4-app:local
How is the container started?
- The -d option runs the container in detached mode.
- The --name option assigns the container name session4-local.
- The -p 8000:8000 option maps host port 8000 to container port 8000.
You should see a container identifier in Terminal. That value confirms Docker created the running container.
Did the container fail to start?
- Check whether a previous container is already using the name session4-local.
- Check whether another local service is already using port 8000.
- Help me start the local container.
Prove the local HTTP path
An HTTP status line proves the request crossed the Mac's host port before reaching the application. The root URL can return a missing-page status while still proving the transport path works.
Before you run the request, what result would prove the network path works even if the root URL has no page?
- Request the application's root URL by running this command:
curl --connect-timeout 5 -v http://127.0.0.1:8000/
What does this request test?
- The --connect-timeout 5 option limits the connection phase to five seconds.
- The -v option shows connection details plus the HTTP exchange.
- The address 127.0.0.1 sends the request through your Mac's loopback interface.
You should see an HTTP status line. A response such as 404 Not Found still proves the request reached the application.
Did the local request time out?
- Confirm that session4-local is still running.
- Repeat the container run command if the container stopped.
- Help me diagnose this local timeout.
- Inspect the latest application logs by running this command:
docker logs --tail 20 session4-local
What do the logs prove?
The --tail 20 option limits the output to the latest twenty lines. A matching access-log entry connects your client request to activity inside the container.
You should see a recent log entry for the root request. This links the HTTP status in Terminal to the application process inside session4-local.
No matching request in the logs?
- Repeat the local HTTP request while the container is running.
- Inspect the latest logs again immediately after the request.
- Help me correlate the request with the container logs.
Removing this temporary container is safe. The session4-app:local image remains available for the next deployment stage.
- Remove the temporary local container by running this command:
docker rm -f session4-local
What does this command remove?
The -f option stops the running container before removing it. The command removes session4-local while preserving session4-app:local.
The command should finish without an error. You now have a clean local baseline with the reusable image still available.
Was the container already missing?
A missing session4-local container means the cleanup state is already correct. Keep the session4-app:local image for the next stage.
Help me confirm my Docker cleanup state.
That's your first trusted boundary established. The unchanged application answered through Docker's local port mapping before any cloud layer was introduced.
✔️ Awesome, I've got everything
Your local validation is complete. Keep the session4-app:local image for the EC2 deployment.
ⓧ I'd like to double check the full code
The application source remains unchanged. Your local Docker state should match these two checkpoints.
Local Docker image session4-app:local: Built on the Mac from the existing application source folder containing Dockerfile, requirements.txt, and app/.
Local Docker container session4-local: Removed after local validation. It was run with -p 8000:8000 and successfully served an HTTP response at http://127.0.0.1:8000/.
Your local baseline is proven. Next, you'll prepare an EC2 host while keeping the application port closed for a controlled diagnosis.
Launch and Prepare the EC2 Host
Your local container already proved that the application image can serve an HTTP response. The next boundary is a public Linux host on Amazon EC2.
The deployment needs a public host with only its management path open. You will keep application port 8000 closed so the missing rule becomes a controlled networking obstacle.
In this step, get ready to:
- Launch a public EC2 instance with the required compute and storage.
- Create restricted SSH access for the instance.
- Install Docker Engine for the EC2 user.
Launch the EC2 instance
Public reachability depends on more than the instance itself. The host needs a public IPv4 address plus a public subnet with a route to an internet gateway.
A security group filters traffic before it reaches the host. Starting with only TCP 22 open keeps the application path unproven until you diagnose it later.
- Sign in to the AWS Management Console.
- Choose US East (N. Virginia) (us-east-1) in the region selector.
- Use the console search to open Amazon EC2.
- Choose Launch instance.
- Enter session4-docker-host as the instance name.
- Choose Amazon Linux 2023 under Application and OS Images (Amazon Machine Image).
- Choose t3.small under Instance type.
Why Use t3.small?
The t3.small instance provides 2.0 GiB of memory. That capacity gives unknown Python dependencies more room during the remote image build.
- Create a key pair named session4-ec2 under Key pair (login).
- Select RSA as the key type.
- Select PEM as the private key format.
- Complete the key pair creation to download session4-ec2.pem.
What Does the Key Pair Protect?
The downloaded PEM file proves your identity when you connect with OpenSSH. AWS keeps the matching public key on the instance.
Keep the private file on your Mac. Anyone with access to that file could attempt to use the same identity.
- Select a default public subnet under Network settings.
- Enable Auto-assign Public IP.
- Create a security group for the instance.
- Add an inbound SSH rule for TCP 22.
- Choose My IP as the SSH source.
- Confirm that no inbound rule exists for TCP 8000.
- Set the root volume size to 8 GB under Configure storage.
- Select gp3 as the root volume type.
Using a Custom VPC?
Your account may not have a default VPC. An existing subnet works when its route table sends 0.0.0.0/0 to an internet gateway.
- Select an existing subnet with that public route.
Know the Cost Before Launching
Launching begins billable usage. This one-hour configuration costs approximately $0.03 before taxes and data transfer.
The cleanup section removes these resources when you finish. Charges can continue while the instance or storage remains.
- Choose Launch instance.
Provisioning can take a few minutes. The running state confirms that AWS has created the host.
- Wait for session4-docker-host to report a running state.
- Confirm that the instance details show a public IPv4 address.
- Open the route table associated with the instance subnet in the VPC console.
- Confirm that the route table contains 0.0.0.0/0 targeting an internet gateway.
- Return to the instance details from earlier.
- Open the attached security group to confirm its inbound rules.
- Confirm that TCP 22 allows only My IP.
- Confirm that TCP 8000 has no inbound rule.
What Does This Prove?
The public address plus the internet gateway route establishes the path between the subnet and the internet. The security group still decides which inbound connections may cross that path.
At this point, SSH has a permitted path. Application traffic on port 8000 does not.
- Record the instance public DNS name here: your EC2 public DNS name.
The cloud foundation is now in place. Your instance has the public path needed for management while the application port remains closed.
Protect the key and connect
The PEM file is the credential for your EC2 login. Restrictive file permissions prevent other local users from reading it.
The shell variables keep the key path and public DNS name available for later SSH and SCP commands. They last for the current Terminal session.
- Switch back to the macOS Terminal session from earlier.
- Replace paste-public-dns-here in the command block with your EC2 public DNS name.
- Prepare a reusable SSH session securely by running these commands:
chmod 400 ~/Downloads/session4-ec2.pem
export KEY_PATH="$HOME/Downloads/session4-ec2.pem"
export EC2_HOST="paste-public-dns-here"
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST"
What Do These Commands Do?
- The chmod command applies permission value 400 so only your local user can read the private key.
- The KEY_PATH variable stores the private key location.
- The EC2_HOST variable stores the instance public DNS name.
- The ssh command connects with the Amazon Linux user ec2-user.
You should reach a shell prompt on the EC2 instance. That prompt confirms that the public route plus the restricted SSH rule work together.
Unable to Reach the EC2 Shell?
- Check that ~/Downloads/session4-ec2.pem matches the key file downloaded by your browser.
- Check that EC2_HOST contains the instance public DNS name.
- Refresh the SSH source if your current public IPv4 address has changed since launch.
- Use Help me diagnose why my SSH connection to the EC2 instance is failing.
Install Docker Engine
Docker runs through a background daemon on the EC2 host. The ec2-user account needs Docker group membership before it can use that daemon without elevated privileges.
Linux applies new group membership when a login session starts. Exiting after the group change ensures that your next SSH session receives the new access.
The package update can take a few minutes while Amazon Linux refreshes installed software. A quiet pause during that work is normal.
- Review the package summary if the installer asks for confirmation.
- Prepare Docker Engine by running each command below in order:
sudo yum update -y
sudo yum install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
exit
How Does This Prepare Docker?
- The first command updates the installed Amazon Linux packages.
- The second command installs Docker Engine.
- The third command starts the Docker service.
- The fourth command adds ec2-user to the docker group.
- The final command closes the old login session.
You should return to your Mac shell after the final command. The Docker group change is ready for a new login session.
Did the Docker Installation Stop?
- Confirm that the instance still has its public IPv4 address.
- Confirm that the subnet route still targets an internet gateway.
- Reconnect to the instance before retrying the failed package command.
- Use Help me diagnose a Docker installation failure on Amazon Linux 2023.
Before you run the check, do you think the new login can communicate with Docker without elevated privileges?
- Verify Docker access from a fresh EC2 login by running these commands:
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST"
docker info
What Should You See?
The SSH command starts a fresh login with the updated group membership. The Docker check should print daemon information without a permission error.
That output proves that Docker Engine is running. It also proves that ec2-user can communicate with the daemon.
Seeing a Docker Permission Error?
- Confirm that you exited the original EC2 session after changing group membership.
- Start another fresh SSH session before repeating the Docker check.
- Confirm that the Docker service started successfully during installation.
- Use Help me fix Docker permissions for ec2-user after reconnecting.
That completes the host preparation. Your EC2 instance can now build and run containers through the regular Amazon Linux user.
Your public Docker host is ready with a restricted management path. Next, you will copy the existing source to EC2 and build the same image on the server.
Deploy the Container to EC2
Your Amazon EC2 host now accepts SSH connections. Docker Engine is ready to build the application into a container image on the server.
Building from the copied source avoids registry credentials. It also keeps Mac CPU architecture differences out of the deployment path.
In this step, get ready to:
- Copy the exact application build context to EC2.
- Build the application image on the EC2 host.
- Prove the running container answers an EC2-local request.
Copy the build context to EC2
The build context contains everything Docker needs to create the image. For this application, it includes app/, requirements.txt, and Dockerfile.
- Return to the Mac shell from earlier by running the first command below.
- Create ~/session4-app on EC2 by running the second command below.
- Copy the exact build context by running the third command below.
- Reconnect to EC2 by running the final command below.
exit
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST" 'mkdir -p ~/session4-app'
scp -i "$KEY_PATH" -r ./app ./requirements.txt ./Dockerfile "ec2-user@$EC2_HOST:~/session4-app/"
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST"
What does this command sequence do?
- The exit command closes the remote shell from the previous step.
- The first ssh command creates ~/session4-app on the EC2 host.
- The scp command transfers the application directory plus both build files.
- The final ssh command returns you to the EC2 shell.
- Confirm the transfer output names files from app/, requirements.txt, and Dockerfile.
- Confirm the final command leaves you at the EC2 shell prompt.
Having trouble copying the files?
- Check that your Mac shell is still inside the application folder containing app/, requirements.txt, and Dockerfile.
- Check that KEY_PATH still points to ~/Downloads/session4-ec2.pem.
- Check that EC2_HOST still contains the instance public DNS name.
- Help me debug the EC2 file transfer.
Build the image on EC2
The copied Dockerfile now becomes the source of the EC2 image. Building it on the host keeps this exercise focused on the network path.
- Build session4-app:local from the copied context by running these commands:
cd ~/session4-app
docker build -t session4-app:local .
What does this build do?
- The cd command switches the EC2 shell into the copied project directory.
- The docker build command reads the local Dockerfile from that directory.
- The -t option assigns the image name session4-app:local.
- Confirm the build completes without an error.
- Confirm the final build output identifies session4-app:local as the image tag.
Good progress. Your EC2 host now has an image built from the same source that worked on your Mac.
Did the image build fail?
- Check that the shell is inside ~/session4-app.
- Check that the transfer completed for Dockerfile and requirements.txt.
- Help me diagnose the EC2 image build.
Run and verify the EC2 container
Docker port publishing connects a host port to a container port. The -p 8000:8000 option publishes container port 8000 through host port 8000 on every host interface.
The attached security group still has no inbound TCP 8000 rule. This local test isolates the application path inside EC2.
- Start the container with port 8000 published by running the first command below.
- List the running containers by running the second command below.
- Read the latest startup logs by running the final command below.
docker run -d --name session4-app -p 8000:8000 session4-app:local
docker ps
docker logs --tail 20 session4-app
What happens when the container starts?
- The -d option keeps the container running in the background.
- The --name session4-app option gives the container a stable name for later checks.
- The -p 8000:8000 option publishes the application through the EC2 host.
- The final two commands confirm the container state plus the latest application output.
- Confirm docker ps lists session4-app as a running container.
- Confirm the log output shows that the application started.
Is the container missing from docker ps?
- Read the container logs for a startup failure.
- Check that the image name is exactly session4-app:local.
- Help me diagnose why the EC2 container stopped.
Before you test from inside EC2, do you expect the request to reach the application while the security group still blocks inbound port 8000?
- Request the application through the EC2 loopback interface by running:
curl --connect-timeout 5 -v http://127.0.0.1:8000/
Why does any HTTP status count?
An HTTP status line proves that the request crossed the EC2 host port and reached the application. The specific route response does not change that transport result.
You should see an HTTP status line in the verbose output. A 404 Not Found response at / still proves that the request reached the application.
- Confirm the application recorded the EC2-local request by running:
docker logs --tail 20 session4-app
What do the final logs prove?
The latest access log corresponds to the request you just made. This links the client response to evidence from inside the container.
That is the server-side deployment working. Your EC2 host can reach the container through published port 8000.
✔️ Awesome, I've got everything!
Your EC2 image runs as session4-app with host port 8000 published. The EC2-local request reaches the application.
The matching container log confirms that the request reached the server process.
ⓧ I'd like to double check the full command flow
This reference shows the complete command flow for the deployment. Compare it with the commands in your terminal history.
exit
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST" 'mkdir -p ~/session4-app'
scp -i "$KEY_PATH" -r ./app ./requirements.txt ./Dockerfile "ec2-user@$EC2_HOST:~/session4-app/"
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST"
cd ~/session4-app
docker build -t session4-app:local .
docker run -d --name session4-app -p 8000:8000 session4-app:local
docker ps
docker logs --tail 20 session4-app
curl --connect-timeout 5 -v http://127.0.0.1:8000/
docker logs --tail 20 session4-app
How is this flow ordered?
The first four lines leave the earlier EC2 session. They create the remote directory before transferring the build context.
The remaining lines build the image. They start the container before testing the local network path.
- The ~/session4-app directory contains app/, requirements.txt, and Dockerfile.
- The EC2 host contains the image session4-app:local.
- The container session4-app is running with -p 8000:8000.
- The request to http://127.0.0.1:8000/ returns an HTTP status line.
- The container logs record the EC2-local request.
- The security group still permits inbound SSH only from your current public IPv4 address.
- The security group still has no inbound rule for port 8000.
The container works from inside EC2. Next, you'll trace the same request from your Mac to find the first network boundary that blocks it.
Prove Where External Access Breaks
Your Docker container now returns an HTTP response from inside Amazon EC2. That proves the application works on its cloud host.
External traffic must cross several more boundaries before it reaches the container. Checking those boundaries in order keeps the working application untouched while you locate the first gap.
In this step, get ready to:
- Collect evidence from the application and host-side port publication.
- Test the application port from your Mac.
- Locate the first unproven boundary in the attached security group.
Prove the internal path
An inside-out diagnosis begins beside the application. The logs prove that requests reach the container. The published port proves that Docker exposes the service through the EC2 host.
- Collect evidence from the running container and EC2 host by running these commands in your existing SSH session:
docker logs --tail 20 session4-app
docker port session4-app 8000/tcp
curl --connect-timeout 5 -v http://127.0.0.1:8000/
What Does This Evidence Prove?
- The first command shows recent requests handled by the running container.
- The second command reports how container port 8000 is published through the EC2 host.
- The final request tests the service from the host itself.
You should see port 8000 published on all host interfaces. You should also see an HTTP status line from the local request.
The matching log entry connects the client request to the running application. Together, these signals prove the application layer and the host-side Docker publication.
Missing One of the Three Signals?
- Check that your terminal prompt belongs to the EC2 host before repeating the evidence commands.
- Confirm that each command uses the running container name session4-app.
- Ask for help with the missing signal.
Test the public endpoint from your Mac
The internal path is proven. Moving the same request to your Mac tests whether traffic can cross the public network path and reach the EC2 host.
Before you run this check, do you think the external request reaches the same HTTP response?
- Move the request outside EC2 by running these commands:
exit
curl --connect-timeout 5 -v "http://$EC2_HOST:8000/"
What Do These Commands Test?
- The first command closes your SSH session and returns you to the Mac.
- The second command targets port 8000 through the EC2 public address stored in EC2_HOST.
- The connection timeout limits this test to five seconds.
You should see the connection stop after five seconds without an HTTP status line. This timeout is the evidence you were looking for.
Why This Timeout Matters
The EC2-local request already proved the application and host publication. The timeout moves your search to the public network boundaries after the host.
Trace the remaining public path
Public reachability depends on an address for the instance and a route through an internet gateway. Once those conditions are proven, the inbound traffic rules become the final boundary to inspect.
- Switch back to the AWS Management Console browser tab from earlier.
- Select session4-docker-host from the Amazon EC2 instance list.
- Confirm that Public IPv4 address contains an address for the instance.
- Select the subnet linked from the instance details.
- Inspect the route table associated with that subnet.
- Confirm that the route table contains destination 0.0.0.0/0 with an internet gateway as its target.
The public IPv4 address gives your Mac a destination. The internet gateway route gives the subnet a path to the internet.
Before you inspect the final boundary, which layer do you expect is still unproven?
- Return to the instance details for session4-docker-host.
- Select the security group attached to the instance.
- Inspect the rules listed for inbound traffic.
- Confirm that SSH on TCP 22 uses My IP as its source.
- Confirm that no Custom TCP rule has port range 8000.
- Leave the inbound rules unchanged.
You should see the SSH rule from your current public IPv4 address and no inbound TCP 8000 rule. The security group is the first unproven boundary and the blocker behind the Mac timeout.
You isolated the security group without changing a working container. Next, you will open only the network path your evidence identified.
Open the Smallest Safe Network Path
Your inside-out checks proved that the application responds on the Amazon EC2 host. They isolated the missing security group rule as the blocked boundary.
The next move is one inbound rule for TCP port 8000 from your current public IPv4 address. This uses least-privilege access to fix the diagnosed blocker without exposing the development server to every IPv4 address.
In this step, get ready to:
- Add a port 8000 inbound rule from My IP.
- Repeat the timed request from the Mac.
- Confirm the successful request in the Docker logs over SSH.
Add the restricted ingress rule
Inbound rules decide which external traffic may reach the instance. The application needs one rule that matches its published port.
- Return to the security group attached to session4-docker-host in the EC2 console from earlier.
- Choose Edit inbound rules.
- Select Custom TCP in the Type field.
- Enter 8000 in Port range.
- Select My IP in Source.
The new row should show Custom TCP, port 8000, and My IP.
Why Use My IP?
The My IP option fills the source with your Mac's public IPv4 address. The rule permits only that source to start a connection on port 8000.
The Anywhere-IPv4 option permits every IPv4 address. Leaving it unused keeps the application rule narrowly scoped.
- Leave Anywhere-IPv4 unused for application port 8000.
- Choose Save rules.
Good call. The saved rule gives you one narrow path to test.
- Confirm the saved rules show port 22 from My IP.
- Confirm the saved rules show port 8000 from My IP.
- Confirm no application rule uses Anywhere-IPv4.
Retest the blocked request
The application remains unchanged. Repeating the same request isolates the security group rule as the only changed boundary.
- Predict whether the same request now crosses the security group.
- Repeat the timed request from the Mac by running this command:
curl --connect-timeout 5 -v "http://$EC2_HOST:8000/"
What Does This Prove?
An HTTP status line proves the request crossed the public network path. A response from Uvicorn confirms that traffic reached the application.
You found the blocker. The same request that timed out now reaches the application through the restricted rule.
Still Seeing a Timeout?
- Confirm the Custom TCP rule shows 8000 under Port range.
- Reselect My IP in Source if your Mac's public IPv4 address changed.
- Help me diagnose the timeout.
Correlate the request with Docker evidence
A client response proves public reachability. A matching container access entry ties that response to the running service.
The port report completes the check by showing that host publication stayed on all interfaces.
- Predict whether the latest external request appears in the container logs.
- Collect the server-side evidence from the Mac by running these commands:
ssh -i "$KEY_PATH" "ec2-user@$EC2_HOST"
docker logs --tail 20 session4-app
docker port session4-app 8000/tcp
How the Evidence Connects
- The SSH command returns you to session4-docker-host.
- The log command shows the newest 20 lines from session4-app. A fresh access entry ties the Mac response to this container.
- The port command confirms that host port 8000 still maps to container port 8000 on all host interfaces.
You should see a new access entry for the request from your Mac. The port report should still show host port 8000 published on all interfaces.
No New Access Entry?
- Repeat the successful Mac request before checking the logs again.
- Confirm the logs belong to session4-app.
- Help me connect the client response to the logs.
Strong diagnosis. Your app now accepts traffic on port 8000 only from your current public IPv4 address.
The matching client response plus container log show exactly where the fix took effect.
Secret mission
Break Docker's Host Binding
A correct security group cannot overcome a loopback-only Docker publication. You will recreate the timeout with that binding. You will prove the cause. Then you will restore access on all host interfaces.
Clean Up Your Resources
Clean Up Your Resources
Choose whether to keep the cloud deployment running, pause it for later, or delete it entirely. Keeping the deployment running costs approximately $0.03 for one hour before taxes or data transfer.
Cost warning
The running Amazon EC2 instance incurs compute charges. Its public IPv4 address incurs an hourly charge.
Stopping the instance leaves storage charges in place. Terminating the instance removes the root volume when Delete on termination is enabled.
Resources you used:
- The running session4-docker-host instance containing ~/session4-app plus the remote image and container.
- The 8 GB gp3 Amazon EBS root volume configured for deletion with the instance.
- The public IPv4 address used to reach session4-docker-host.
- The local Docker image tagged session4-app:local on your Mac.
Keep everything running
No action needed. Choose this if you plan to keep testing the application from your Mac.
- Leave session4-docker-host running in Amazon EC2.
- Keep the restored session4-app container running with port 8000 published on all host interfaces.
- Budget approximately $0.03 for each hour that the current deployment remains active.
Pause - I'll come back to this later
Pausing the instance stops the application while preserving its root volume. Storage charges continue until you terminate the instance.
- Select session4-docker-host in the Amazon EC2 instances list.
- Use the instance state controls to stop it.
- Wait until the instance status confirms that it has stopped.
- Check the Public IPv4 address after starting the instance again.
- Update EC2_HOST with the current address before reconnecting.
The application remains unavailable while the instance is stopped. Your remote image and project directory remain on the root volume.
Delete - I don't want to use this again
Deleting the instance is permanent. Your original application source on the Mac remains untouched.
- Select session4-docker-host in the Amazon EC2 instances list.
- Confirm that the root volume has Delete on termination enabled in the instance storage details.
- Choose Instance state.
- Choose Terminate (delete) instance.
- Confirm the deletion by choosing Terminate (delete).
- Wait until the instance status confirms that termination is complete.
What does termination remove?
Termination permanently removes session4-docker-host. The enabled root-volume setting also removes ~/session4-app plus the remote image and container.
The former public IPv4 address stops serving this instance. The application can no longer accumulate compute charges.
- Repeat the Mac request from Step 5.
You should no longer receive an HTTP response from the terminated deployment.
- Remove the local image from your Mac by running:
docker image rm session4-app:local
What does this remove?
This command removes only the local image tagged session4-app:local from your Mac.
Your existing application source remains available for future builds.
- Confirm in Docker Desktop that session4-app:local no longer appears among your local images.
Image still listed?
- Confirm that you ran the image removal command on your Mac.
- Remove any local container that still uses session4-app:local before trying again.
- Use help me remove the local Docker image if the image remains.
Nice Work!
Nice Work!
Excellent work! You deployed the existing application with Docker on Amazon EC2. You also turned two similar connection timeouts into clear evidence about where traffic stopped.
You've learned how to:
- Build and validate a container image on your Mac. Rebuild the same image from transferred source on the EC2 host.
- Apply an inside-out diagnosis across the application, container, and host. Follow the evidence through the VPC route, public address, and security group.
- Restore external access with least-privilege ingress on TCP port 8000. Restrict that access to your current public IPv4 address. Correlate the successful Mac request with the container log.
- Secret Mission: Reproduced a loopback-only host binding failure. Proved why security group ingress could not repair a service published only on 127.0.0.1. Restored the publication across all host interfaces.
Ready to quiz yourself?