Deploying a Go App to DigitalOcean with Zero Downtime using pmgo and GitHub Actions
Tags: go, cicd, github, deploymen
Published: 2023-01-06 19:28:49

In this tutorial, we will learn how to use the `pmgo` utility and GitHub Actions to deploy a Go application to DigitalOcean with zero downtime. We will be using a feature called "rolling deployments" which allows us to deploy new versions of our app while keeping the old version running until the new version is fully up and running. This ensures that there is no downtime for our users during the deployment process.

**Prerequisites**

Before we begin, you will need to have the following:

- A DigitalOcean account and an API key
-     A Go application that you want to deploy
-     A GitHub repository for your Go app
-     The pmgo utility installed on your local machine

**Setting up DigitalOcean**

First, we need to create a droplet on DigitalOcean to host our Go app. You can do this through the DigitalOcean control panel or using the DigitalOcean API.

Once you have created your droplet, you will need to set up a PostgreSQL database and configure your Go app to use it. You can do this through the DigitalOcean control panel or by connecting to your droplet via SSH and installing and configuring PostgreSQL manually.

**Setting up pmgo**

The **pmgo** utility is a command-line tool that helps you deploy Go applications to servers. It handles building and deploying your code, as well as setting up the necessary services and configurations.

To install pmgo, simply fetch it using go cli:

```bash
$ go get github.com/struCoder/pmgo
$ mv $GOPATH/bin/pmgo /usr/local/bin
```
or

```bash
git clone https://github.com/struCoder/pmgo.git
cd path/to/struCoder/pmgo
go build -v pmgo.go
mv pmgo /usr/local/bin
```

To use `pmgo`, you will first need to create a pmgo.yml file in the root of your Go app repository. This file will contain the configuration for your deployment.

Here is an example `pmgo.yml` file for a Go app:

```yaml
name: my-go-app

servers:
  - address: my-go-app.example.com
    user: root

build:
  - go build

deploy:
  - pmgo deploy

services:
  - name: my-go-app
    command: ./my-go-app

```
This file specifies the name of your app, the server address and user, the build command, the deploy command, and the service command.

**Setting up GitHub Actions**

GitHub Actions are automated tasks that can be triggered by certain events in your GitHub repository. We will be using GitHub Actions to automatically build and deploy our Go app whenever we push code to the repository.

To set up GitHub Actions, you will need to create a .github/workflows directory in your repository and add a YAML file to it that specifies the steps of your workflow.

Here is an example workflow file that uses pmgo to deploy a Go app to DigitalOcean with zero downtime:

```yaml
name: Deploy Go App

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Build and Deploy Go App
        run: pmgo deploy --rolling

```
This workflow file specifies that it should be triggered on pushes to the main branch, and it has a single job that runs on the latest version of Ubuntu and consists of two steps. The first step checks out the code from the repository, and the second step runs the `pmgo deploy` command with the `--rolling` flag.

A good thing to also note is that it is possible to deploy a Go app to DigitalOcean without using the `pmgo.yml` file. Instead of using the `pmgo deploy` command, you can specify the steps of your deployment manually in your GitHub Actions workflow file.

Here is an example workflow file that demonstrates how to do this:

```yaml
name: Deploy Go App

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Build Go App
        run: go build
      - name: Copy Go App to Server
        uses: appleboy/scp-action@master
        with:
          host: my-go-app.example.com
          username: root
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          source: my-go-app
          target: /root/my-go-app
      - name: Restart Go App Service
        run: ssh root@my-go-app.example.com "systemctl restart my-go-app"

```
This workflow file performs the following steps:

1. It checks out the code from the repository.
2.     It builds the Go app using the go build command.
3.     It copies the built binary to the server using the scp-action action.
4.     It restarts the Go app service on the server using the systemctl command.

By manually specifying these steps, you can deploy your Go app to DigitalOcean without using the pmgo.yml file. However, using pmgo can simplify the deployment process and provide additional features such as rolling deployments and service management.

**Conclusion**

In this tutorial, we learned how to use the pmgo utility and GitHub Actions to deploy a Go app to DigitalOcean with zero downtime. We used the pmgo.yml file to specify the configuration for our deployment and a GitHub Actions workflow to automate the build and deployment process. We also saw how to manually deploy a Go app to DigitalOcean without using the pmgo.yml file.

By following these steps, you can easily and automatically deploy your Go apps to DigitalOcean, ensuring that your users experience no downtime during the deployment process.