AWS EC2 Public
sg • eip • ssh • web

Expose an app with AWS EC2 and Elastic IP

A practical guide to launching an AWS EC2 instance, understanding Security Groups, attaching an Elastic IP, and exposing an app to the internet more safely.

10 min read16/06/2026

If you are new to AWS, the confusing part is usually not launching EC2 itself. The real friction starts right after that: which ports should you open, when do you need an Elastic IP, and how do you expose an app to the internet without opening too much? This guide follows that exact flow.

When should you use EC2?

EC2 is a good fit when you need a Linux machine that keeps running for:

  • deploying a backend
  • running an internal database or Redis
  • building a test environment
  • hosting a web app, API, or worker

If you only need to run a small app and do not want to manage a server, ECS Fargate, App Runner, or Lightsail may be simpler. But if you want to understand AWS infrastructure from the ground up, EC2 is still the easiest starting point.

4 concepts to understand before clicking Launch

What is EC2 in this context?

Think of EC2 as a virtual machine running inside AWS. You choose:

  • an operating system such as Ubuntu
  • an instance type such as t3.micro or t3.small
  • EBS storage
  • network rules that define who can reach the machine

What is a Security Group?

A Security Group is the instance-level firewall. It decides:

  • which ports are open
  • which IPs are allowed in
  • what traffic can go out

Examples:

  • open 22 for SSH
  • open 80 for HTTP
  • open 443 for HTTPS
  • do not expose 3306, 5432, or 6379 publicly unless you really need to

What is an Elastic IP?

The default public IPv4 on EC2 can change after you stop and start the instance. An Elastic IP is a static public IP that helps when you need:

  • stable DNS records
  • a public IP that does not change after stop/start
  • a long-running server

What does exposing an app publicly mean?

It means users on the internet can reach your app through:

  • a public IP
  • an Elastic IP
  • or a domain pointing to that IP

To make this work, all 4 layers must be correct:

  1. the EC2 instance must have internet routing
  2. the Security Group must allow the right ports
  3. the OS firewall must not block them
  4. the app must listen on the correct address such as 0.0.0.0

Step 1: Launch your first EC2 instance

Open AWS Console -> EC2 -> Instances -> Launch instance.

Minimum setup:

  • Name: for example my-first-ec2
  • AMI: Ubuntu Server 24.04 LTS
  • Instance type: t3.micro or t3.small
  • Key pair: create one if you do not have one yet
  • Network settings: allow SSH from your IP only
  • Storage: 20 GB is enough for a small test box or web app

For a first machine, start with:

  • only SSH open
  • source set to My IP

Do not pre-open many ports unless you already know what the app needs.

Step 2: SSH into the instance

Once the instance is running, copy the public IP and connect:

chmod 400 my-key.pem
ssh -i my-key.pem ubuntu@YOUR_EC2_PUBLIC_IP

If SSH fails, check these first:

  1. the key file is correct
  2. port 22 is open in the Security Group
  3. the source for port 22 matches your current IP
  4. the subnet and route table have internet gateway access

Step 3: Understand Security Group rules the easy way

A common setup for a web app looks like this:

Purpose Port Recommended source
SSH 22 your IP
HTTP 80 0.0.0.0/0
HTTPS 443 0.0.0.0/0

For an app running on 3000, 8000, or 8080:

  • for quick testing, you can expose that port directly
  • for production, it is better to keep the app internal and put Nginx in front on 80/443

Ports you usually should not expose directly:

  • MySQL 3306
  • PostgreSQL 5432
  • Redis 6379
  • MongoDB 27017

If those services must be reachable, prefer:

  • allowing only private IP ranges
  • allowing another Security Group
  • or using SSH tunnels, a bastion host, or a VPN

Step 4: When do you need an Elastic IP?

If this machine will stay online for a while, serve a domain, or needs a stable public IP, attach an Elastic IP.

Go to:

EC2 -> Elastic IPs -> Allocate Elastic IP -> Associate Elastic IP

Attach it to the correct instance.

Good reasons to use an Elastic IP:

  • production server
  • domain-based access
  • whitelisting your IP in third-party services

Cases where you may not need it yet:

  • short-lived test machines
  • temporary labs

Note: an allocated Elastic IP that is not attached can still incur charges. Release it if you no longer need it.

Step 5: Expose your app publicly with fewer mistakes

Quick way for testing

Assume your Node.js app runs on port 3000:

ss -tulpn | grep 3000

If the app is only bound to 127.0.0.1:3000, outside traffic cannot reach it. The app must listen on 0.0.0.0.

Example with Express:

app.listen(3000, "0.0.0.0");

Then add an inbound rule:

  • TCP 3000
  • source 0.0.0.0/0 for temporary testing

At that point you can test:

http://YOUR_ELASTIC_IP:3000

Better approach for production

Do not leave port 3000 publicly exposed long term. Put Nginx in front:

sudo apt update
sudo apt install nginx -y

Example config:

server {
    listen 80;
    server_name _;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable it and reload:

sudo nginx -t
sudo systemctl reload nginx

At this point the Security Group only needs:

  • 80
  • 443

Your backend stays internal on:

  • 127.0.0.1:3000

This is cleaner because:

  • fewer public ports
  • SSL is easier
  • swapping apps behind the proxy is easier
  • logs and rate limiting are easier at the reverse proxy layer

How to make a domain point to it

Once you have an Elastic IP:

  1. go to your DNS provider
  2. create an A record
  3. point the domain or subdomain to the Elastic IP

Example:

  • api.example.com -> 3.25.xx.xx

If you use Nginx, you can then add HTTPS with Let's Encrypt or put the domain behind Cloudflare.

Common mistakes when exposing EC2

The Security Group is open but it still does not work

Usually one of these is wrong:

  • the app is listening on 127.0.0.1 instead of 0.0.0.0
  • Ubuntu ufw is enabled and blocking the port
  • Nginx was not reloaded or the config is invalid
  • you edited the wrong Security Group

Quick checks:

sudo ufw status
ss -tulpn
curl http://127.0.0.1:3000
curl http://YOUR_ELASTIC_IP

SSH works but HTTP does not

That usually means:

  • port 22 is configured correctly
  • but 80 or 443 is not open in the Security Group
  • or the web server is not running

The IP changed after stop/start

That is the point where you need an Elastic IP. The default public IP is not meant to stay fixed long term.

Quick conclusion

If you only want the short version:

  1. launch Ubuntu on EC2
  2. open 22 only for your IP
  3. SSH into the machine
  4. run the app and make sure it listens on 0.0.0.0
  5. in production, expose it through Nginx on 80/443
  6. attach an Elastic IP if you need a stable IP or a domain

If you follow this flow, most “EC2 is running but I still cannot access it from outside” problems become much easier to debug.