Skip to main content

GitLab CI Pipeline: Compile and Deploy a Go Application via SCP (Embedded Device Deployment)

569 words·
GitLab GitLab CI CI Pipeline Go Golang
Table of Contents
GitLab-CI-Go-Application - This article is part of a series.
Part 1: This Article

Overview
#

In this tutorial I’m using the following setup based on Ubuntu 22.04 servers, GitLab is dockerized:

192.168.70.4 # GitLab
192.168.70.5 # GitLab Runner
192.168.70.6 # Deployment Server

I’m using the same setup for the deployment via SSH as described in my blog post: GitLab CI Pipeline - Deploy website with Nginx Docker Container

The main requirements for the deployment via SSH key are the following:

  • Create a SSH key pair on the server where GitLab is deployed

  • Copy the public SSH key to the authorized keys file of the Deployment server

  • SSH into the deployment servers to add the fingerprint

  • Add the private SSH key as variable to the GitLab Repository CI/CD settings

  • On the deployment server, a user named “gitlab-deployment” is used for the authentication of for the GitLab CI pipeline



Deployment Server Prerequisites
#

Deployment Folder
#

Create a folder for the Go binary deployment:

# Create folder
sudo mkdir /go-binary

# Change the permissions
sudo chown -R gitlab-deployment:root /go-binary



GitLab Repository
#

This GitLab repository is available on GitHub:
https://github.com/jueklu/compile-and-deploy-go-binary-via-scp


File & Folder Structure
#

The file and folder structure of the GitLab repository looks like this:

GitLab-Repository
├── .gitlab-ci.yml
├── go.mod
├── main.go
└── README.md

CI Pipeline Manifest
#

  • .gitlab-ci.yml
# Variables that will be reused in the pipeline
variables:
  DEPLOY_IP: "192.168.70.6"  # Deployment server IP
  DEPLOY_USER: "gitlab-deployment"  # Deployment server SSH user
  OUTPUT_DIR: go-bin  # Directory to store the compiled binary
  OUTPUT_NAME: $OUTPUT_DIR/example-binary_${CI_COMMIT_REF_SLUG} # Name of the binary (same as the project name)


# Pipeline stages
stages:
  - compile
  - deploy


### Compile Job
compile:
  image: golang:latest
  stage: compile
  before_script:  # Initialize the Go module environment
    # Create directory for the compiled binary
    - mkdir -p $OUTPUT_DIR
    # Initialize a Go module if it doesn't already exist
    - go mod init example-project || true
    # Download dependencies (even if there are none, it's safe to run)
    - go mod tidy
  script:  # Compile the Go binary and store it in the specified output directory
    # Compile the Go program and output the binary to $OUTPUT_NAME
    - go build -o $OUTPUT_NAME ./main.go
    # List binary in the logs
    - ls -la $OUTPUT_DIR
  artifacts:
    paths:
      # Save the binary as an artifact for the next stage
      - $OUTPUT_NAME
  only:
    - main


### Deploy Job
deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    # Update the package index, install the OpenSSH client for SSH connections
    - apk update && apk add openssh-client
    # If the private SSH key file ($ID_RSA) exists, set secure permissions (read/write for the owner only)
    - if [ -f "$ID_RSA" ]; then chmod og= $ID_RSA; fi
  script:
    # Copy the binary to the target Linux server
    - scp -i $ID_RSA -o StrictHostKeyChecking=no $OUTPUT_NAME $DEPLOY_USER@$DEPLOY_IP:/go-binary
  only:
    - main

Go Source Code
#

This Go code will just output “Hi there!” when executed.


main.go
#

  • main.go
// Declare the main package / required for any standalone executable Go program
package main

// Import the fmt package for formatted input/output functions
import "fmt"

// Define the main function, the entry point of the program
func main() {
  fmt.Println("Hi there!") // Print the message to the console
}

go.mod
#

  • go.mod
module jueklu/some-go-project

go 1.21.8



Verify the Deployed Go Binary
#

Verify the Binary
#

Verify the file on the deployment server:

# List files
sudo ls /go-binary

# Shell output:
example-binary_main

Execute the Binary
#

# Run the binary
sudo /go-binary/example-binary_main

# Shell output:
Hi there!
GitLab-CI-Go-Application - This article is part of a series.
Part 1: This Article