How to Automate Golang Delivery With Buddy CI/CD
By: Gabriel Tanner
Tags: Programming, DevOps, Golang, Continuous Delivery, Continuous Integration

Step 4. Continuous Delivery Pipeline

Now that the tests are successfully running, it is time to build and deploy the application on our DigitalOcean droplet. Since we want our application to be deployed using Docker, we first need to build the image and push it to some kind of a container registry before using it on our droplet.

Build the application

In this step, we’ll build a Docker image of our application and push it to a container registry. We’ll use Docker Hub as the registry, as it’s the most popular and free to use for public images (plus one private image is free).

Note: Feel free to use another public registry or your own private one. If you want to know how to create your own private registry from scratch, you can follow this guide.

Start by adding the Build image action from the Docker section of the action roster:

Adding Build Image action to the pipeline

Next, we need to select the Dockerfile that will serve as the basis of our image, alongside the context in which the build command will be executed. Here we choose the directory for the project:

Configuring directory for Docker Build action

Now you only need to select a registry and provide the necessary credentials for pushing the image to your account in the Options window. You can also set the repository and tag of the image:

Selecting registry for the Docker image

Run the Docker image

The next step is deploying and running the image on our DigitalOcean droplet. There is currently no official Buddy action for this (yet), so we’re going to use the SSH action instead:

Adding SSH action to Buddy pipeline

After adding the action to the pipeline, we need to configure it to match our droplet settings:

Set the authentification mode to Password (if you are using an SSH key, then select Private SSH key or Buddy workspace key instead)

(if you are using an SSH key, then select or instead) Fill in the IP Address, username, and password used to sign in to your server

Next, add the following commands to the action details:

# Pull Docker image

docker pull gabrieltanner/golang-http-server:latest # Stop and remove the container if it already exists

docker stop http-server || true && docker rm http-server || true # Start the new container

docker run -p 8080:8080 -d --name http-server gabrieltanner/golang-http-server

Let’s walk through these commands:

The docker pull command is used to pull our image from the container registry on the selected server.

command is used to pull our image from the container registry on the selected server. The second command is used to stop and remove the existing container. This needs to be done to update the container to the newly built image version. The commands will return an error if the container is not running. This is expected behavior, so we need to ignore it using ... || true .

. The docker run command starts the container and publishes port 8080 to the host system using the -p flag.

A properly configured SSH action will look like this:

SSH action configuration

You can use environment variables to store sensitive data like login and password.

Optional: wait for approval

You can add some kind of manual confirmation to the process before deploying the new version to your production server. This can be done by adding the “Wait for approval” action to your pipeline:

Wait for approval configuration

Test the pipeline

Once you’ve finished configuring the newly added actions, it’s time to rerun the pipeline to test the functionality. For that, you can either push some changes to the Git repository or click on the Run pipeline button to trigger the run manually:

Pipeline post-execution details

You now have a fully functional continuous integration/deployment pipeline for your Golang application. On every push to the selected branch, however, you can still add some useful actions that keep you up to date with your application’s current build status.