Nginx AWS Deployment
Introduction
Deploying Nginx on Amazon Web Services (AWS) combines the power of one of the world's most popular web servers with the flexibility and scalability of cloud infrastructure. This guide will walk you through the process of setting up Nginx on AWS, from launching your first EC2 instance to configuring advanced features like load balancing and automatic scaling.
Nginx (pronounced "engine-x") is a high-performance web server that can also function as a reverse proxy, load balancer, and HTTP cache. AWS provides a robust platform where you can deploy Nginx in various configurations to serve websites, APIs, and applications with optimal performance and reliability.
Prerequisites
Before we begin, you should have:
- An AWS account
- Basic understanding of Linux commands
- Familiarity with web servers and HTTP concepts
- AWS CLI installed and configured (optional but recommended)
Basic Nginx Deployment on EC2
Step 1: Launch an EC2 Instance
Let's start by launching a basic EC2 instance where we'll install Nginx:
- Log in to the AWS Management Console
- Navigate to EC2 service
- Click "Launch Instance"
- Choose an Amazon Linux 2 or Ubuntu Server AMI
- Select t2.micro instance type (free tier eligible)
- Configure instance details as needed
- Add storage (default is usually sufficient)
- Add tags (optional)
- Configure security group:
- Allow SSH (port 22) from your IP
- Allow HTTP (port 80) from anywhere
- Allow HTTPS (port 443) from anywhere
- Review and launch with your key pair
Step 2: Connect to Your Instance
Connect to your instance using SSH:
ssh -i /path/to/your-key.pem ec2-user@your-instance-public-dns
For Ubuntu:
ssh -i /path/to/your-key.pem ubuntu@your-instance-public-dns
Step 3: Install Nginx
For Amazon Linux 2:
# Update system packages
sudo yum update -y
# Install Nginx
sudo amazon-linux-extras install nginx1 -y
# Start Nginx
sudo systemctl start nginx
# Enable Nginx to start on boot
sudo systemctl enable nginx
# Check status
sudo systemctl status nginx
For Ubuntu:
# Update system packages
sudo apt update
sudo apt upgrade -y
# Install Nginx
sudo apt install nginx -y
# Start Nginx
sudo systemctl start nginx
# Enable Nginx to start on boot
sudo systemctl enable nginx
# Check status
sudo systemctl status nginx
Step 4: Verify Installation
You can verify that Nginx is running by:
-
Checking the service status:
bashsudo systemctl status nginx
-
Testing with curl:
bashcurl http://localhost
-
Opening your instance's public DNS in a web browser:
http://your-instance-public-dns
You should see the Nginx welcome page.
Configuring Nginx on AWS
Basic Configuration
The main Nginx configuration file is located at /etc/nginx/nginx.conf
. Let's create a simple website configuration:
-
Create a directory for your website:
bashsudo mkdir -p /var/www/mywebsite
-
Create a sample HTML file:
bashsudo nano /var/www/mywebsite/index.html
-
Add some HTML content:
html<!DOCTYPE html>
<html>
<head>
<title>My AWS Nginx Website</title>
</head>
<body>
<h1>Hello from AWS!</h1>
<p>This is my first Nginx website deployed on AWS.</p>
</body>
</html> -
Create a server block configuration:
bashsudo nano /etc/nginx/conf.d/mywebsite.conf
-
Add the following configuration:
nginxserver {
listen 80;
server_name _;
root /var/www/mywebsite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
} -
Test the configuration:
bashsudo nginx -t
-
Reload Nginx:
bashsudo systemctl reload nginx
-
Visit your website at your instance's public DNS.
Setting Up a Domain Name
To use a custom domain:
-
Register a domain through Route 53 or any domain registrar
-
Create a Route 53 hosted zone for your domain
-
Create an A record pointing to your EC2 instance's public IP
-
Update your Nginx server block:
nginxserver {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/mywebsite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
} -
Reload Nginx:
bashsudo nginx -t
sudo systemctl reload nginx
Securing Nginx with SSL/TLS
Using AWS Certificate Manager (ACM)
- Request a certificate in ACM
- Create an Application Load Balancer (ALB)
- Configure HTTPS listener with your certificate
- Point ALB to your EC2 instance
Using Let's Encrypt with Certbot
For direct EC2 setup:
# Amazon Linux 2
sudo amazon-linux-extras install epel -y
sudo yum install certbot python2-certbot-nginx -y
# Ubuntu
sudo apt install certbot python3-certbot-nginx -y
Obtain and install certificate:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will automatically modify your Nginx configuration.
Advanced AWS Deployments
Load Balancing with Nginx and AWS ELB
For high-availability setups:
- Launch multiple EC2 instances with Nginx
- Create an Application Load Balancer (ALB)
- Create a target group with your instances
- Configure health checks
- Set up listeners for HTTP/HTTPS traffic
Auto Scaling Nginx on AWS
Create an Auto Scaling Group (ASG):
- Create a launch template or configuration with Nginx installation
- Configure an ASG with desired capacity
- Set up scaling policies based on CPU usage or request count
- Attach the ASG to your load balancer target group
Example User Data script for your launch template:
#!/bin/bash
yum update -y
amazon-linux-extras install nginx1 -y
systemctl start nginx
systemctl enable nginx
cat > /var/www/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Auto Scaled Nginx on AWS</title>
</head>
<body>
<h1>Hello from Auto Scaling Group!</h1>
<p>This server was launched automatically by AWS Auto Scaling.</p>
<p>Server ID: $(hostname)</p>
</body>
</html>
EOF
Deploying Nginx with AWS Elastic Beanstalk
For a fully managed solution:
- Create a
.ebextensions
directory in your project - Create a configuration file
.ebextensions/nginx.config
:
packages:
yum:
nginx: []
files:
"/etc/nginx/conf.d/custom.conf":
mode: "000644"
owner: root
group: root
content: |
server {
listen 80;
server_name localhost;
location / {
root /var/www/html;
index index.html;
}
}
commands:
01_create_html:
command: |
mkdir -p /var/www/html
echo "<h1>Elastic Beanstalk Nginx</h1>" > /var/www/html/index.html
services:
sysvinit:
nginx:
enabled: true
ensureRunning: true
- Create a
Procfile
:
web: nginx -g "daemon off;"
- Deploy using the EB CLI:
eb init
eb create
eb deploy
Monitoring Nginx on AWS
CloudWatch Integration
Monitor your Nginx instances with CloudWatch:
-
Install CloudWatch agent:
bashsudo yum install amazon-cloudwatch-agent -y
-
Create CloudWatch config for Nginx logs:
bashsudo nano /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
-
Add configuration:
json{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/nginx/access.log",
"log_group_name": "nginx-access-logs",
"log_stream_name": "{instance_id}-access-log"
},
{
"file_path": "/var/log/nginx/error.log",
"log_group_name": "nginx-error-logs",
"log_stream_name": "{instance_id}-error-log"
}
]
}
}
},
"metrics": {
"metrics_collected": {
"mem": {
"measurement": ["mem_used_percent"]
},
"swap": {
"measurement": ["swap_used_percent"]
}
}
}
} -
Start the CloudWatch agent:
bashsudo systemctl start amazon-cloudwatch-agent
sudo systemctl enable amazon-cloudwatch-agent
Setting Up Alarms
Create CloudWatch alarms for:
- High CPU utilization
- Memory usage
- HTTP 5xx errors
- Response time
Performance Tuning for AWS
Nginx Worker Optimization
Edit /etc/nginx/nginx.conf
:
worker_processes auto;
worker_rlimit_nofile 30000;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
# ... other settings ...
keepalive_timeout 65;
keepalive_requests 100000;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Cache settings
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# Gzip settings
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
application/javascript
application/json
application/xml
application/xml+rss
text/css
text/javascript
text/plain
text/xml;
}
EC2 Instance Optimization
Choose the right instance type:
- C5 instances for compute-intensive workloads
- R5 instances for memory-intensive applications
- T3 instances for variable workloads
EBS Optimization
Use gp3 or io2 volumes for better performance with Nginx serving static content.
Deploying a Full Stack Application
Example: Node.js Application with Nginx
-
Install Node.js:
bashcurl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -
sudo yum install -y nodejs -
Clone your application:
bashgit clone https://github.com/yourusername/your-app.git
cd your-app
npm install
npm start -
Configure Nginx as reverse proxy:
nginxserver {
listen 80;
server_name yourdomain.com;
location / {
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;
}
} -
Set up PM2 for process management:
bashsudo npm install -g pm2
pm2 start app.js
pm2 startup
pm2 save
Advanced Topics
Nginx as a Load Balancer on AWS
You can use Nginx for load balancing across multiple EC2 instances:
http {
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.0.0.1 backup;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
}
Setting Up Caching
Configure Nginx for caching static content:
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
server {
listen 80;
server_name yourdomain.com;
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
}
}
}
Infrastructure as Code for Nginx on AWS
Using AWS CloudFormation
Create a CloudFormation template for your Nginx deployment:
AWSTemplateFormatVersion: '2010-09-09'
Resources:
NginxInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0c55b159cbfafe1f0 # Amazon Linux 2 AMI
SecurityGroups:
- !Ref NginxSecurityGroup
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum update -y
amazon-linux-extras install nginx1 -y
systemctl start nginx
systemctl enable nginx
NginxSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP/HTTPS and SSH
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Using Terraform
provider "aws" {
region = "us-east-1"
}
resource "aws_instance" "nginx" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
user_data = <<-EOF
#!/bin/bash
yum update -y
amazon-linux-extras install nginx1 -y
systemctl start nginx
systemctl enable nginx
EOF
vpc_security_group_ids = [aws_security_group.nginx.id]
tags = {
Name = "nginx-server"
}
}
resource "aws_security_group" "nginx" {
name = "nginx-sg"
description = "Allow HTTP/HTTPS and SSH traffic"
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Troubleshooting Nginx on AWS
Common Issues and Solutions
-
Nginx won't start
bash# Check error logs
sudo journalctl -u nginx.service
sudo cat /var/log/nginx/error.log
# Check configuration
sudo nginx -t -
Permission issues
bash# Fix permissions
sudo chown -R nginx:nginx /var/www/
sudo chmod -R 755 /var/www/ -
Connection refused
bash# Check if Nginx is running
sudo systemctl status nginx
# Check security groups
# Verify ports 80/443 are open in AWS console -
High CPU/Memory usage
bash# Check worker processes
grep worker_processes /etc/nginx/nginx.conf
# Monitor resource usage
top
Summary
In this guide, we've covered:
- Basic Nginx installation on AWS EC2
- Configuration of Nginx for web hosting
- Setting up domain names and SSL/TLS
- Advanced deployments using AWS services
- Monitoring and performance tuning
- Full-stack application deployment
- Infrastructure as Code approaches
- Troubleshooting common issues
Nginx on AWS provides a powerful, scalable solution for web hosting needs. By following this guide, you should be able to deploy and manage Nginx effectively on the AWS cloud platform.
Additional Resources
Practice Exercises
- Deploy Nginx on a t2.micro instance and host a simple personal website.
- Set up a load-balanced Nginx deployment with at least two EC2 instances.
- Configure Nginx with SSL/TLS using Let's Encrypt.
- Create a CloudFormation template for your Nginx deployment.
- Set up Nginx as a reverse proxy for a containerized application.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)