前言
本文介绍使用docker+nginx+jenkins将hexo博客部署至云服务器。
hexo博客提交云服务器流程:
- 本地电脑hexo三连,或者githubaction三连部署到github。
- jenkins监测到github项目主页更新,拉取更新后的文件到vps的jenkins工作目录,然后持续集成部署更新文件。Jenkins(概念篇):Jenkins 简介_ron jenkins 什么意思
- vps本地脚本把jenkins工作目录更新的文件传输到nginx工作目录。
开始之前确保以下几个条件:
1
| sudo apt-get install git
|
docker安装jenkins和nginx
创建目录
1 2 3 4 5 6 7 8 9
| cd /root/data/docker_data/jenkins mkdir compose mkdir jenkins_home mkdir nginx mkdir nginx/conf mkdir html mkdir html/dev mkdir html/release mkdir html/pro
|
创建docker-compose.yml
、nginx.conf
配置文件
1 2 3 4 5
| cd /root/data/docker_data/jenkins/compose touch docker-compose.yml
cd /root/data/docker_data/jenkins/nginx/conf touch nginx.conf
|
docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| version: '3' services: docker_jenkins: user: root restart: always image: jenkins/jenkins:lts container_name: jenkins ports: - 8888:8080 - 50000:50000 volumes: - ../jenkins_home/:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose docker_nginx_dev: restart: always image: nginx container_name: nginx_dev ports: - 8871:8001 volumes: - ../nginx/conf/nginx.conf:/etc/nginx/nginx.conf - ../html:/usr/share/nginx/html - ../nginx/logs:/var/log/nginx
docker_nginx_sit: restart: always image: nginx container_name: nginx_sit ports: - 6092:8002 volumes: - ../nginx/conf/nginx.conf:/etc/nginx/nginx.conf - ../html:/usr/share/nginx/html - ../nginx/logs:/var/log/nginx
|
上面的代码跑了三个容器,jenkins,nginx_dev,nginx_sit
nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; gzip on;
server { listen 8001; server_name localhost;
location / { root /usr/share/nginx/html/dev/hexo;
index index.html; try_files $uri $uri/ /index.html; } }
server { listen 8002; server_name localhost;
location / { root /usr/share/nginx/html/sit/hexo;
index index.html; try_files $uri $uri/ /index.html; } }
}
|
运行docker容器
1 2
| cd /root/data/docker_data/jenkins/compose docker-compose up -d
|
查看容器运行状态
验证nginx
在/docker/html/dev/hexo
目录下新建index.html
,文件内容如下
1 2 3 4 5 6 7 8 9 10 11
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>welcome to Nginx</h1> </body> </html>
|
浏览器访问服务器ip:8871,例如192.168.8.5:8871
jenkins配置
浏览器输入你的服务器ip:8888
图片展示的docker-compose.yml和上面给出的有出入。当前运行给出挂载jenkins_home前有两个点,代表当前目录的上一级目录。所以实际运行的jenkins_home目录在docker-compose.yml的上一级目录。总之到jenkins_home目录下去找密码。
后面的安装和配置建议看从零开始搭建JENKINS+GITHUB持续集成环境,这篇文章看Jenkins的使用
到验证构建
。主要步骤看建议的文章,下面列出有出入的地方
自定义任务名字的话,在后续创建脚本的步骤中把监控文件代码中的blog,改成你的任务名称。
1 2
| # 监控的文件 JENKINS_FILE="/root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar"
|
- 启用github插件,github plugin虽然默认安装了,但是并没有启用。需要取消启用github-branch这个插件,再开启github plugin。这两个插件只能启用一个,所以需要取消一个。
1 2
| rm -rf hexo.tar tar -zcvf hexo.tar ./*
|
脚本的意思是,jenkins从github拉取更新的代码后,先把jenkins容器/var/jenkins_home/workspace/blog/hexo.tar 文件先给删除,然后再打包jenkins容器/var/jenkins_home/workspace/blog目录下的所有文件到hexo.tar文件。把文件打包成hexo.tar方便后续传输到nginx。
注意:构建步骤这里添加的执行shell本质是在jenkins容器的/var/jenkins_home/workspace/blog目录下执行的操作。所以在这里写脚本传输jenkins容器文件到nginx容器是没可能的。下面会给出本地脚本来进行容器间文件的传输。
建议文章的图会和安装的有出入,但细心点是可以按他的步骤设置好的。
启用脚本
脚本功能:每隔10秒监测jenkins构建的输出目录workspace下hexo.tar是否更新,有更新就会执行先删除目标目录hexo文件夹下的所有文件,然后解压hexo.tar到目标目录,无更新不执行。
1 2
| cd /root/data/shell_script touch monitor_jenkins_to_nginx.sh
|
复制代码到monitor_jenkins_to_nginx.sh文件,然后执行以下命令
1
| ./monitor_jenkins_to_nginx.sh
|
monitor_jenkins_to_nginx.sh脚本代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| #!/bin/bash
# 配置参数 readonly JENKINS_FILE="/root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar" readonly NGINX_DEST_DIR="/root/data/docker_data/jenkins/html/dev/hexo" readonly INTERVAL=10 readonly LOG_FILE="/root/data/shell_script/monitor_jenkins_to_nginx/monitor_jenkins_to_nginx.log" readonly STOP_FILE="/root/data/shell_script/monitor_jenkins_to_nginx/stop_monitor_script" readonly MAX_LOG_SIZE=$((20 * 1024 * 1024)) # 20 MB readonly PROTECTED_DIRS=("nav" "qrc" "fyh" "bbd" "finalshell")
# 日志函数 log_message() { local timestamp timestamp=$(date '+%Y-%m-%d %H:%M:%S') echo "$timestamp $1" >> "$LOG_FILE" }
# 获取文件的最后修改时间 get_file_mod_time() { [ -f "$JENKINS_FILE" ] && stat -c %Y "$JENKINS_FILE" || echo 0 }
# 检查并控制日志文件大小 check_log_size() { if [ -f "$LOG_FILE" ] && [ "$(stat -c%s "$LOG_FILE")" -gt "$MAX_LOG_SIZE" ]; then log_message "日志文件超过 $MAX_LOG_SIZE 字节,正在删除..." : > "$LOG_FILE" log_message "日志文件已被重置。" fi }
# 判断文件是否稳定 is_file_stable() { local initial_size current_size initial_size=$(stat -c%s "$JENKINS_FILE") sleep 2 current_size=$(stat -c%s "$JENKINS_FILE") [ "$initial_size" -eq "$current_size" ] }
# 处理文件变化 handle_file_change() { log_message "检测到 $JENKINS_FILE 文件变化,正在处理..." # 创建目标目录 if ! mkdir -p "$NGINX_DEST_DIR"; then log_message "创建目标目录 $NGINX_DEST_DIR 失败。" return 1 fi # 构建排除目录的 find 命令参数 local exclude_args=() for dir in "${PROTECTED_DIRS[@]}"; do exclude_args+=(-not -name "$dir") done # 清理目标目录 if find "$NGINX_DEST_DIR" -mindepth 1 -maxdepth 1 "${exclude_args[@]}" -exec rm -rf {} + ; then log_message "已成功删除 $NGINX_DEST_DIR 目录中的无关文件。" # 检查文件稳定性并解压 if is_file_stable; then log_message "文件 $JENKINS_FILE 已经稳定,准备解压..." if tar -tf "$JENKINS_FILE" > /dev/null 2>&1; then if tar -xf "$JENKINS_FILE" -C "$NGINX_DEST_DIR"; then log_message "文件已成功解压到 $NGINX_DEST_DIR" else log_message "解压文件失败,请检查路径是否正确。" fi else log_message "文件 $JENKINS_FILE 可能已损坏,无法解压。" fi else log_message "文件 $JENKINS_FILE 仍在变化,稍后再试。" fi else log_message "删除 $NGINX_DEST_DIR 目录中的文件失败,请检查路径。" fi }
# 主监控循环 main_loop() { local last_mod_time current_mod_time last_mod_time=$(get_file_mod_time) while true; do [ -f "$STOP_FILE" ] && { log_message "检测到停止标志文件,脚本退出。" rm -f "$STOP_FILE" exit 0 }
current_mod_time=$(get_file_mod_time) [ "$current_mod_time" -gt "$last_mod_time" ] && { handle_file_change last_mod_time="$current_mod_time" }
check_log_size sleep "$INTERVAL" done }
# 创建日志目录 mkdir -p "$(dirname "$LOG_FILE")"
# 启动脚本 if [ "$1" != "start" ]; then echo "正在启动脚本,并在后台运行..." nohup "$0" start > "$LOG_FILE" 2>&1 & echo "脚本已在后台启动,日志输出到 $LOG_FILE" exit 0 fi
main_loop
|
日志记录
1 2 3 4
| 2024-11-27 11:09:13 检测到 /root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar 文件变化,正在处理... 2024-11-27 11:09:13 已成功删除 /root/data/docker_data/jenkins/html/dev/hexo 目录中的无关文件。 2024-11-27 11:09:15 文件 /root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar 已经稳定,准备解压... 2024-11-27 11:09:15 文件已成功解压到 /root/data/docker_data/jenkins/html/dev/hexo
|
停止运行脚本
1 2
| cd /root/data/shell_script/monitor_jenkins_to_nginx touch stop_monitor_script
|
查看脚本是否退出运行
1
| ps aux | grep monitor_jenkins_to_nginx.sh | grep -v grep
|
如果没有输出,则表示该脚本已经退出运行状态
脚本设置开机自启
方法 1: 使用 crontab
设置开机自启
将脚本添加到 crontab
中,以便在系统启动时自动运行。
1.安装 cron
使用 apt
包管理器来安装 cron
,通常在 Debian/Ubuntu 系统上可以执行以下命令:
1 2
| sudo apt update sudo apt install cron
|
2.启动并启用 cron
服务
安装完成后,启动 cron
服务并设置其开机自启:
1 2
| sudo systemctl start cron sudo systemctl enable cron
|
3.编辑 crontab
文件:
4.在 crontab
中添加以下行,设置开机启动脚本:
1
| @reboot /bin/bash /root/data/shell_script/monitor_jenkins_to_nginx.sh start
|
这行命令会在系统启动时自动执行脚本。
5.保存并退出编辑器。
方法 2: 使用 systemd
设置开机自启
创建一个新的 systemd
服务文件,例如 monitor_jenkins_to_nginx.service
:
1
| sudo nano /etc/systemd/system/monitor_jenkins_to_nginx.service
|
在服务文件中添加以下内容:
1 2 3 4 5 6 7 8 9 10 11
| [Unit] Description=Monitor Jenkins to Nginx Script After=network.target
[Service] Type=simple ExecStart=/bin/bash /root/data/shell_script/monitor_jenkins_to_nginx.sh start Restart=on-failure
[Install] WantedBy=multi-user.target
|
这将使脚本在系统启动后运行,并确保网络启动完成后才运行该脚本。
保存文件并退出编辑器。
重新加载 systemd
配置:
1
| sudo systemctl daemon-reload
|
启动服务并设置为开机启动:
1
| sudo systemctl start monitor_jenkins_to_nginx.service
|
1
| sudo systemctl enable monitor_jenkins_to_nginx.service
|
6.查看脚本运行状态
1
| sudo systemctl status monitor_jenkins_to_nginx.service
|
参考资料
从零开始搭建JENKINS+GITHUB持续集成环境
Docker Compose安装部署Jenkins
Jenkins修改显示语言为中文显示(亲测有效)_jenkins 中文-CSDN博客
Jenkins配置任务时无 send files execute commands over SSH
Docker + Jenkins + Nginx实现前端自动化部署