DEV Community

Nandes Simanjuntak
Nandes Simanjuntak

Posted on

Deploying Golang and Angular Applications with Docker and Nginx

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"]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.

Clone Project

Begin by cloning your project onto your server. I typically place my projects in the /var/www/html directory. Once the cloning is complete, navigate to the project directory and run the following command to start your project: docker compose up -d

CONTAINER ID   IMAGE                      COMMAND                  CREATED        STATUS        PORTS                                       NAMES
c93969a04b43   image-converter-backend    "./main"                 46 hours ago   Up 46 hours   0.0.0.0:9090->9090/tcp, :::9090->9090/tcp   image-converter-backend-1
3856213fb4f5   image-converter-frontend   "/docker-entrypoint.…"   46 hours ago   Up 46 hours   0.0.0.0:8081->80/tcp, :::8081->80/tcp       image-converter-frontend-1
Enter fullscreen mode Exit fullscreen mode

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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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 ./
Enter fullscreen mode Exit fullscreen mode

Check that the symlink was created successfully:

ls -l

# output:
... yourdomain.com -> /etc/nginx/sites-available/yourdomain.com
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Finally restart the service:

sudo systemctl restart nginx
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (1)

Collapse
 
zidd profile image
zidd

Amazing works! Bring it on my brother!!