Deploying Golang and Angular Applications with Docker and Nginx

RMAG news

Introduction

Welcome to my blog! In this article, I’ve documented the process of deploying a Golang backend and Angular frontend application using Docker and Nginx. This tutorial will walk you through the steps to set up a production-ready environment for your Golang and Angular applications.

Project Repository
You can find the code for this project on GitHub: Project Repository

My Image Converter Application
Check out the deployed application to see it in action: My Image Converter

Personal Website
Visit my personal website to learn more about me and my other projects: ninedaystech.com

Choosing your server provider

Before diving into deployment, the first step is to select a reliable server provider. There are several options available, including Google Cloud Platform (GCP), Amazon Web Services (AWS), and others. For this guide, i’ve chosen DigitalOcean as my server provider for its simplicity, affordability, and robust features.

To get started with DigitalOcean, you can follow these steps: https://www.digitalocean.com/community/tags/getting-started

Prepare your project

Let’s take an example with a deployment that use docker compose:

Below Dockerfile for backend side, like i have mentioned above i develop my simple application using go for the backend

# syntax=docker/dockerfile:1

ARG GO_VERSION=1.22

FROM golang:${GO_VERSION}-alpine

ENV GO_ENV production

WORKDIR /usr/src/backend

COPY go.mod go.sum ./

RUN go mod download

COPY . .

RUN CGO_ENABLED=0 GOOS=linux go build -o main ./cmd

EXPOSE 9090

CMD [“./main”]

And for the frontend i develop my simple application using Angular. Below Dockerfile for frontend side:

FROM node:20-alpine AS build

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm cache clean –force

RUN npm install -g @angular/cli

RUN npm install
RUN npx ngcc –properties es2023 browser module main –first-only –create-ivy-entry-points

COPY . .

RUN npm run build

FROM nginx:stable

COPY –from=build /usr/src/app/dist/frontend/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

In the frontend side, i did multi-stage builds in my dockerfile. Because i use multi-stage which is my angular application will run on nginx image, so i need add configuration file for nginx. The configuration file named as nginx.conf. Below the example for nginx configuration file:

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

server {
listen 80;
server_name localhost;

root /usr/share/nginx/html;
index index.html index.htm;

location / {
try_files $uri $uri/ /index.html;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}

And then i will create that image and run the container using docker compose. Below my docker compose configuration:

services:
backend:
build:
context: ./backend
ports:
– 9090:9090
volumes:
– ./backend/converted_images:/go/src/app/converted_images

frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
– 8081:80

I will run my backend using port 9090 and port 8081 for my frontend. I used port forwarding for my frontend because my nginx run on port 80.

Deployment section

Okay, let’s deploy our project. First you need connect to your server/droplets. Open your terminal and run command like below:

ssh username@your_ip_address

Then, you need to install docker and nginx in your server. If you using digital ocean maybe this can help you to install docker and nginx: docker installation guide for ubuntu and nginx installation guide for ubuntu

Configure NGINX

After installation done, next we need to tell NGINX to listen to port 80 (http requests) for our custom domain name and map it back to the port we configured in our docker-compose.yml file and our app’s production config.

SSH into your server and create a new file in /etc/nginx/sites-available/ (you can name it yourdomain.com) with the following contents:

server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://localhost:9090;
}
}

Next we need to create a symlink to the file for the /sites-enabled directory:

cd /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/yourdomain.com ./

Check that the symlink was created successfully:

ls -l

# output:
… yourdomain.com -> /etc/nginx/sites-available/yourdomain.com

Next check that the NGINX syntax is OK:

sudo nginx -t

# output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Finally restart the service:

sudo systemctl restart nginx

Note: The above step is only for backend, you can follow the same step and enter the proxy_pass with appropriate address

Conclusion

Congratulations! You’ve successfully deployed your project to your server. Now, let’s access your newly deployed application and ensure that all features are running smoothly. You can find the project repository and the final result.

I hope this guide has been helpful in simplifying the deployment process for you. If you have any questions, feedback, or suggestions for improvement, please don’t hesitate to leave a comment below. Your input is valuable and will help us enhance future tutorials.

Thank you for reading, and happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *