
Setting up a Continuous Deployment (CD) pipeline for a GoLang application involves several key steps. You'll need to use a CI/CD tool like Jenkins, GitLab CI/CD, or CircleCI to automate the build, test, and deployment process.
To create a reliable CD pipeline, it's essential to have a clear understanding of your application's dependencies and build process. In the "Understanding Go Dependencies" section, we discussed how to use tools like Go Modules to manage dependencies.
A well-structured CD pipeline should include automated tests to ensure the application is working correctly after each build. This is where Go's built-in testing framework, Go Test, comes in handy. By running Go Test as part of your pipeline, you can catch any regressions early on and prevent bugs from making it to production.
To streamline your pipeline, consider using a containerization tool like Docker to package your application and its dependencies. This makes it easier to deploy your application to different environments.
Here's an interesting read: Golang Test Command
Getting Started
Implementing CI/CD best practices can ease the way to effective software development.
Artifactory can play a central role in helping to bring those methods into your software development pipeline.
GoLang applications can be released fast and at top quality with the right approach.
You can start trying to put these best practices into practice with a free trial of Artifactory.
Attend Gophercon to dive in with the experts and explore all the best ways to release your Go applications.
Any questions about implementing CI/CD in GoLang?
If this caught your attention, see: Golang Ci Linter Install
Pipeline Setup
To set up a pipeline for Golang CI/CD, you'll need to configure Jenkins with the necessary plugins. You can use Jenkins to automate tasks such as unit testing, functional testing, building the Docker image, and pushing the Docker image to Dockerhub.
First, install Jenkins on your system and head over to the official Jenkins page to do that. You'll also need to install plugins such as Go, Docker, and the Docker plugin from the Available tab in Manage Plugins.
To make Docker and Golang available to Jenkins nodes, you'll need to configure these plugins globally by going to Manage Jenkins -> Global Tool Configuration. Set the configuration as shown in the image below, which makes Docker and Golang available to Jenkins nodes.
To build a pipeline for CI/CD, select New Item on the Dashboard and choose a Pipeline. You'll then need to configure and add the GitHub repository that will be tracked by Jenkins, which can be done periodically, manually, or after GitHub events like pull requests and commits.
Add credentials to be used by your code and Jenkins for GitHub and Dockerhub, creating two credentials as shown below:
- Unit testing
- Functional testing
- Building the Docker image
- Pushing the Docker image to Dockerhub
These tasks will be automated in your pipeline, reducing the need for separate teams to test, build, and deploy your application.
Best Practices
At JFrog, GoLang is used as the language for several flagship solutions, including Artifactory at the heart of their CI/CD.
Using GoLang for several flagship solutions is a testament to its reliability and efficiency.
GoLang is used at JFrog, and they practice what they promote by using Artifactory in their CI/CD pipeline.
Artifactory is used at the heart of JFrog's CI/CD, which suggests its importance in their development process.
The Release Workflow
The Release Workflow is a crucial step in our GoLang CD pipeline. We create a separate file for it, .github/workflows/release.yml, which will contain the necessary configuration.
Each workflow is triggered on newly created tags. However, be aware that the on condition may have some issues, such as triggering the build workflow when pushing a tag. This is because Actions is still in beta.
The job in our release workflow checks out the code and uses the GoReleaser official Docker image to do all the work. We define a different argument for the "Validate" and "Create Release" steps.
The GITHUB_TOKEN environment variable is required by Go Releaser to create a release on GitHub. This variable is passed to the container, and it's injected automatically by the Actions platform.
A new release is created on GitHub with the application artifacts and Changelog generated by Go Releaser.
Tools and Setup
To set up your GoLang application for Continuous Deployment (CD), you'll need a few essential tools installed on your local environment. You'll require git as your version control tool, Docker to build containers locally, and Go as the programming language for your application.
Here are the tools you need to have installed:
- git: For version control.
- docker: For building containers locally.
- go: As the programming language for your application.
- wsl2 (if using Windows): For installing dependencies within WSL.
- Gitlab: To follow the next steps.
- VM: To prepare a virtual machine, either on your local machine or with a cloud provider.
By the way, a disclaimer before we proceed further. The step-by-step tutorial I've written in this article uses Ubuntu within the WSL system, and I will also be using commands that are available within that operating system.
Create Dockerfile and docker-compose.yaml
To create a Dockerfile, start by creating a new file in the root directory of your project. This file should have a common configuration used for Golang applications, declaring two steps: the builder step and the final step.
The builder step is used to build the Golang application, and the second step copies the build output into the Docker image. You can run the following command to build the Docker image locally and ensure the Dockerfile specification is correct.
If the build is successful, the output should look like a list of steps executed by Docker. Next, create a docker-compose.yaml file in the deployment/production folder, or use a different environment folder if you have multiple environments.
In the docker-compose.yaml file, you can define two containers to run, just like the example shows. Replace the 'alianarib' value with your GitLab username and run the command to create the containers. After running the command, you should see two files in your current directory.
VM Setup
VM Setup is a crucial step in getting your application up and running. You'll need to choose a virtual machine (VM) provider, and for this example, we'll be using Vultr due to its affordability and straightforward setup.
To prepare the VM for production, you'll need to install Docker and the Docker Compose plugin. This will allow you to manage containers and orchestrate your application.
Creating a new user for deployment purposes is also essential. This user will be used to manage the application without having root access.
You'll also need to add the previously generated public key to the authorized_keys list to enable secure SSH login.
To ensure secure access, you'll need to create a new non-root user for deployment and disable password-based login on the VM.
Here are the steps to prepare the VM:
- Install Docker and the Docker Compose plugin.
- Create a new user for deployment purposes.
- Add the previously generated public key to the authorized_keys list.
- Create a ‘deployment’ folder.
After logging into the VM, you'll need to install Docker and Docker Compose. This will provide the necessary dependencies for your application.
Broaden your view: Docker Golang
Jenkins and Docker Setup
Jenkins is a tool that can be used for setting up CI/CD, and it's completely open source. It's written in Java.
To get started with Jenkins, you first need to install it on your system. Head over to the official Jenkins page to do that.
Jenkins can automate all of your CI/CD processes, including unit testing, functional testing, building the Docker image, and pushing the Docker image to Dockerhub. You can use a script in the Jenkinsfile to set this up.
To configure Jenkins, you'll need to install some plugins and set up credentials. You'll need to install Go, Docker, and the Docker plugin from the Available tab in Manage Plugins.
Here are the Jenkins plugins you'll need to install:
- Go
- Docker
- Docker plugin
Once you've installed the plugins, you'll need to configure them globally by going to Manage Jenkins -> Global Tool Configuration. You'll need to set up Docker and Golang to be available to Jenkins nodes that will run CI/CD workflows.
Jenkins can track your GitHub repository and run your CI/CD pipeline periodically, manually, or after GitHub events. You'll need to add the GitHub repository with the appropriate branch you want to track.
Prerequisites
To get started with the tools and setup for your GoLang applications, you'll need to have a few key things in place.
Git is the version control tool we'll be using, so make sure you have it installed.
You'll also need to have Docker installed, as we'll be using it to build containers locally.
Go needs to be installed as well, as we'll be using it as an example application in this article.
If you're using Windows, you should use WSL2 and install all your dependencies within WSL.
To follow the next steps, make sure you have an account on GitLab.com.
A Virtual Machine (VM) is also required, whether it's on your local machine or with a cloud provider.
Here's a list of the required tools:
- git
- docker
- go
- wsl2 (if using Windows)
- Gitlab
- VM
Deployment and Rollback
You can deploy your Go-based microservices with ease by creating a GitLab tag, which triggers an automatic pipeline that performs the deployment to your server.
The deployment process can be done in a single step, and you can verify that everything is running smoothly by checking the output of the 'docker ps' command.
To access the application, simply use the public IP, and if the output appears as expected, you can be sure that your application is running fine.
Build Once, Deploy Anywhere
Building a Go-based microservice requires a fresh build at each staging transition, but this introduces new uncertainties as shared code changes.
You can't be certain what's in the build, even with safeguards to help assure deterministic builds.
Many software development procedures require repeating the same quality checks in each stage.
However, by building your Go-based microservices once, you can guarantee that what was tested is exactly what is being released to production.
Building each Docker image once and promoting it through a series of staging repositories is a more efficient approach.
This ensures that the same quality checks aren't repeated in each stage, saving time and reducing uncertainty.
In this way, you can ensure that your Go-based microservices are built once and deployed anywhere with confidence.
By following this approach, you can streamline your deployment process and reduce the risk of errors.
Explore further: Golang Build Flags
Step 5: Deployment
In this step, we'll explore the deployment process, which is made easy by having a CI/CD pipeline in place. This pipeline can be triggered by creating a GitLab tag in the ‘Code > Tags’ menu.
Creating a GitLab tag automatically runs a pipeline that performs the deployment to your server. The pipeline status can be checked to ensure everything is running smoothly.
If the pipeline is all green, it's a good sign that the deployment was successful. To verify this, you can check your server using the ‘docker ps’ command to see all running containers.
The output should show the number of containers running, such as 2 containers in the example. This indicates that the application is up and running.
If you make changes to the application code, such as changing the word ‘world’ to ‘Indonesia’ in the ‘handler.go’ file, you can push the code and create a new tag to see the changes live.
However, what if there's an error in the deployment pipeline and you need to mitigate it quickly? We'll discuss how to handle such errors in the next step.
Here's a summary of the steps involved in the deployment process:
Step 6: Rollback
In a deployment scenario, errors can occur, and it's crucial to have a rollback plan in place to mitigate the issue quickly.
To simulate an error, a 'panic' function in Golang can be used in the 'handler.go' file, as shown in the previous example.
The goal of a rollback is to return the application to a previous version where there was no error or panic, allowing users to continue using the application without interruption.
By triggering the deployment pipeline of the previous version, the application can be quickly restored to a stable state, minimizing downtime and user impact.
This approach has been successfully used in various deployment scenarios, where a quick rollback was necessary to resolve critical errors.
If this caught your attention, see: Golang Version Manager
Continuous Integration
Continuous Integration is a game-changer for GoLang CD. It automates the process of building, testing, and validating code changes, ensuring that every commit is a working version of the software.
This saves developers a lot of time and effort, allowing them to focus on writing code rather than manually testing it. Continuous Integration tools like Jenkins and CircleCI are popular choices for GoLang projects.
By integrating automated testing into the development process, teams can catch errors and bugs early on, reducing the risk of downstream problems. In fact, a study found that teams using Continuous Integration saw a 50% reduction in defects.
Automated testing also helps to ensure that code changes don't break existing functionality, which is a major concern for GoLang developers. By running tests automatically, teams can be confident that their code is stable and reliable.
In a GoLang CD pipeline, Continuous Integration is typically the first step, followed by Continuous Deployment and Continuous Monitoring. This allows teams to quickly and reliably deliver new features and updates to users.
By automating the testing process, teams can also get faster feedback on code changes, which enables them to make data-driven decisions and improve the overall quality of their software.
Featured Images: pexels.com


