前言
本文介绍使用docker+nginx+jenkins将hexo博客部署至云服务器。
博客提交云服务器流程:
- 本地电脑hexo三连,或者githubaction三连部署到github。
- jenkins监测到github项目主页更新,拉取更新后的文件到vps的jenkins工作目录,然后持续集部署更新文件。Jenkins(概念篇):Jenkins 简介_ron jenkins 什么意思
- vps本地脚本把jenkins工作目录更新的文件传输到nginx工作目录。
准备工作
可以部署到githubpage的hexo博客;vps云服务器;
vps安装docker,docker-compose
安装git
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
| #!/bin/bash
# 监控的文件 JENKINS_FILE="/root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar"
# 解压目标目录 NGINX_DEST_DIR="/root/data/docker_data/jenkins/html/dev/hexo"
# 监控间隔时间(秒) INTERVAL=10
# 日志文件路径 LOG_FILE="/root/data/shell_script/monitor_jenkins_to_nginx/monitor_jenkins_to_nginx.log"
# 停止标志文件 STOP_FILE="/root/data/shell_script/monitor_jenkins_to_nginx/stop_monitor_script"
# 最大日志文件大小(字节)20 MB MAX_LOG_SIZE=$((20 * 1024 * 1024))
# 创建日志目录(如果不存在) mkdir -p "$(dirname "$LOG_FILE")"
# 获取文件的最后修改时间 get_file_mod_time() { if [ -f "$JENKINS_FILE" ]; then stat -c %Y "$JENKINS_FILE" else echo 0 fi }
# 检查并控制日志文件大小 check_log_size() { if [ -f "$LOG_FILE" ]; then LOG_SIZE=$(stat -c%s "$LOG_FILE") if [ "$LOG_SIZE" -gt "$MAX_LOG_SIZE" ]; then echo "日志文件超过 $MAX_LOG_SIZE 字节,正在删除..." >> "$LOG_FILE" > "$LOG_FILE" echo "日志文件已被重置。" >> "$LOG_FILE" fi fi }
# 上一次的文件修改时间 LAST_MOD_TIME=$(get_file_mod_time)
# 后台执行脚本 if [ "$1" != "start" ]; then echo "正在启动脚本,并在后台运行..." nohup $0 start > "$LOG_FILE" 2>&1 & echo "脚本已在后台启动,日志输出到 $LOG_FILE" exit 0 fi
# 监控文件变化 while true; do # 检查是否存在停止标志文件 if [ -f "$STOP_FILE" ]; then echo "检测到停止标志文件,脚本退出。" >> "$LOG_FILE" rm -f "$STOP_FILE" exit 0 fi
CURRENT_MOD_TIME=$(get_file_mod_time) if [ "$CURRENT_MOD_TIME" -gt "$LAST_MOD_TIME" ]; then echo "检测到 $JENKINS_FILE 文件变化,正在处理..." >> "$LOG_FILE" # 确保目标目录存在 mkdir -p "$NGINX_DEST_DIR" # 删除目标目录中除 nav, qrc, fyh, bbd 目录外的所有文件 find "$NGINX_DEST_DIR" -mindepth 1 -maxdepth 1 ! -name 'nav' ! -name 'qrc' ! -name 'fyh' ! -name 'bbd' -exec rm -rf {} +
if [ $? -eq 0 ]; then echo "已成功删除 $NGINX_DEST_DIR 目录中的无关文件。" >> "$LOG_FILE" # 解压文件到目标目录 tar -xf "$JENKINS_FILE" -C "$NGINX_DEST_DIR" if [ $? -eq 0 ]; then echo "文件已成功解压到 $NGINX_DEST_DIR" >> "$LOG_FILE" else echo "解压文件失败,请检查路径是否正确。" >> "$LOG_FILE" fi else echo "删除 $NGINX_DEST_DIR 目录中的文件失败,请检查路径。" >> "$LOG_FILE" fi # 更新最后的修改时间 LAST_MOD_TIME="$CURRENT_MOD_TIME" fi
# 检查日志文件大小并控制 check_log_size
# 等待指定时间再进行下一次检查 sleep "$INTERVAL" done
|
日志记录
1 2 3
| 检测到 /root/data/docker_data/jenkins/jenkins_home/workspace/blog/hexo.tar 文件变化,正在处理... 已成功删除 /root/data/docker_data/jenkins/html/dev/hexo 目录中的所有文件。 文件已成功解压到 /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
中,以便在系统启动时自动运行。
- 安装
cron
使用 apt
包管理器来安装 cron
,通常在 Debian/Ubuntu 系统上可以执行以下命令:
1 2
| sudo apt update sudo apt install cron
|
- 启动并启用
cron
服务
安装完成后,启动 cron
服务并设置其开机自启:
1 2
| sudo systemctl start cron sudo systemctl enable cron
|
- 编辑
crontab
文件:
- 在
crontab
中添加以下行,设置开机启动脚本:
1
| @reboot /bin/bash /root/data/shell_script/monitor_jenkins_to_nginx.sh start
|
这行命令会在系统启动时自动执行脚本。
- 保存并退出编辑器。
方法 2: 使用 systemd
设置开机自启 (适用于现代 Linux 系统)
创建一个新的 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 2
| sudo systemctl start monitor_jenkins_to_nginx.service sudo systemctl enable monitor_jenkins_to_nginx.service
|
参考资料
从零开始搭建JENKINS+GITHUB持续集成环境
Docker Compose安装部署Jenkins
Jenkins修改显示语言为中文显示(亲测有效)_jenkins 中文-CSDN博客
Jenkins配置任务时无 send files execute commands over SSH
Docker + Jenkins + Nginx实现前端自动化部署