这是我参与更文挑战的第3天,活动详情查看:更文挑战git
本文记录了如何使用 Jenkins Pipeline 实现构建和远程部署。github
企业里常见的项目自动化流程应该构建机从代码仓拉取代码进行构建,构建完成后会将产物推送到制品库中,好比镜像仓, 而后中间会有测试环境,用于进行自动化测试或人工测试,最后进行远程部署。golang
这里咱们用的 Go 的项目结构,它大概的结构应该是下面这样的:web
|-- my-app
|-- .gitignore
|-- README.md
|-- LICENSE
|-- go.mod
|-- go.sum
|-- main.go
|-- pkg
|-- ...
复制代码
由于这里构建的是 Go 的项目,若是用到私有库,在 go mod tidy
时会要求提供 Git 凭证,咱们能够如今 Jenkins 的凭证管理中建立 Username with password
类型的凭证,其中 Username
就是 GitHub 的用户名,password
则是 GitHub 的 AccessToken
,这里主要用到的是 AccessToken
,Username
其实并不须要。docker
但在 Jenkins Pipeline 中使用 usernamePassword
时要求同时定义用户名变量名 usernameVariable
和 密码变量名 passwordVariable
。bash
stage('Build') {
steps {
withCredentials(bindings: [
usernamePassword(credentialsId: 'GITHUB_CREDENTIAL',
usernameVariable: 'GITHUB_USER',
passwordVariable: 'GITHUB_ACCESS_TOKEN'
)
]) {
sh ''' git config --global url."https://${GITHUB_ACCESS_TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/" go mod tidy go build -o bin/my-app main.go '''
}
}
}
复制代码
在构建完成后,咱们会将构建产物推送到制品库,而后咱们能够从制品库中拉取构建产物进行部署测试环境并进行测试,在验证经过后,会从制品库中拉取验证经过的产物进行部署上线。服务器
但在本文中,咱们的应用相对简单,能够忽略推送产物到制品库以及中间的测试验证环节,目标是实现构建后当即部署上线。markdown
通常来讲,线上环境和构建环境不会是同一台机器,因此这个时候咱们须要将构建产物复制到另外一台服务器上,而后在另外一台服务器上进行部署。app
因为须要对另外一台服务器进行操做,因此咱们须要在 Jenkins 上配置 DEPLOY_HOST
、DEPLOY_PORT
和 SSH_CREDENTIAL
三个凭证,其中 DEPLOY_HOST
和 DEPLOY_PORT
是 Secret text
类型的凭证,SSH_CREDENTIAL
是 SSH Username with private key
类型的凭证。ssh
stage('Deploy') {
environment {
DEPLOY_HOST = credentials('DEPLOY_HOST')
DEPLOY_PORT = credentials('DEPLOY_PORT')
}
steps {
withCredentials([
sshUserPrivateKey(credentialsId: 'SSH_CREDENTIAL',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USERNAME'),
]) {
sh """ mkdir -p ~/.ssh && chmod 700 ~/.ssh echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config cat ${SSH_KEY} > ~/.ssh/id_rsa && chmod 400 ~/.ssh/id_rsa scp -P ${DEPLOY_PORT} bin/my-app ${SSH_USER}@${DEPLOY_HOST}:/data/my-app ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} \"nohup /data/my-app >> /data/my-app.log 2>&1 &\" """
}
}
}
复制代码
部署的步骤主要包括:
nohup /data/my-app >> /data/my-app.log 2>&1 &
其中简化了一些细节,好比在部署前,咱们须要先备份数据。因此这里咱们能够写一个复杂的部署脚本 deploy.sh
放在项目中,而后在 Jenkins Pipeline 中使用 scp
将部署脚本文件复制到部署服务器,假设放在 /data/deploy.sh
,最后只需 ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} /bin/bash /data/deploy.sh
便可。
pipeline {
agent {
docker {
image 'golang:1.15-alpine'
args '-v /data/my-app-cache:/go/.cache'
}
}
options {
timeout(time: 20, unit: 'MINUTES')
disableConcurrentBuilds()
}
stages {
stage('Build') {
steps {
withCredentials(bindings: [
usernamePassword(credentialsId: 'GITHUB_CREDENTIAL',
usernameVariable: 'GITHUB_USER',
passwordVariable: 'GITHUB_ACCESS_TOKEN'
)
]) {
sh ''' git config --global url."https://${GITHUB_ACCESS_TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/" go mod tidy go build -o bin/my-app main.go '''
}
}
}
stage('Deploy') {
environment {
DEPLOY_HOST = credentials('DEPLOY_HOST')
DEPLOY_PORT = credentials('DEPLOY_PORT')
}
steps {
withCredentials([
sshUserPrivateKey(credentialsId: 'SSH_CREDENTIAL',
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USERNAME'),
]) {
sh """ mkdir -p ~/.ssh && chmod 700 ~/.ssh echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config cat ${SSH_KEY} > ~/.ssh/id_rsa && chmod 400 ~/.ssh/id_rsa scp -P ${DEPLOY_PORT} bin/my-app ${SSH_USER}@${DEPLOY_HOST}:/data/my-app ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} \"nohup /data/my-app >> /data/my-app.log 2>&1 &\" """
}
}
}
}
}
复制代码
笔者不才,很是欢迎你们对本文的内容进行指正,或者与笔者进行探讨!