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.
Prerequisites
Section titled “Prerequisites”- A Jenkins server with Go installed (see CI/CD Setup)
- GitLab with your project repository
- A target deployment server accessible via SSH from Jenkins
Step 1: Create a Demo Service
Section titled “Step 1: Create a Demo Service”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:
cd apicode && goctl api go -api *.api -dir ./go mod tidyAdd 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:
go run apicode.go# Visit http://127.0.0.1:8888/hello?msg=worldPush the code to GitLab.
Step 2: Configure SSH Keys
Section titled “Step 2: Configure SSH Keys”Jenkins needs SSH access to both GitLab (to pull code) and the target server (to deploy):
# On the Jenkins server — copy its public keycat /root/.ssh/id_rsa.pubAdd this key to:
- GitLab — Settings → SSH Keys (for code checkout)
- Target server — Append to
/root/.ssh/authorized_keys(for deployment viascp)
Step 3: Create Jenkins Pipeline
Section titled “Step 3: Create Jenkins Pipeline”-
In Jenkins, click New Item → name it
apicode→ select Pipeline → OK -
Under General, check This project is parameterized → Add Parameter → Git Parameter
- Name:
branch - Parameter Type: Branch
- Default:
master
- Name:
-
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 &"' } } }}Step 4: Build & Deploy
Section titled “Step 4: Build & Deploy”- Open the
apicodepipeline in Jenkins - Click Build with Parameters
- Select the branch and click Build
Once the pipeline completes, verify the deployment:
curl "http://your-target-server:8888/hello?msg=world"# {"msg":"hello->world"}Process Management Alternatives
Section titled “Process Management Alternatives”systemd
Section titled “systemd”[Unit]Description=apicode serviceAfter=network.target
[Service]Type=simpleExecStart=/root/deploy/apicode -f /root/deploy/etc/apicode.yamlRestart=alwaysRestartSec=5
[Install]WantedBy=multi-user.targetsudo systemctl enable apicodesudo systemctl start apicodesupervisor
Section titled “supervisor”[program:apicode]command=/root/deploy/apicode -f /root/deploy/etc/apicode.yamlautostart=trueautorestart=truestdout_logfile=/var/log/apicode.stdout.logstderr_logfile=/var/log/apicode.stderr.logsudo supervisorctl updatesudo supervisorctl start apicodeWhat’s Next
Section titled “What’s Next”- Docker Deployment — Containerized deployment
- Kubernetes Deployment — Orchestrated deployment at scale