How I deploy Golang to AWS with Amazon ec2 , Ubuntu and Mysql

On my previous blog, I wrote about how I started using Golang Fiber as a new backend for PuzzleNomic. For me, it has been a great learning journey where I have learned not only the theoretical aspects of Golang but also practically how to create a simple API with it, connect the backend to the frontend (React), and configure the database. Then, I realized that it's not complete if I only do it on localhost. Instead, I decided to try deploying it to AWS. As someone who is always looking for challenges and gets bored with everyday jobs, I think this is my stepping stone to obtaining at least the AWS Cloud Practitioner certification as an added value to my skills.

Prerequisites

  1. An AWS account ( I used free tier for ec2 and rds )
  2. Setup github personal access token ( this will be used when cloning project to ec2 instance ) . read more
  3. Git installed on your local machine

Lets get started

  1. Launch an EC2 instance on the free tier by logging into your AWS account, navigating to the EC2 service, and clicking on "Launch Instance".
  2. Select "Ubuntu Server 20.04/22 LTS" as the AMI (Amazon Machine Image) and "t2.micro" as the instance type (these are eligible for free tier).
  3. Follow the steps to configure the instance, such as setting up a key pair to access the instance, and then launch the instance.
  4. Once the instance is running, SSH into it using the key pair you created in the previous step.
  5. Update the package list on the instance: sudo apt update
  6. Install Golang on the instance by running the following commands:

sudo apt install

golang export PATH=$PATH:/usr/local/go/bin

  1. Clone your Golang Fiber app's repository to the instance using Git: git clone [your repository URL]
  2. Navigate into the cloned repository: cd [your repository name]
  3. Build your Golang app by running go build main.go

To start your Golang service as a systemd service, follow these additional steps:

  1. Create a systemd service file for your Golang app by running sudo nano /etc/systemd/system/[your service name].service and adding the following configuration:

[Unit]Description=[Your service description]

[Service]Type=simple WorkingDirectory=/home/ubuntu/[your repository name]

ExecStart=/home/ubuntu/[your repository name]/mainRestart=always

[Install]WantedBy=multi-user.target

  1. Save and close the file by pressing Ctrl+X, then Y, then Enter.
  2. Reload the systemd daemon by running sudo systemctl daemon-reload
  3. Start your Golang service by running sudo systemctl start [your service name]
  4. Verify that your Golang service is running by running sudo systemctl status [your service name]

configure reverse proxy with NGINX

  1. First, create a new DNS record for your subdomain. You can do this through your domain registrar or DNS provider. Set the DNS record's value to the public IP address of your EC2 instance.
  2. Install nginx on your EC2 instance if it's not already installed. You can do this by running the following command:

sudo apt update

sudo apt install nginx

3. Create a new server block for your subdomain in the /etc/nginx/sites-available/ directory. You can name the file anything you want, but it's a good practice to name it after your subdomain. For example, if your subdomain is example.domain.com, you can name the file example.domain.com.

In the file, add the following configuration to set up the reverse proxy to your desired port. Replace example.domain.com with your subdomain, localhost with your application's IP, and 3000 with the desired port

server { listen 80; listen [::]:80;

server_name example.domain.com;

location /

server { listen80; server_name app.example.com; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_redirect off; } }

Save and close the file.

Create a symbolic link to enable the server block sudo ln -s /etc/nginx/sites-available/example.domain.com /etc/nginx/sites-enabled/

Remove the default server block configuration sudo rm /etc/nginx/sites-enabled/default

Verify that the nginx configuration is valid sudo nginx -t

Reload the nginx configuration sudo systemctl reload nginx

Result ‌‌

The app performed very quickly, and everything looked good. The device used was the Asus ROG 6.

I printed out some logs to show the interaction between the API and the apps whenever the endpoint was triggered with a POST or GET request.

The structure of the database I'm using is managed through DBeaver, which is a tool for managing Amazon RDS (Relational Database Service).

Improvement


The next step I plan to take is to add a simple CI/CD pipeline workflow to this project using GitHub Actions. Additionally, I would like to make some improvements to the frontend by adding animations with React SKIA, implementing OAuth authentication, and exploring other enhancements.