相关系列文章:
1、jenkins构建前端并上传服务器
在这篇文章中(Docker+Jenkins+Harbor)未完成前端的远程部署,这里对前端vue工程进行编译打包并上传远程服务器。
1-1 jenkins安装nodejs和nodejs插件
1-2 前端编译流水线语法
bash
stage('编译前端工程') {
steps {
dir("${env.WORKSPACE}/infra-portal"){
nodejs('Nodejs14') {
sh '''
npm -v
npm config set registry https://registry.npm.taobao.org
npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass
rm -rf dist/
npm install && npm run build
'''
sh "tar -zcvf dist-${env.TAG}.tar.gz dist/*"
echo '打包完成'
}
}
}
}
1-3 jenkins免密登陆配置
jenkins服务器执行ssh-keygen -t rsa生成密钥对,遇到卡顿地方直接回车即可
bash
ssh-keygen -t rsa
远程服务器(需要免密登陆的服务器)在/root/.ssh路径下会生成authorized_keys文件
执行下面代码将jenkins服务器生成的id_rsa.pub(公钥)内容复制到authorized_keys文件下:
bash
# 复制到远程服务器
ssh-copy-id root@192.168.88.9
bash
# 重启远程服务器的SSH
systemctl restart sshd
# 设置权限
chmod 700 /root/.ssh
chmod 644 authorized_keys
chmod 644 known_hosts
# 验证,不需要密码登陆
ssh 192.168.88.9
ps: 根据网上其他人的文章到这一步也就完成,但我这边不成功,还是需要密码才能登陆,我这边重启了服务器才成功
1-4 jenkins配置全局凭证并远程部署
添加SSH凭证,配置前面1-3生成的id_rsa私钥内容
username:远程服务器名
Private Key: 私钥文件(id_rsa)
bash
# 流水线语法,credentialsId为创建的凭证随机生成的ID,也可以自定义生成ID
stage('上传远程服务器') {
steps {
dir("${env.WORKSPACE}/infra-portal"){
withCredentials([sshUserPrivateKey(credentialsId: '48a060e5-74f0-4193-90d7-a8b6a7fdbab3', keyFileVariable: 'identity', usernameVariable: 'root')]) {
sh 'ssh -T -o StrictHostKeyChecking=no root@192.168.88.9'
sh 'scp -P 22 -o StrictHostKeyChecking=no dist-v1.0.0.tar.gz root@192.168.88.9:/home/'
echo '上传成功'
}
}
}
}
ps: 若主机可以免登陆但容器内不行,构建时报错:Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
远程连接失败需要密码可尝试以下步骤:
bash
# 远程连接失败可能是由于容器内.ssh文件夹没有相关密钥,<container_name>为容器名,复制密钥到容器内
docker cp /root/.ssh <container_name>:/root/.ssh
# 以root进入jenkins容器下
docker exec -u root -it <container_name> bash
# 复制 Root 用户的 .ssh 目录到 Jenkins 用户的 home 目录
cp -r /root/.ssh /var/jenkins_home/
# 更改文件的所有者为 Jenkins 用户
chown -R jenkins:jenkins /var/jenkins_home/.ssh
1-5 Jenkinsfile完整代码
bash
//harbor地址
def harbor_url="192.168.88.20:9002"
//镜像库的名称
def harbor_project="infra"
//Harbor的凭证
def harbor_auth = "9ed86288-cf38-4533-86ca-792b934452f9"
// 远程连接凭证
def remote_auth = "48a060e5-74f0-4193-90d7-a8b6a7fdbab3"
// 远程服务器
def remote_addr = "root@192.168.88.9"
// 镜像
def authImage = "${harbor_url}/${harbor_project}/infra-auth:${env.TAG}"
def businessImage = "${harbor_url}/${harbor_project}/infra-business:${env.TAG}"
def gatewayImage = "${harbor_url}/${harbor_project}/infra-gateway:${env.TAG}"
def vue_dist = "dist-${env.TAG}.tar.gz"
pipeline {
agent any
tools {
// jenkins全局工具配置配置的maven和jdk
maven 'apache-maven-3.9.2'
jdk 'jdk1.8.0_291'
}
stages {
stage('拉取代码') {
steps {
echo '相关环境变量'
sh "printenv"
echo '-------------------------------------'
git 'https://gitee.com/dalao708/infra.git'
echo '拉取成功'
}
}
stage('编译前端工程') {
steps {
dir("${env.WORKSPACE}/infra-portal"){
nodejs('Nodejs14') {
sh '''
npm -v
npm config set registry https://registry.npm.taobao.org
npm config set sass_binary_site=https://npm.taobao.org/mirrors/node-sass
rm -rf dist/
npm install && npm run build
'''
sh "tar -zcvf ${vue_dist} dist/*"
echo '打包完成'
}
}
}
}
stage('上传远程服务器') {
steps {
dir("${env.WORKSPACE}/infra-portal"){
withCredentials([sshUserPrivateKey(credentialsId: "${remote_auth}", keyFileVariable: 'identity', usernameVariable: 'root')]) {
sh "ssh -T -o StrictHostKeyChecking=no ${remote_addr}"
sh "scp -P 22 -o StrictHostKeyChecking=no ${vue_dist} ${remote_addr}:/home/nginx/www/infra/"
sh "rm -rf ${vue_dist}"
echo '上传成功'
}
}
}
}
stage('清理maven库') {
steps {
dir("${env.WORKSPACE}"){
sh "rm -rf /var/jenkins_home/.m2/repository/com/infra/server/*"
echo '清理maven库完成'
}
}
}
stage('构建基础工程') {
steps {
dir("${env.WORKSPACE}/infra-server"){
sh "mvn -Dmaven.test.skip=true clean install"
//编译,安装公共工程
sh "mvn -f infra-support -Dmaven.test.skip=true clean install"
echo '构建基础工程'
}
}
}
stage('编译&构建镜像') {
steps {
dir("${env.WORKSPACE}/infra-server"){
sh "mvn -f infra-auth -Dmaven.test.skip=true clean package dockerfile:build"
sh "mvn -f infra-business -Dmaven.test.skip=true clean package dockerfile:build"
sh "mvn -f infra-gateway -Dmaven.test.skip=true clean package dockerfile:build"
echo '编译&构建镜像完成'
sh "docker tag infra-auth ${authImage}"
sh "docker tag infra-business ${businessImage}"
sh "docker tag infra-gateway ${gatewayImage}"
echo '镜像打标签完成'
}
}
}
stage('上传Harbor') {
steps {
withCredentials([usernamePassword(credentialsId: "${harbor_auth}", passwordVariable: 'password', usernameVariable: 'username')]) {
//登录到Harbor
sh "docker login -u ${username} -p ${password} ${harbor_url}"
//镜像上传
sh "docker push ${authImage}"
sh "docker push ${businessImage}"
sh "docker push ${gatewayImage}"
sh "echo 镜像上传成功"
//删除本地镜像
sh "docker rmi -f ${authImage}"
sh "docker rmi -f ${businessImage}"
sh "docker rmi -f ${gatewayImage}"
sh "docker rmi -f infra-auth"
sh "docker rmi -f infra-business"
sh "docker rmi -f infra-gateway"
sh "echo 删除本地镜像成功"
}
}
}
}
}
2、部署项目
2-1 测试是否能正常从harbor拉取镜像
bash
docker pull 192.168.88.20:9002/infra/infra-gateway:v1.0
报错:Error response from daemon: Get "https://192.168.88.20:9002/v2/": http: server gave HTTP response to HTTPS client
解决:
bash
vim /etc/docker/daemon.json
# 内容如下,保存并退出
{
"insecure-registries": ["192.168.88.20:9002"]
}
# 重新加载daemon
systemctl daemon-reload
# 重启docker
systemctl restart docker
报错:Error response from daemon: unauthorized: unauthorized to access repository: infra/infra-gateway, action: pull: unauthorized to access repository: infra/infra-gateway, action: pull
解决:
bash
# 登陆再拉取
docker login 192.168.88.20:9002 -u admin -p Harbor12345
2-2 编写docker-compose.yaml
bash
# 前面安装mysql集群时候已经安装了docker swarm集群
# node1上创建docker-compose.yaml文件
mkdir /opt/infra
cd /opt/infra
vim docker-compose.yaml
bash
version: '3.8'
services:
infra-gateway:
image: 192.168.88.20:9002/infra/infra-gateway:v1.0.0 # 拉取Harbor中拉取镜像
environment:
- SPRING_PROFILES_ACTIVE=prod
ports:
- "9000:9000"
deploy:
replicas: 1 # 部署1个副本
endpoint_mode: vip # 使用默认的vip方式进行服务访问
volumes:
- gateway-data:/app/data
infra-auth:
image: 192.168.88.20:9002/infra/infra-auth:v1.0.0
environment:
- SPRING_PROFILES_ACTIVE=prod
ports:
- "9001:9001"
deploy:
replicas: 1
endpoint_mode: vip
volumes:
- auth-data:/app/data
infra-business:
image: 192.168.88.20:9002/infra/infra-business:v1.0.0
environment:
- SPRING_PROFILES_ACTIVE=prod
ports:
- "9002:9002"
deploy:
replicas: 1
endpoint_mode: vip
volumes:
- business-data:/app/data
volumes:
gateway-data:
auth-data:
business-data:
2-3 启动&停止
bash
docker compose up -d
其他命令:
bash
# 检查docker-compose.yaml文件的命令是否正确
docker compose config -q
# 停止服务
docker compose down -v
2-4 其他
- 前端vue项目工程只需要构建完放到服务器上,nginx做映射即可,其实也可以直接通过jenkins做完这一切,上传到服务器后直接解压到指定目录
- 部署过程中可能会遇到很多问题,如虚拟机的设置的内存或者硬盘不足导致服务启动失败,需要检查看看。项目本身问题,如整合了redis集群,项目本地是单机的,需要检查一下redisConfig类是否有做动态切换等
- 构建镜像后运行时报找不到app.jar,找不到主类等,则项目中参考以下配置一下:
bash
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>com.infra.server.AuthRun</mainClass>
</configuration>
</plugin>