Learning AWS in Public — Part 3: From Localhost to the Cloud with Amazon EC2
Learn how to deploy your first web application on Amazon EC2. This beginner-friendly, hands-on guide covers launching a virtual server, connecting through SSH, installing Python and Flask, configuring Nginx, setting up security groups, and making your application accessible over the internet. Understand common deployment errors, basic security practices, and AWS cost considerations while taking your first step toward cloud computing.
Series: AWS for Students — From Local Projects to the Cloud (4 articles)
- …
- 3Learning AWS in Public — Part 3: From Localhost to the Cloud with Amazon EC2 This article
In the previous article, I explored the fundamentals of AWS, including account setup, Regions, Availability Zones, IAM, and cost management.
Now it's time to move from theory to practice.
As developers, we often build applications on our laptops. We run backend servers, connect databases, test APIs, and ensure everything works locally.
But what happens when we want other people to access our applications over the internet?
One solution is to deploy the application on a cloud server.
In this article, we'll explore Amazon Elastic Compute Cloud (Amazon EC2) and learn how to deploy a simple web application on a virtual machine.
The goal is to understand the journey from a locally developed application to one hosted in the cloud.
We'll use Python and Flask for this tutorial because they keep the initial setup simple. The same deployment concepts can later be applied to Java Spring Boot and Node.js applications.
1. What Is Amazon EC2?
Amazon EC2 is an AWS service that provides virtual servers called instances.
Instead of purchasing and maintaining a physical server, we can launch a virtual machine in the cloud and use it to run applications.
An EC2 instance provides configurable computing resources, including:
- CPU and memory
- Operating system
- Storage
- Network connectivity
- Security controls
- Application runtimes
For example, we could launch an Ubuntu server, install Java, and deploy a Spring Boot application.
A simplified architecture looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Developer's Laptop
|
| Deploy application
v
Amazon EC2
|
+-- Operating System
|
+-- Application Runtime
|
+-- Web Application
|
v
Internet UsersEC2 provides considerable flexibility, but it also means we must understand server administration, security, application processes, and maintenance.
2. Understanding the Important EC2 Concepts
Before launching our instance, let's understand some terms we'll encounter in the AWS Console.
Amazon Machine Image (AMI): A template used to launch an EC2 instance. It includes an operating system and may include additional software.
Instance type: Defines the computing resources available to an instance, including CPU and memory.
Key pair: Provides credentials used to authenticate when connecting to an instance through SSH.
Security group: Acts as a virtual firewall that controls inbound and outbound traffic.
Amazon EBS: Provides block storage that can be attached to EC2 instances.
Understanding these concepts will make it easier to configure our first cloud server.
3. What Do We Need Before Starting?
To follow this tutorial, you'll need:
- An AWS account
- A web browser
- A terminal with an SSH client
- Basic familiarity with Linux commands
- Basic Python knowledge
Before creating any resources, review the current AWS pricing and your account's free-tier eligibility.
Important: EC2 instances, attached storage, public IPv4 addresses, and data transfer may incur charges. Free usage depends on your account eligibility, resource configuration, and current AWS terms.
Never assume a resource is free simply because it is small.
4. Launching Your First EC2 Instance
Open the AWS Management Console and navigate to Amazon EC2.
Choose Launch instance to begin configuring your virtual server.
Step 1: Name your instance
Use a descriptive name, such as:
first-ec2-web-serverDescriptive names make cloud resources easier to identify and manage.
Step 2: Choose an operating system
Select a suitable Ubuntu Server Amazon Machine Image.
Ubuntu is a popular option for learning Linux administration and deploying web applications.
Step 3: Select an instance type
Choose a small instance that is appropriate for the tutorial.
Check the current pricing, available instance types, resource requirements, and applicable free-tier terms before proceeding.
Step 4: Configure a key pair
Create or select an SSH key pair.
If you create a new key pair, download the private key and store it securely. AWS generally does not allow you to download the same private key again later.
On Linux or macOS, you can commonly restrict the key's permissions using:
1
chmod 400 my-key.pemNever upload your private key to GitHub or share it publicly.
Step 5: Configure network access
For our web server, we'll need the following inbound rules:
| Port | Purpose | Suggested source |
|---|---|---|
| 22 | SSH administration | Your IP address |
| 80 | HTTP traffic | Public access if the website should be public |
We'll configure HTTPS separately if we extend this tutorial with TLS.
Avoid opening unnecessary ports. In particular, do not expose SSH to the entire internet unless there is a specific, carefully considered reason.
Step 6: Review and launch
Review your configuration, check the estimated charges, and launch the instance.
Wait until the instance is running and its status checks have passed.
Your first cloud server is now provisioned.
5. Connecting to EC2 Through SSH
Next, we'll connect to the virtual machine.
In the EC2 Console, select your instance and locate its public IPv4 address or public DNS name.
Run the following command from a terminal with SSH installed:
1
ssh -i my-key.pem ubuntu@YOUR_PUBLIC_IPReplace
my-key.pem with your private key's path and YOUR_PUBLIC_IP with the actual public IP address of your instance.The username
ubuntu is appropriate for standard Ubuntu AMIs. Other operating systems may use different usernames.If the connection fails, check:
- Whether the instance is running.
- Whether the public IP address is correct.
- Whether the security group permits SSH from your IP.
- Whether you're using the correct private key.
- Whether the instance's network configuration permits connectivity.
Once connected, commands entered in this session will execute on the remote server rather than your local machine.
6. Updating the Server
Before installing software, update the operating system's package information.
Run:
1
2
sudo apt update
sudo apt upgrade -yThe first command refreshes the package index. The second installs available package upgrades.
Depending on the updates, a reboot may be recommended.
Keeping the operating system updated is an important part of server maintenance.
7. Creating a Simple Web Application
We'll use Flask, a lightweight Python web framework, to create a basic application.
First, install Python and the virtual environment tools:
1
sudo apt install -y python3 python3-venv python3-pipCreate a project directory:
1
2
mkdir first-web-app
cd first-web-appCreate and activate a virtual environment:
1
2
python3 -m venv .venv
source .venv/bin/activateInstall Flask:
1
pip install flaskCreate a file named
app.py:1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask
app = Flask(__name__)
def home():
return "Hello from my first AWS EC2 application!"
def health():
return {"status": "healthy"}
if __name__ == "__main__":
app.run(host="127.0.0.1", port=5000)Our application provides two endpoints:
/returns a welcome message./healthreturns a simple health-check response.
Notice that the application listens on
127.0.0.1, meaning it accepts connections only from the local machine.We'll use Nginx as a reverse proxy to expose the application through HTTP without directly exposing Flask's development server.
8. Testing the Application
Run the application:
1
python app.pyOpen a second SSH session to the instance and test the home endpoint:
1
curl http://127.0.0.1:5000/Expected output:
1
Hello from my first AWS EC2 application!Now test the health endpoint:
1
curl http://127.0.0.1:5000/healthExpected output:
1
{"status":"healthy"}If both requests succeed, our application is running on EC2.
However, it isn't yet accessible to external users. Let's configure a web server.
9. Configuring Nginx as a Reverse Proxy
Nginx is a web server that can also act as a reverse proxy, forwarding incoming requests to an application running locally.
Install Nginx:
1
sudo apt install -y nginxCreate a configuration file:
1
sudo nano /etc/nginx/sites-available/first-web-appAdd this configuration:
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name _;
location / {
proxy_pass http://127.0.0.1:5000;
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;
}
}Save the file and enable the configuration:
1
2
sudo ln -s /etc/nginx/sites-available/first-web-app \
/etc/nginx/sites-enabled/first-web-appIf the default Nginx site conflicts with this configuration, disable the default site.
Validate the configuration:
1
sudo nginx -tIf the test succeeds, reload Nginx:
1
sudo systemctl reload nginxNginx now listens on port 80 and forwards HTTP requests to the Flask application on port 5000.
For this introductory exercise, Flask is running in the foreground. Keep its terminal open while testing. A more reliable deployment should run the application through a production WSGI server and a process manager such as systemd.
10. Accessing the Application from the Internet
Return to the EC2 Console and open the instance's security group.
Ensure that an inbound rule allows HTTP traffic on port 80 from the appropriate source. For a publicly accessible demonstration website, this is commonly
0.0.0.0/0.Keep SSH restricted to your IP address.
Now open the following URL in your browser:
1
http://YOUR_PUBLIC_IPReplace the placeholder with your instance's actual public IPv4 address.
You should see:
Hello from my first AWS EC2 application!
Congratulations! We've moved a simple application from a local development environment to a cloud-hosted server.
Here's how the request travels through the system:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Browser
|
v
Internet
|
v
EC2 Security Group
|
v
Nginx (Port 80)
|
v
Flask Application (Port 5000)
|
v
HTTP ResponseThis basic architecture introduces important concepts used in real deployments, including virtual machines, network security, application runtimes, and reverse proxies.
11. Applying the Same Concepts to Java Spring Boot
Although this tutorial uses Python, the same principles apply to Java Spring Boot applications.
A typical workflow would be:
- Build the application using Maven or Gradle.
- Package it as an executable JAR.
- Install a compatible Java runtime on EC2.
- Transfer the JAR to the server.
- Configure environment variables and database credentials.
- Run the application using a suitable process manager.
- Configure Nginx or another appropriate entry point.
- Set up HTTPS before using the application for real users.
Node.js applications can be deployed similarly, using a compatible Node.js runtime and a suitable process manager.
The programming language changes, but many of the underlying deployment concepts remain the same.
12. Common Problems and Troubleshooting
SSH connection times out
Possible causes include incorrect security group rules, a changed public IP, an incorrect address, or an instance networking problem.
Verify the instance's status, public address, network configuration, and SSH access rules.
The website cannot be reached
Check whether Flask is running, Nginx is active, port 80 is allowed, and the instance has a working public network path.
Useful commands:
1
2
3
sudo systemctl status nginx
sudo nginx -t
curl http://127.0.0.1:5000/Nginx returns a 502 Bad Gateway error
This often indicates that Nginx cannot communicate with the upstream application.
Test Flask directly:
1
curl http://127.0.0.1:5000/If this fails, investigate the application process before changing the Nginx configuration.
The application works locally but not remotely
Remember that
127.0.0.1 refers to the local machine or network namespace.In our setup, Flask listens on localhost, while Nginx provides the external HTTP entry point.
Understanding this distinction is especially useful when deploying backend APIs.
13. Security and Cost Considerations
A working deployment is not automatically production-ready.
Before using this approach for a real application, consider:
- HTTPS: Configure TLS using an appropriate certificate and deployment architecture.
- Process management: Ensure the application restarts when needed.
- Secrets: Keep credentials out of source code and version control.
- Operating system updates: Apply security patches regularly.
- Monitoring: Review application logs, resource usage, and system health.
- Backups: Plan recovery for any persistent data.
- Network security: Expose only necessary ports.
- Cost management: Review compute, storage, networking, and related charges.
For production use, replace Flask's development server with a production WSGI server, and configure an appropriate process manager.
Cleaning up after the experiment
When you finish, stop or terminate resources you no longer need, depending on whether you plan to continue the project.
Remember that terminating an instance doesn't necessarily delete every associated resource. Review attached storage, snapshots, allocated IP addresses, and other resources separately.
Stopping an instance also may not eliminate all charges, particularly for storage and certain networking resources.
14. What I Learned
This exercise shows that deploying an application requires more than copying source code to a server.
We explored:
- Provisioning a virtual machine.
- Connecting to a remote Linux server.
- Installing and running application software.
- Configuring network access rules.
- Using Nginx as a reverse proxy.
- Understanding local and public network addresses.
- Identifying common deployment failures.
- Considering security and operating costs.
These are foundational skills that can be applied to many different application architectures.
Conclusion
In this article, we explored Amazon EC2 and walked through hosting a basic web application on a cloud server.
We launched a virtual machine, connected through SSH, installed Python and Flask, configured Nginx, and made the application accessible over HTTP.
This is only a starting point. Real-world applications require more work around process management, HTTPS, authentication, monitoring, reliability, and security.
In the next article, we'll explore Amazon S3 and cloud storage, learning how to create a bucket, upload files, understand access permissions, and integrate object storage into an application.
The journey from localhost to the cloud begins with small, practical steps—and this is just the beginning.
Official Resources
Series: AWS for Students — From Local Projects to the Cloud (4 articles)
- …
- 3Learning AWS in Public — Part 3: From Localhost to the Cloud with Amazon EC2 This article
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article