Skip to content

Deploy a Go app to AWS (EC2) with Nginx, SSL & Custom Domain (Step-by-Step)

Published:

In this tutorial, we will deploy a Go backend to an AWS EC2 instance. We will use Nginx as a reverse proxy to serve the API and SSL to secure the connection and add a custom domain.

This is a follow-up to a previous tutorial where we built a complete REST API in Go using Gin. You can find the full tutorial at Complete REST API in Go – Build an Event App.

Table of contents

Open Table of contents

Prerequisites

Before we begin, make sure you have:

  1. AWS Account

Setting up EC2

Step 1: Launch an EC2 Instance

  1. Access AWS Console:

    • Open the AWS Console and use the search bar to navigate to EC2. Search EC2
  2. Launch Instance:

    • Click on “Launch Instance.” Launch EC2 Instance
  3. Configure Instance:

    • Name: go-api
    • AMI: Amazon Linux 2023
    • Instance Type: t3.micro (free tier) Configure EC2
  4. Key Pair:

    • Create a new key pair named go-api-key and assign it to the instance. Key Pair for EC2
  5. Network Settings:

    • Create a security group with the following inbound rules:
      • SSH: TCP, Port 22, Source: Anywhere (0.0.0.0/0)
      • HTTP: TCP, Port 80, Source: Anywhere (0.0.0.0/0)
      • HTTPS: TCP, Port 443, Source: Anywhere (0.0.0.0/0) EC2 Network Settings
  6. Storage and Advanced Details:

    • Storage: 8 GB (default)
    • Advanced Details: Default settings
  7. Launch the Instance:

    • Click “Launch instance.” Launch EC2 Instance

Step 2: Connect to the EC2 Instance

  1. Set Key Pair Permissions:

    • After downloading the key pair, open a terminal and set permissions:
      chmod 400 go-api-key.pem
    • This ensures only the owner can read the file, preventing connection errors.
  2. Connect to the Instance:

    • Find the instance’s IP address in the EC2 instance details. EC2 Instance Details
    • Use the terminal to connect using the key pair:
      ssh -i go-api-key.pem ec2-user@your-instance-ip
    • ec2-user is the default username for Amazon Linux 2023.

Building the Application on EC2

  1. Inside EC2 instance install Git and Go:

    sudo dnf install git golang -y
  2. Clone the Repository:

    git clone https://github.com/patni1992/Rest-api-in-go-gin.git
  3. Navigate to the Repository:

    cd Rest-api-in-go-gin
  4. Run Migrations:

    • Run migrations to create the database:
    go run ./cmd/migrate/ up
    
  5. Build the Application api binary:

    • Build the application using go build:
      go build -o events-api ./cmd/api

Deploying the Application

  1. Make the API binary executable:

    chmod +x events-api
  2. Run the Application:

Verify the application is running:

curl -v localhost:8080/api/v1/events

If everything is working, you should see a status code 200.

Currently we can only access the API from the EC2 instance and not from the outside world, we will add a custom domain and setup Nginx to serve the API.

Stopping the Application

(This is how you can stop the application if you need to, keep it running for now)

To stop the application, you can use the kill command to terminate the process. First, find the process ID (PID) of the running application:

ps aux | grep events-api

This will list the processes related to events-api. Look for the line that corresponds to your running application and note the PID (the number in the second column).

Then, use the kill command to stop the application:

kill <PID>

Replace <PID> with the actual process ID you found. This will terminate the application running in the background.

Adding a Subdomain

  1. Create a Subdomain:

    • In your domain registrar’s DNS settings, add a new A record for your subdomain (e.g., go-api.yourdomain.com) pointing to your EC2 instance’s public IP. This is how it looks in Cloudflare:

    Cloudflare DNS Settings

  2. Verify Propagation:

    • Use tools like whatsmydns.net to ensure the subdomain points to the correct IP.

    Whatsmydns.net

Configuring Nginx for SSL

1. Install Nginx

sudo dnf install nginx -y

2. Configure Nginx

  1. Edit Nginx Configuration:

    • Open the Nginx configuration file with nano or vim if you prefer:

      sudo nano /etc/nginx/nginx.conf
  2. Add Required Blocks:

    • Ensure your configuration includes the events block and the http block:

      events {
          worker_connections 1024;
      }
      
      http {
          server {
              listen 80;
              server_name go-api.yourdomain.com;
      
              location / {
                  proxy_pass http://localhost:8080;
                  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;
              }
          }
      }
  3. Test Nginx Configuration:

    sudo nginx -t
  4. Restart Nginx:

    sudo systemctl restart nginx

3. Obtain SSL Certificate

  1. Install Certbot:

    sudo dnf install certbot python3-certbot-nginx -y
  2. Obtain and Install SSL Certificate:

    sudo certbot --nginx -d go-api.yourdomain.com
  3. Automate Renewal:

    • Certbot usually sets up automatic renewal, but you can verify with:
      sudo certbot renew --dry-run

4. Verify

Conclusion

You’ve successfully deployed your Go application to AWS EC2, with a custom domain and configured Nginx for SSL. Once you know how to do this, you can deploy your application to any other cloud provider the steps will be very similar and you can learn more about other services on AWS since many of them are built on top of AWS EC2.