How to Deploy to Aws Ec2
How to Deploy to AWS EC2 Deploying applications to Amazon Web Services (AWS) Elastic Compute Cloud (EC2) is one of the most fundamental and widely adopted practices in modern cloud infrastructure. Whether you're a startup launching your first web app or an enterprise scaling complex microservices, EC2 provides the flexibility, scalability, and control needed to run virtually any workload in the cl
How to Deploy to AWS EC2
Deploying applications to Amazon Web Services (AWS) Elastic Compute Cloud (EC2) is one of the most fundamental and widely adopted practices in modern cloud infrastructure. Whether you're a startup launching your first web app or an enterprise scaling complex microservices, EC2 provides the flexibility, scalability, and control needed to run virtually any workload in the cloud. Unlike managed platforms that abstract away server details, EC2 gives you full administrative access to virtual machinesmaking it ideal for teams that require custom configurations, specific runtime environments, or compliance-driven infrastructure.
This guide walks you through the complete process of deploying an application to AWS EC2from setting up your first instance to securing, monitoring, and maintaining your deployment. Youll learn not just how to do it, but why each step matters. By the end, youll have a production-ready deployment pipeline thats secure, scalable, and optimized for performance.
Step-by-Step Guide
1. Understand AWS EC2 and Its Role in Deployment
Amazon EC2 is a web service that provides resizable compute capacity in the cloud. It allows you to launch virtual serverscalled instanceson demand. These instances can run operating systems such as Linux (Amazon Linux, Ubuntu, CentOS) or Windows, and you can choose from a wide range of instance types optimized for compute, memory, storage, or graphics.
When you deploy to EC2, youre essentially provisioning a virtual machine that hosts your application. This could be a static website, a Node.js backend, a Python Flask API, a Java Spring Boot service, or even a full-stack application with a database. Unlike Platform-as-a-Service (PaaS) offerings like Heroku or AWS Elastic Beanstalk, EC2 gives you complete control over the underlying OS, network configuration, security groups, and software stack.
2. Set Up an AWS Account
If you dont already have an AWS account, go to aws.amazon.com and click Create an AWS Account. Youll need a valid email address, phone number, and payment method. AWS offers a Free Tier for new users, which includes 750 hours per month of t2.micro or t3.micro instance usage for one yearperfect for learning and small-scale deployments.
After signing up, log in to the AWS Management Console. This is your central dashboard for managing all AWS services. From here, youll navigate to EC2 under the Compute section.
3. Choose an Amazon Machine Image (AMI)
An AMI is a pre-configured template that includes an operating system, software, and configuration settings. When launching an EC2 instance, you must select an AMI. For most web applications, we recommend:
- Amazon Linux 2023 Optimized for AWS, lightweight, and frequently updated.
- Ubuntu Server 22.04 LTS Popular for developers, strong community support, and excellent package management.
- Windows Server 2022 Only if your application requires .NET, IIS, or Windows-specific dependencies.
In the EC2 dashboard, click Launch Instance. Under Choose an Amazon Machine Image, search for Ubuntu Server 22.04 LTS and select the first result. This AMI is free-tier eligible and widely documented.
4. Select an Instance Type
Instance types define the hardware specifications of your virtual server. For development and small applications, choose t3.micro or t2.micro (both included in Free Tier). These offer 1 vCPU and 1 GB of RAMsufficient for lightweight apps like a static site or a small API.
For production applications, consider:
- t3.small 2 vCPU, 2 GB RAM (ideal for low-traffic apps)
- t3.medium 2 vCPU, 4 GB RAM (recommended for most production APIs)
- m6a.large 2 vCPU, 8 GB RAM (for memory-intensive applications)
Click Next: Configure Instance Details after selecting your instance type.
5. Configure Instance Details
This step lets you fine-tune how your instance behaves. For most deployments, the defaults are acceptable. However, pay attention to:
- Number of instances: Set to 1 unless youre deploying a load-balanced cluster.
- Network: Ensure youre launching in the default VPC. If youve created a custom VPC, select it.
- Subnet: Choose a public subnet if you want your instance to be reachable from the internet. For private deployments, use a private subnet with a NAT gateway.
- Auto-assign Public IP: Enable this if you want to connect via SSH or access your app over HTTP/HTTPS. Disable it for internal-only services.
Click Next: Add Storage to proceed.
6. Add Storage
By default, EC2 allocates an 8 GB General Purpose SSD (gp3) volume. For most applications, this is sufficient. However, if youre deploying a database-heavy app or storing large assets, increase the size to 20 GB or more.
You can also add additional volumes for data separation (e.g., one for OS, one for logs, one for databases). Click Next: Add Tags after adjusting storage.
7. Add Tags (Optional but Recommended)
Tags are key-value pairs that help you organize, identify, and manage your resources. For example:
- Key: Name, Value: my-app-production
- Key: Environment, Value: Production
- Key: Owner, Value: dev-team
Tagging improves cost allocation, automation, and security policies. Click Next: Configure Security Group to continue.
8. Configure Security Group
Security groups act as virtual firewalls for your EC2 instance. They control inbound and outbound traffic at the instance level.
Click Add Rule and configure the following:
- Type: SSH, Protocol: TCP, Port Range: 22, Source: My IP (recommended) or specify your static IP address
- Type: HTTP, Protocol: TCP, Port Range: 80, Source: 0.0.0.0/0 (for public access)
- Type: HTTPS, Protocol: TCP, Port Range: 443, Source: 0.0.0.0/0 (if using SSL)
Never open port 22 to 0.0.0.0/0 in production. Restrict SSH access to known IPs or use a bastion host. Click Review and Launch.
9. Review and Launch
Verify all settings. If everything looks correct, click Launch. Youll be prompted to select or create a key pair.
10. Create and Download a Key Pair
A key pair is used for secure SSH access to your instance. Click Create a new key pair, give it a name (e.g., my-app-key), and select PEM as the format. Click Download Key Pair.
Important: Save this .pem file in a secure location. Youll need it to connect to your instance. Never share it or commit it to version control. Set strict permissions:
chmod 400 my-app-key.pem
Click Launch Instances. Youll see a confirmation message. Wait a few moments for the instance to initialize.
11. Connect to Your EC2 Instance via SSH
Once the instance state changes to running, select it in the EC2 dashboard and click Connect. Choose SSH client and copy the provided command:
ssh -i "my-app-key.pem" ubuntu@ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com
Open your terminal (macOS/Linux) or use PuTTY (Windows) and paste the command. You should now be logged into your EC2 instance.
12. Install Required Software
Update the package list and install dependencies:
sudo apt update && sudo apt upgrade -y
sudo apt install nginx nodejs npm python3-pip git -y
Depending on your application, install additional tools:
- For Node.js apps:
npm install -g pm2 - For Python apps:
pip3 install virtualenv - For Docker:
sudo apt install docker.io && sudo systemctl enable docker && sudo systemctl start docker
13. Deploy Your Application Code
There are multiple ways to deploy code to EC2:
Option A: Clone from GitHub
cd /home/ubuntu
git clone https://github.com/yourusername/your-app.git
cd your-app
npm install
or pip install -r requirements.txt
Option B: Upload via SCP
If you have a local build, transfer it using SCP:
scp -i "my-app-key.pem" -r ./my-app ubuntu@ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com:/home/ubuntu/
Option C: Use CI/CD (Advanced)
Set up GitHub Actions or AWS CodeDeploy to automatically push code on git push. This is recommended for production environments.
14. Start Your Application
For a Node.js app:
pm2 start app.js --name "my-app"
pm2 startup
pm2 save
For a Python Flask app:
cd /home/ubuntu/your-app
export FLASK_APP=app.py
flask run --host=0.0.0.0 --port=5000 &
For a static site:
Move your files to Nginxs root directory:
sudo rm -rf /var/www/html/*
sudo cp -r /home/ubuntu/your-app/dist/* /var/www/html/
sudo systemctl restart nginx
15. Configure a Domain Name (Optional)
To use a custom domain (e.g., www.yourapp.com), purchase a domain via Route 53 or another registrar. Then:
- Point your domains A record to your EC2 instances public IP.
- Or use an Elastic IP (static IP) and associate it with your instance to avoid DNS changes after reboot.
16. Set Up HTTPS with Lets Encrypt
Install Certbot to obtain a free SSL certificate:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Follow the prompts. Certbot will automatically update your Nginx config and enable HTTPS. Test your site at SSL Labs to verify.
17. Test Your Deployment
Open your browser and navigate to your public IP or domain. You should see your application live. Use curl or Postman to test API endpoints:
curl http://yourdomain.com/api/health
Check logs if something fails:
sudo journalctl -u nginx -f
pm2 logs my-app
Best Practices
Use Elastic IPs for Static Addresses
EC2 public IPs change when you stop and start an instance. To avoid breaking DNS or client connections, allocate an Elastic IP from the EC2 dashboard and associate it with your instance. This provides a static, persistent public IP address.
Enable Monitoring and Logging
Install the Amazon CloudWatch agent to send system metrics (CPU, memory, disk) to CloudWatch:
sudo apt install amazon-cloudwatch-agent -y
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent.json -s
Enable detailed monitoring in the EC2 instance settings for 1-minute metric intervals.
Implement Automated Backups
Use AWS Backup or create a script that takes daily EBS snapshots:
aws ec2 create-snapshot --volume-id vol-xxxxxxxx --description "Daily backup of my-app server"
Automate this with cron:
crontab -e
Add: 0 2 * * * /home/ubuntu/backup.sh
Harden Security
- Disable root SSH login:
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
- Use key-based authentication only:
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
- Restart SSH:
sudo systemctl restart ssh - Install fail2ban:
sudo apt install fail2ban - Use a non-root user for deployments:
sudo adduser deployer && sudo usermod -aG sudo deployer
Separate Environments
Use separate EC2 instances for development, staging, and production. Tag them clearly and apply different security groups. Never deploy directly to production from your local machine.
Use a Reverse Proxy
Always run your application behind Nginx or Apache. They handle SSL termination, load balancing, static file serving, and request buffering better than application servers alone.
Regularly Patch and Update
Set up automatic security updates:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Configure email alerts for updates via cron or CloudWatch Alarms.
Plan for Scalability
EC2 is not inherently scalable. To handle traffic spikes, use:
- Auto Scaling Groups (ASG) to add/remove instances based on load
- Application Load Balancer (ALB) to distribute traffic
- Amazon RDS for managed databases
- Amazon S3 for static assets
Design your app to be stateless so instances can be replaced without data loss.
Tools and Resources
Essential AWS Tools
- AWS CLI: Command-line interface for managing AWS resources. Install with:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install - AWS Console: Web-based dashboard for manual operations.
- CloudFormation: Infrastructure-as-code tool to define and deploy EC2 stacks declaratively.
- Systems Manager (SSM): Securely manage instances without SSH. Use Session Manager to connect via browser.
- CodeDeploy: Automate application deployments to EC2 from GitHub, Bitbucket, or S3.
Deployment Automation Tools
- GitHub Actions: Automate builds and deployments on git push.
- Ansible: Configuration management tool to provision and configure EC2 instances.
- Terraform: Infrastructure-as-code tool to define EC2, VPC, security groups, and more in code.
- Docker: Containerize your app for consistent environments across development and production.
Monitoring and Logging
- CloudWatch: Native AWS monitoring service for metrics and logs.
- Logrotate: Prevent log files from consuming disk space.
- ELK Stack (Elasticsearch, Logstash, Kibana): For advanced log aggregation (run on separate EC2 instances or use Amazon OpenSearch).
- Netdata: Real-time performance monitoring dashboard.
Security Tools
- Trivy: Open-source vulnerability scanner for containers and OS packages.
- AWS Inspector: Automated security assessment service.
- HashiCorp Vault: For managing secrets and API keys securely.
- SSH Key Management: Use AWS Secrets Manager or parameter store to store and rotate keys.
Learning Resources
- AWS EC2 Documentation
- AWS Hands-On Deployment Tutorial
- Udemy: AWS EC2 from Scratch
- AWS GitHub Samples Repository
Real Examples
Example 1: Deploying a React Frontend + Node.js API
Scenario: A full-stack application with a React frontend and Express.js backend.
Steps:
- Build the React app:
npm run build - Upload the build folder to EC2:
scp -r build/ ubuntu@ip:/home/ubuntu/frontend - Copy files to Nginx:
sudo cp -r /home/ubuntu/frontend/* /var/www/html/ - Deploy Node.js API:
git clone https://github.com/user/api.git && cd api && npm install && pm2 start server.js - Configure Nginx to proxy /api requests to port 3000:
server {
listen 80;
server_name yourdomain.com;
location / {
root /var/www/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Restart Nginx: sudo systemctl restart nginx
Example 2: Deploying a Python Django App with Gunicorn and Nginx
Scenario: A Django web app with PostgreSQL.
Steps:
- Install Python and pip:
sudo apt install python3-pip python3-venv - Create virtual environment:
python3 -m venv venv && source venv/bin/activate - Install requirements:
pip install gunicorn django psycopg2 - Collect static files:
python manage.py collectstatic --noinput - Run Gunicorn:
gunicorn --bind 0.0.0.0:8000 myproject.wsgi - Configure Nginx to proxy to port 8000
- Use systemd to manage Gunicorn as a service:
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/myproject
ExecStart=/home/ubuntu/myproject/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/home/ubuntu/myproject/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Enable and start: sudo systemctl enable gunicorn && sudo systemctl start gunicorn
Example 3: Containerized App with Docker on EC2
Scenario: A Node.js app packaged in a Docker container.
Steps:
- Build Docker image locally:
docker build -t myapp . - Push to Amazon ECR:
aws ecr get-login-password | docker login --username AWS --password-stdin your-account.dkr.ecr.region.amazonaws.com && docker tag myapp:latest your-account.dkr.ecr.region.amazonaws.com/myapp:latest && docker push your-account.dkr.ecr.region.amazonaws.com/myapp:latest - On EC2:
sudo docker run -d -p 80:3000 --name myapp your-account.dkr.ecr.region.amazonaws.com/myapp:latest - Configure Nginx as reverse proxy if needed.
This approach ensures consistency across environments and simplifies rollback.
FAQs
Is AWS EC2 free to use?
Yes, AWS offers a Free Tier that includes 750 hours per month of t2.micro or t3.micro instance usage for 12 months. Beyond that, pricing starts at around $0.0116 per hour for t3.micro. Always monitor usage to avoid unexpected charges.
Can I deploy a database on EC2?
You can, but its not recommended for production. Instead, use Amazon RDS (Relational Database Service) for managed MySQL, PostgreSQL, or SQL Server. RDS handles backups, patching, replication, and scaling automatically.
How do I update my app without downtime?
Use a blue-green deployment strategy: Launch a new EC2 instance with the updated code, test it, then switch traffic using an Elastic Load Balancer. Alternatively, use AWS CodeDeploy with Auto Scaling Groups to roll out updates incrementally.
Why is my app not accessible via browser?
Common causes:
- Security group doesnt allow HTTP/HTTPS traffic
- Nginx or app server isnt running
- Application is bound to 127.0.0.1 instead of 0.0.0.0
- Public IP changed (use Elastic IP)
- DNS propagation delay (wait up to 48 hours)
Should I use EC2 or Elastic Beanstalk?
Use EC2 if you need full control over the OS, networking, and software stack. Use Elastic Beanstalk if you want a PaaS experienceAWS handles infrastructure, scaling, and monitoring automatically. EC2 gives more flexibility; Elastic Beanstalk gives more simplicity.
How do I secure SSH access?
Use key pairs only, disable root login, restrict SSH to specific IPs, install fail2ban, and consider using AWS Systems Manager Session Manager to connect without opening port 22 at all.
Can I run multiple apps on one EC2 instance?
Yes, using virtual hosts in Nginx or different ports. For example:
- app1.yourdomain.com ? port 3000
- app2.yourdomain.com ? port 4000
Each app should run as a separate process (e.g., PM2 or systemd service) and be isolated with proper file permissions.
What happens if my EC2 instance crashes?
EC2 instances are ephemeral. If they crash, you lose data stored locally unless you use EBS volumes with snapshots or external storage (S3, RDS). Always design for failure: use backups, auto-recovery, and stateless applications.
How do I reduce costs?
- Use Spot Instances for non-critical workloads (up to 90% discount)
- Shut down instances when not in use (e.g., dev environments at night)
- Use Reserved Instances for predictable, long-term workloads
- Switch from gp2 to gp3 EBS volumes for better performance at lower cost
Conclusion
Deploying to AWS EC2 is a foundational skill for any developer or DevOps engineer working in the cloud. While it requires more hands-on management than managed platforms, the control, flexibility, and cost-efficiency it offers make it indispensable for production-grade applications. By following this guide, youve learned not just how to launch an instance, but how to deploy, secure, monitor, and maintain a resilient application in the cloud.
Remember: EC2 is a toolnot a solution. Its power lies in how you combine it with other AWS services, automation tools, and operational best practices. As your applications grow, consider moving toward infrastructure-as-code (Terraform, CloudFormation), containerization (Docker, ECS), and auto-scaling to reduce manual overhead and increase reliability.
Start small, test thoroughly, document everything, and always prioritize security. The cloud is powerfulbut only when used wisely.