Article Details

AWS Corporate Verification Deploy Docker on AWS EC2

AWS Account2026-05-15 15:48:09OrbitCloud

Deploy Docker on AWS EC2

Docker on AWS EC2 is the kind of thing that sounds intimidating until you actually do it. Then it’s mostly like assembling furniture: a few steps feel silly, you double-check a couple screws, and suddenly you’ve built something that keeps your stuff running reliably instead of flopping around on your laptop like a half-inflated air mattress.

In this guide, we’ll walk through the full journey: picking an EC2 instance, securing it, installing Docker, running a test container, and deploying a real application container. We’ll also touch on persistence, logging, and a few operational habits that make you look like a calm professional instead of a panicked wizard.

Assumptions: You have an AWS account, basic familiarity with the AWS Console, and a local computer where you can build a Docker image. If you don’t have all that, no worries—you can still follow along and adapt the steps.

What You’re Actually Building

At the end of this tutorial, you’ll have an EC2 virtual machine running Docker. Docker will run your application inside a container. When you send requests to the EC2 instance, they’ll reach the container. Optionally, you’ll store data persistently so that container restarts don’t wipe your world.

Think of EC2 as your physical stage and Docker as the crew that sets up the props. You could do everything directly on the EC2 machine, but Docker makes packaging and deployment consistent. It’s like moving houses: instead of explaining your entire kitchen to every new roommate, you ship a fully furnished set.

Prerequisites

Before you start, prepare a few things so the universe doesn’t ambush you later:

  • An AWS account with permission to launch EC2 instances.
  • AWS Corporate Verification A key pair for SSH access (or the ability to create one).
  • Docker installed locally to build an image (optional but recommended).
  • Your application packaged as a Docker image (we’ll use an example so you can follow).

You do not need to be a DevOps superhero. You just need patience, and perhaps a snack. Deployment is 30% command line and 70% waiting for AWS to finish doing AWS things.

Step 1: Choose an EC2 Instance

A common beginner move is to pick the smallest instance and then later regret it when Docker pulls images, your app starts compiling, and everything feels like it’s running through wet cement. For a simple web app, a t3.small or t3.micro instance is often fine, but if you expect heavier usage, choose accordingly.

Here’s a reasonable default approach:

  • Instance type: t3.small (good balance for learning)
  • OS: Ubuntu Server 22.04 LTS (or Amazon Linux 2023, if you prefer)
  • AWS Corporate Verification Security groups: configured later

In the AWS Console:

  • Go to EC2 → Instances → Launch instances.
  • Choose an Amazon Machine Image (AMI), such as Ubuntu Server 22.04 LTS.
  • Select an instance type (t3.small is a decent starting point).
  • Create or select a key pair for SSH.

For learning purposes, a small instance is great. For production, you’d pick based on load testing and cost constraints. We’re not trying to run Netflix here. Yet.

Step 2: Configure Security Group Rules

Your security group is the bouncer at the club. It decides who can enter and who gets turned away at the door. For Docker deployment, you typically need:

  • SSH access (port 22) from your IP address
  • Application traffic (example: port 80 or 3000) from the internet (or at least from your desired sources)

In the EC2 Launch wizard, under “Security group” you can add rules:

  • Inbound rule: SSH (TCP 22), source = your IP address (recommended)
  • Inbound rule: HTTP (TCP 80) or a custom port your app uses (e.g., 3000)

Important: Don’t open SSH to “0.0.0.0/0” unless you enjoy living dangerously. It’s not illegal, but it’s close to summoning trouble.

If you’re deploying a web app that listens on port 80 inside the container, you’ll likely map EC2 port 80 to container port 80. That’s the easiest configuration for beginners.

Step 3: Connect to Your EC2 Instance

Once your instance is running, connect via SSH. In the AWS Console, open the instance details page and use the “Connect” button. It will show you a command using your key pair.

Example SSH command (you’ll adjust the username and key file path):

ssh -i /path/to/your-key.pem ubuntu@<EC2_PUBLIC_IP>

If you chose Ubuntu, the username is usually “ubuntu”. For Amazon Linux, it’s typically “ec2-user”.

Now you have access to the machine where Docker will live. Go ahead and feel powerful for a moment. Then we install Docker.

Step 4: Install Docker on EC2

We’ll use an Ubuntu-based example. The process on other distros is similar, but package names and service management commands might differ.

Update package list

sudo apt update

Install Docker prerequisites

sudo apt install -y ca-certificates curl gnupg

AWS Corporate Verification Add Docker’s official GPG key and repository

On many systems, Docker’s repository setup steps are straightforward. If you follow Docker’s official instructions for your OS, you’ll avoid the “why doesn’t apt know about Docker” phase of grief.

Common pattern:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Install Docker Engine

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

Start and enable Docker

sudo systemctl enable docker
sudo systemctl start docker

Verify Docker works

sudo docker version
sudo docker run hello-world

If you see Docker doing the happy dance (it usually prints a friendly message), you’re ready for the next step.

Step 5: Manage Docker Permissions (So You Don’t Use sudo Forever)

By default, Docker commands may require root privileges via sudo. That’s safe, but it’s also annoying. A common fix is to add your user to the “docker” group.

On Ubuntu, your SSH user might be “ubuntu”. Do this:

sudo usermod -aG docker $USER
newgrp docker

Then re-check:

docker ps

If it works without sudo, congratulations—you’ve banished some friction.

If it doesn’t, log out and log back in (or reboot). Linux sometimes needs an extra moment to update group membership like it’s a sleepy cat refusing to get out of bed.

Step 6: Run a Test Container

Before deploying your app, run a simple container to prove networking and container execution are working. The “hello-world” image is great for verifying Docker installation, but it doesn’t test port mapping.

Let’s run a lightweight web server container that listens on a port. For example, use nginx:

docker run -d --name web-test -p 80:80 nginx:alpine

Now test it from your laptop:

  • Open a browser and go to http://<EC2_PUBLIC_IP>
  • Or use curl: curl http://<EC2_PUBLIC_IP>

If you see the nginx welcome page, you’ve confirmed that:

  • Your EC2 inbound firewall (security group) allows traffic
  • AWS Corporate Verification Your container publishes ports correctly

If it doesn’t work, the problem is usually one of these:

  • Security group inbound rule missing for port 80 (or whatever port you used)
  • You mapped the wrong port (e.g., -p 8080:80)
  • The container isn’t running (docker ps)

To check logs:

docker logs web-test

AWS Corporate Verification Step 7: Deploy Your Application Container

Now the fun part: running your own Docker image. There are two common approaches:

  • Build locally, then push to a registry (recommended): Docker Hub or Amazon ECR.
  • Build directly on the EC2 instance (okay for small apps, but slower and more error-prone).

For learning and real deployments, using a registry is cleaner. It’s also easier to redeploy updates.

Recommended approach: Use Amazon ECR

Amazon Elastic Container Registry (ECR) is AWS’s container image registry. It’s integrated with AWS identity and makes private images easy.

The high-level steps are:

  1. Create an ECR repository.
  2. Authenticate Docker to ECR.
  3. AWS Corporate Verification Build your image locally.
  4. Tag and push the image to ECR.
  5. On EC2, pull the image and run the container.

1) Create an ECR repository

  • Go to AWS Console → ECR → Repositories → Create repository.
  • Name it something like my-app.

You’ll get repository URI info that looks like:

<aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-app

2) Login Docker to ECR

On your local machine (or anywhere you can run docker commands), you can use the AWS CLI to get login credentials. Exact commands depend on your setup, but you’ll typically use:

aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <registry_uri>

If you don’t have AWS CLI installed locally yet, you can install it, or run the push from your CI system. Again, no need to overcomplicate life on day one.

3) Build your Docker image

Assuming you have a project folder with a Dockerfile, build it:

docker build -t my-app:latest .

Let’s include a simple conceptual example. If your app is a Node.js server, your Dockerfile might expose port 3000 and start the server. If it’s a Python Flask app, you’d likely expose port 5000. The principle is the same.

4) Tag the image for ECR and push

docker tag my-app:latest <aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-app:latest
docker push <aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-app:latest

When the push completes, the image is stored in ECR and ready to be pulled by your EC2 instance.

Step 8: Pull the image on EC2 and run it

On your EC2 instance, you need permission to pull from ECR. The easiest way is to attach an IAM role to the EC2 instance (not to hardcode AWS keys in your machine like it’s a cursed artifact).

Create an IAM role with permissions like:

  • AmazonEC2ContainerRegistryReadOnly

Attach this role to your EC2 instance:

  • EC2 Console → Instances → Your instance → Actions → Security → Modify IAM role

After it’s attached, you can pull images.

On EC2, install AWS CLI if needed (often it’s already present on Amazon Linux; on Ubuntu it might not be). If you have aws cli installed, run:

aws ecr get-login-password --region <region> | sudo docker login --username AWS --password-stdin <registry_uri>

Then pull and run the container:

sudo docker pull <aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-app:latest
sudo docker run -d --name my-app -p 80:3000 <aws_account_id>.dkr.ecr.<region>.amazonaws.com/my-app:latest

This assumes your app listens on port 3000 inside the container, and you want it accessible on port 80 from outside. Adjust the port mapping to match your app.

Step 9: Use Docker Compose (Optional, But Highly Recommended)

If your application is more than one container (for example, app + database + redis), Docker Compose saves your sanity. Even if you deploy on EC2 without Compose, you’ll soon feel the urge to document the command line rituals you keep repeating.

With Compose, you define services in a docker-compose.yml file and start everything with a single command.

Example concept (not guaranteed to match your stack):

version: '3.8'
services:
  app:
    image: my-app:latest
    ports:
      - "80:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/app
  db:
    image: postgres:16
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

Then on EC2:

docker compose up -d

If Compose isn’t installed, you can typically install it, or use the Docker Compose plugin depending on your Docker version.

Even if you don’t use Compose now, consider it for the moment your “simple demo” becomes a “simple production-ish setup.” That moment always arrives. Eventually. Like a bill.

Step 10: Persist Data (Because Containers Are Not Magic)

Containers are designed to be disposable. That’s their superpower. But it can also be a trap if you store your important data inside the container filesystem.

If you run a container without persistence and then restart or recreate it, your data might be gone. That might be okay for stateless services, but not for databases or user uploads.

There are two common persistence approaches on EC2:

  • Docker volumes: good for local persistence while the EC2 instance persists.
  • Bind mounts: map directories on the host into the container.
  • Use AWS storage: EFS (shared), S3 (object storage), or EBS (block storage) depending on needs.

For example, for a database container like Postgres, you’d map a volume:

docker volume create db-data

docker run -d --name postgres \
  -e POSTGRES_PASSWORD=secret \
  -e POSTGRES_USER=app \
  -e POSTGRES_DB=appdb \
  -v db-data:/var/lib/postgresql/data \
  -p 5432:5432 postgres:16

This way, restarting the container keeps data in the volume. If you rebuild the container, the volume stays.

If you need long-term persistence beyond the lifecycle of the EC2 instance, use EBS/EFS or a managed database service like RDS. For production, you usually don’t want to manage databases manually unless you enjoy it and you have time, confidence, and strong coffee.

Step 11: Logging and Monitoring (So You Can Debug Like a Human)

You’ll want to see what your containers are doing, especially when something breaks at 2 a.m. and your future self is writing frantic messages to present you.

Basic logging commands:

  • View container logs: docker logs my-app
  • Follow logs live: docker logs -f my-app
  • Inspect container details: docker inspect my-app

Example:

docker logs -f my-app

If you use a platform like CloudWatch Logs, you can aggregate logs centrally. This is a big step toward being able to answer “what happened?” with evidence instead of vibes.

For monitoring, also consider:

  • Health checks (at the app level and/or Docker level)
  • Basic uptime checks
  • Metrics collection (CPU, memory, network)

Step 12: Keep Your Deployment Up to Date

When you build a new version of your app, you’ll repeat a familiar dance:

  • Build new image
  • Push to ECR
  • On EC2, pull new image
  • Stop old container and start new one

Here’s a straightforward container refresh workflow:

# Pull latest image
sudo docker pull <registry_uri>/my-app:latest

# Stop old container
sudo docker stop my-app

# Remove old container (optional, but helps keep things tidy)
sudo docker rm my-app

# Run new container
sudo docker run -d --name my-app -p 80:3000 <registry_uri>/my-app:latest

For a more polished workflow, you can:

  • Use version tags instead of always using :latest
  • Automate with scripts, systemd services, or CI/CD pipelines
  • Use rolling deployments if you run multiple instances

Step 13: Make It Restart Automatically (Because Reboots Happen)

EC2 instances can restart for maintenance, crashes, updates, or random “because the cloud said so” reasons. You want your containers to come back automatically.

The simplest approach is to use a restart policy:

sudo docker run -d --restart unless-stopped --name my-app -p 80:3000 <image>

Common restart policies:

  • no: don’t restart
  • on-failure[:max-retries]: restart when container exits with non-zero code
  • always: restart always
  • AWS Corporate Verification unless-stopped: restart unless you stop it manually

For most simple deployments, unless-stopped is a good default. It’s like telling your container, “Stay put unless I specifically kick you out.”

Step 14: Troubleshooting the Most Common Problems

Let’s cover the greatest hits. If something goes wrong, it’s usually one of these.

1) Container is running, but you can’t access it from the internet

Check:

  • Security group inbound rules include the port you’re exposing (e.g., 80).
  • You mapped ports correctly with -p EC2_PORT:CONTAINER_PORT.
  • Your app inside the container listens on the expected port and binds to 0.0.0.0 (not only localhost).

Inside EC2, verify port mapping:

sudo docker ps

If needed, check listening ports (install tools if necessary):

sudo apt install -y net-tools
sudo netstat -tulpn

2) Permission errors when using Docker

AWS Corporate Verification If you see “permission denied while trying to connect to the Docker daemon,” you likely need to add your user to the docker group or use sudo.

Fix (as shown earlier):

sudo usermod -aG docker $USER
newgrp docker

Log out/in if needed.

3) ECR pull fails with authentication errors

Check:

  • The EC2 instance IAM role has ECR read permissions.
  • You ran docker login to the correct ECR registry URI.
  • You’re using the correct region.

Also check the aws CLI is configured or that the instance metadata permissions are working (no need to store AWS keys manually).

4) Your container keeps restarting

Check logs:

docker logs my-app

Common reasons include:

  • The app crashes on startup.
  • Wrong environment variables.
  • AWS Corporate Verification Database connection issues.
  • Missing secrets or config files.

Restart loops are often fixable once you read the logs. Not glamorous, but effective.

Step 15: Environment Variables and Secrets

You’ll probably need configuration values: database URLs, API keys, or service endpoints. Environment variables are common for container configuration.

Example:

sudo docker run -d --restart unless-stopped --name my-app \
  -e APP_ENV=production \
  -e DATABASE_URL='postgres://app:secret@host:5432/appdb' \
  -p 80:3000 \
  <image>

In production, avoid hardcoding secrets into images. Instead, use AWS services like:

  • AWS Secrets Manager
  • SSM Parameter Store

This guide focuses on Docker deployment basics, but it’s worth planning for secrets early. Your future self will thank you, and so will your security team (if you have one, or if you wish you did).

Step 16: Hardening the Setup (Optional but Sensible)

If you want to be a responsible adult (or at least behave like one), consider:

  • Use least-privilege IAM roles for EC2.
  • Restrict SSH access to your IP.
  • Use HTTPS by putting a reverse proxy in front (often with an ALB/ELB, Nginx, or a managed service).
  • Keep Docker and OS updated.

For HTTPS, a typical approach is to use an Application Load Balancer with a certificate and forward traffic to your EC2 instance. Docker can stay blissfully unaware of certificates, like a chef who never wants to handle paperwork.

A Mini End-to-End Example (Putting It All Together)

Let’s pretend we’re deploying a simple web app that listens on port 3000 inside the container. Our goal is to map it to port 80 on EC2.

1) Launch Ubuntu EC2 instance (t3.small), attach key pair, open inbound SSH from your IP.

2) Add inbound rule for HTTP (80) from wherever you need.

3) SSH into EC2.

4) Install Docker, start service, and run hello-world.

5) Run nginx test container with -p 80:80 to validate networking.

6) Create ECR repository my-app and push your image.

7) Attach IAM role to EC2 with ECR read permissions.

8) On EC2, docker login to ECR, docker pull your image.

9) Run the app container with:

sudo docker run -d --restart unless-stopped --name my-app -p 80:3000 <ecr-uri>/my-app:latest

10) Test by visiting http://<EC2_PUBLIC_IP>.

If it loads, you’re done. If it doesn’t, you troubleshoot by checking security group rules, docker ps, and docker logs. That’s the whole game: verify each layer until you find the weak link.

Conclusion

Deploying Docker on AWS EC2 is a practical skill that pays off fast. You learn how to turn an EC2 instance into a container host, how to secure it, how to run containers, and how to deploy updates without fear. Along the way, you pick up the habits that distinguish “I got it working once” from “I can operate this reliably.”

If you remember one thing, make it this: containers are predictable, but networks and permissions are the occasional chaos gremlins. When something breaks, check security groups, port mappings, and container logs. Most problems shrink instantly once you stop guessing and start observing.

Next steps, if you want to level up: automate deployments with CI/CD, add a load balancer for scalability, use ECS or EKS if you want AWS-native container orchestration, and implement proper secret management. But for now, you’ve successfully marched Docker onto EC2, which is more than enough heroics for one article.

TelegramContact Us
CS ID
@cloudcup
TelegramSupport
CS ID
@yanhuacloud