Skip to main content

Compilation and Deployment

Preface

This article will guide you through compiling and deploying a Go project. If you just want the quick steps, skip to the Conclusion.

Step 1: Compilation

1. Go Build Command

go build

By default, go build generates a statically linked binary for the current operating system and architecture. This means all dependencies, including the Go standard library, are packaged into a single executable. This simplifies deployment by eliminating concerns about missing libraries.

The difference between dynamic and static compilation is that dynamic binaries need to load dependencies at runtime, while static binaries contain everything they need, making them more portable.

2. Static Compilation

CGO_ENABLED=0 go build

3. Dynamic Compilation

CGO_ENABLED=1 go build

4. Force Dynamic Compilation

CGO_ENABLED=1 go build -ldflags '-linkmode=external -extldflags "-shared"'

5. Cross-Compilation

Go's cross-platform capability is a key strength. It natively supports cross-compiling, allowing you to build executables for different operating systems and architectures from a single machine.

Set the GOOS and GOARCH environment variables to cross-compile:

# Compile for Linux
GOOS=linux GOARCH=amd64 go build

# Compile for Windows
GOOS=windows GOARCH=amd64 go build

Common GOOS values include windows, linux, and darwin (macOS); GOARCH corresponds to amd64, 386, arm, etc.

6. Compilation Optimization

Go provides several flags for optimizing the resulting binary:

  • -ldflags: Passes flags to the linker, which can reduce the binary size by stripping symbols and debug information:

    go build -ldflags="-s -w"
  • -trimpath: Removes build paths to reduce the risk of information leakage:

    go build -trimpath

These options help optimize the binary size and performance.

Step 2: Deployment

1. File Deployment

The simplest way to deploy a Go application is to transfer the compiled binary to the target server. Thanks to Go's static linking, you only need to deploy the executable file.

Typical deployment steps:

  1. Compile the project:
    GOOS=linux GOARCH=amd64 go build -o myapp
  2. Transfer the binary to the server using scp or rsync:
    scp myapp user@server:/path/to/deploy
  3. Run the binary on the server:
    ./myapp

2. Containerized Deployment

Docker is widely used for modern deployments, packaging applications and their dependencies into a container that can run in any environment. Go’s static compilation makes it ideal for Docker containerization.

Dockerfile Example

# Use official Golang image for building
FROM golang:1.20 AS builder

# Set work directory
WORKDIR /app

# Copy source code to the container
COPY . .

# Build the application
RUN go build -o myapp

# Use a smaller image for running the app
FROM alpine:latest
WORKDIR /root/

# Copy the compiled binary from the builder stage
COPY --from=builder /app/myapp .

# Set the command to execute
CMD ["./myapp"]

Build and run the Docker image:

docker build -t myapp .
docker run -d -p 8080:8080 myapp

3. Automated Compilation and Deployment (CI/CD)

In modern development workflows, Continuous Integration and Continuous Deployment (CI/CD) ensure efficient and reliable delivery. Popular CI tools include GitLab CI, GitHub Actions, and Jenkins.

Example: Using GitHub Actions for Automated Deployment

Add the following .github/workflows/main.yml to your GitHub project:

name: Go CI

on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.20
- name: Build
run: go build -o myapp
- name: Deploy to server
run: scp myapp user@server:/path/to/deploy

This CI file triggers a build and deployment whenever changes are pushed to the main branch.

Conclusion

Below is a compilation and deployment script you can customize to your needs:

#!/bin/bash
set -e

KEY=auth

USER=your-user-name
HOST=127.0.0.1
DOMAIN=gostartkit.com

GIT_COMMIT=$(git rev-parse HEAD)

# Compilation

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build \
-ldflags "-X 'main.osarch=linux/amd64' -X 'main.gitrev=${GIT_COMMIT}' -s -w" \
-trimpath \
-buildmode=exe \
-tags release \
-o bin/${KEY}-linux-amd64

# Deployment

rsync -avzP ./bin/$KEY-linux-amd64 -e "ssh -o ProxyCommand='nc -x 127.0.0.1:1080 %h %p'" $USER@$HOST:/opt/local/www/$KEY.$DOMAIN/bin/

Go’s compilation and deployment process is straightforward. By mastering compilation optimization, cross-compilation, and containerization techniques, you can make your Go application more efficient and portable. CI/CD tools like GitHub Actions further enhance team collaboration and deployment efficiency.


Copyright Notice: Free to Share - Non-commercial - No Derivatives - Keep Author - Keep Source

Author: afxcn

Source: https://gostartkit.com/docs/golang/compile-deploy

Date: September 5, 2024