Skip to content

Bare Metal Deployment

This guide shows how to deploy a go-zero service directly on a physical server using nohup as a process daemon, with Jenkins handling the build and deployment pipeline.

  • A Jenkins server with Go installed (see CI/CD Setup)
  • GitLab with your project repository
  • A target deployment server accessible via SSH from Jenkins
apicode.api
syntax = "v1"
info(
title: "deploy demo"
desc: "deployment example"
author: "go-zero"
)
type (
HelloReq {
Msg string `form:"msg"`
}
HelloResp {
Msg string `json:"msg"`
}
)
service apicode {
@doc "hello"
@handler hello
get /hello(HelloReq) returns(HelloResp)
}

Generate and build the project:

Terminal window
cd apicode && goctl api go -api *.api -dir ./
go mod tidy

Add the logic in hellologic.go:

func (l *HelloLogic) Hello(req *types.HelloReq) (resp *types.HelloResp, err error) {
return &types.HelloResp{
Msg: "hello->" + req.Msg,
}, nil
}

Verify locally:

Terminal window
go run apicode.go
# Visit http://127.0.0.1:8888/hello?msg=world

Push the code to GitLab.

Jenkins needs SSH access to both GitLab (to pull code) and the target server (to deploy):

Terminal window
# On the Jenkins server — copy its public key
cat /root/.ssh/id_rsa.pub

Add this key to:

  1. GitLab — Settings → SSH Keys (for code checkout)
  2. Target server — Append to /root/.ssh/authorized_keys (for deployment via scp)
  1. In Jenkins, click New Item → name it apicode → select Pipeline → OK

  2. Under General, check This project is parameterizedAdd ParameterGit Parameter

    • Name: branch
    • Parameter Type: Branch
    • Default: master
  3. In the Pipeline section, enter the script:

pipeline {
agent any
parameters {
gitParameter name: 'branch',
type: 'PT_BRANCH',
branchFilter: 'origin/(.*)',
defaultValue: 'master',
selectedValue: 'DEFAULT',
sortMode: 'ASCENDING_SMART',
description: 'Select branch to build'
}
stages {
stage('Info') {
steps {
sh 'echo Branch: $branch'
}
}
stage('Checkout') {
steps {
checkout([$class: 'GitSCM',
branches: [[name: '$branch']],
doGenerateSubmoduleConfigurations: false,
extensions: [],
submoduleCfg: [],
userRemoteConfigs: [[
credentialsId: 'gitlab-cert',
url: 'ssh://git@your-gitlab:2222/root/apicode.git'
]]
])
}
}
stage('Build') {
steps {
sh '/usr/local/go/bin/go build -o apicode apicode.go'
sh 'mkdir -p deploy && cp -r ./etc ./apicode deploy'
sh 'tar -zcvf deploy.tar.gz deploy'
}
}
stage('Deploy') {
steps {
sh 'scp ./deploy.tar.gz root@your-target-server:/root/'
sh 'ssh root@your-target-server "tar -xvf /root/deploy.tar.gz -C /root/"'
sh 'ssh root@your-target-server "nohup /root/deploy/apicode -f /root/deploy/etc/apicode.yaml > /root/deploy/stdout.log 2> /root/deploy/stderr.log &"'
}
}
}
}
  1. Open the apicode pipeline in Jenkins
  2. Click Build with Parameters
  3. Select the branch and click Build

Once the pipeline completes, verify the deployment:

Terminal window
curl "http://your-target-server:8888/hello?msg=world"
# {"msg":"hello->world"}
/etc/systemd/system/apicode.service
[Unit]
Description=apicode service
After=network.target
[Service]
Type=simple
ExecStart=/root/deploy/apicode -f /root/deploy/etc/apicode.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Terminal window
sudo systemctl enable apicode
sudo systemctl start apicode
/etc/supervisor/conf.d/apicode.conf
[program:apicode]
command=/root/deploy/apicode -f /root/deploy/etc/apicode.yaml
autostart=true
autorestart=true
stdout_logfile=/var/log/apicode.stdout.log
stderr_logfile=/var/log/apicode.stderr.log
Terminal window
sudo supervisorctl update
sudo supervisorctl start apicode