Gitlab Runner 学习
runner下载|安装|启动
下载
# 为您的系统下载二进制文件
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
# 授予执行权限
sudo chmod +x /usr/local/bin/gitlab-runner
# 创建 GitLab Runner 用户
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# 安装并作为服务运行
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
# 如果使用基于 `deb` 包的发行版(如 Ubuntu、Debian)
curl -s https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
apt install -y gitlab-runner
# 如果使用基于 `rpm` 包的发行版(如 CentOS、RHEL、Fedora)
curl -s https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
dnf install -y gitlab-runner
启动
gitlab-runner start
停止
gitlab-runner stop
注册runner
命令行创建
gitlab-runner register --url http://gitlab.local --token xxx
Gitlab页面创建
# 页面创建的 runner 仍然需要到 runner 服务器上执行一遍指令
删除runner
按名字删除
sudo gitlab-runner unregister --name "python-runner"
通过 URL 和令牌删除
sudo gitlab-runner unregister --url http://gitlab.local --token xxx
全部删除
sudo gitlab-runner unregister --all-runners
删除配置文件
rm -rf /xxx/xxx/.gitlab-runner/config.toml
测试.gitlab-ci.yml
# GitLab CI/CD 配置文件 - 简化版本
# 这个文件定义了GitLab的持续集成/持续部署流程
# 定义流水线的阶段(stages)
# 每个作业(job)必须属于一个阶段,阶段按顺序执行
stages:
- test # 测试阶段:运行各种测试
- deploy # 部署阶段:部署应用到不同环境
# 全局变量定义
# 这些变量可以在所有作业中使用
variables:
FLASK_ENV: testing # Flask应用环境(testing/production)
VENV_PATH: venv # Python虚拟环境路径
PYTHON_VERSION: 3.11 # 使用的Python版本
UWSGI_PORT: 8099 # uWSGI服务监听的端口
HEALTH_CHECK_ENDPOINT: /api/v1/health/ # 健康检查接口路径
WAIT_TIMEOUT: 30 # 应用启动等待超时时间(秒)
# 缓存配置
# 缓存可以加速后续流水线的执行
cache:
key: $CI_COMMIT_REF_SLUG # 缓存键,基于分支名称
paths:
- venv/ # 缓存Python虚拟环境
- .cache/pip # 缓存pip下载的包
# 单元测试作业
# 这个作业运行Python单元测试
unit_tests:
stage: test # 属于test阶段
tags:
- myDebainTest # 指定运行器标签(GitLab Runner的标签)
before_script: # 作业执行前的准备工作
- echo "🚀 开始设置Python环境..."
- python${PYTHON_VERSION} --version # 检查Python版本
- python${PYTHON_VERSION} -m venv $VENV_PATH || python3 -m venv $VENV_PATH # 创建虚拟环境
- source $VENV_PATH/bin/activate # 激活虚拟环境
- pip install --upgrade pip # 升级pip
- pip install -r requirements.txt # 安装依赖包
- echo "当前FLASK_ENV:" $FLASK_ENV # 显示当前环境变量
- export FLASK_ENV="$FLASK_ENV" # 设置环境变量
script: # 作业的主要执行脚本
- echo "🧪 运行单元测试..."
- echo "当前FLASK_ENV:" $FLASK_ENV
- python -c "import os; print('Python进程中的FLASK_ENV:', os.getenv('FLASK_ENV'))" # 验证环境变量
- python -m pytest test/ -v --tb=short || echo "⚠️ 没有找到测试文件或测试失败" # 运行pytest测试
after_script: # 作业执行后的清理工作
- echo "🧹 清理环境..."
- pkill -9 uwsgi || true # 强制停止uWSGI进程
- deactivate || true # 退出虚拟环境
artifacts: # 制品(构建产物)配置
when: always # 总是上传制品(无论成功或失败)
reports:
junit: test-results.xml # JUnit格式的测试报告
paths:
- test-results.xml # 测试报告文件路径
expire_in: 1 week # 制品保留时间
only: # 触发条件:只在以下分支/事件触发
- main
- develop
- merge_requests
# 健康检查测试作业
# 这个作业测试应用的健康检查接口
health_check_test:
stage: test
tags:
- myDebainTest
before_script:
- echo "🚀 开始设置Python环境..."
- python${PYTHON_VERSION} --version
- python${PYTHON_VERSION} -m venv $VENV_PATH || python3 -m venv $VENV_PATH
- source $VENV_PATH/bin/activate
- pip install --upgrade pip
- pip install -r requirements.txt
- echo "当前FLASK_ENV:" $FLASK_ENV
- export FLASK_ENV="$FLASK_ENV"
script:
- echo "🔍 启动Flask应用并测试健康检查接口..."
- echo "当前FLASK_ENV:" $FLASK_ENV
- python -c "import os; print('Python进程中的FLASK_ENV:', os.getenv('FLASK_ENV'))"
- pkill -9 uwsgi || true # 确保没有残留的uWSGI进程
- uwsgi --ini uwsgi.ini --daemonize api.log --env FLASK_ENV="$FLASK_ENV" # 后台启动uWSGI
- |
echo ⏳ 等待应用启动...
# 循环检查应用是否启动成功
for i in {1..$WAIT_TIMEOUT}; do
if curl -s -f http://127.0.0.1:$UWSGI_PORT$HEALTH_CHECK_ENDPOINT > /dev/null 2>&1; then
echo ✅ 应用在第 $i 秒启动成功
break
fi
sleep 1
if [ $i -eq $WAIT_TIMEOUT ]; then
echo ❌ 应用启动超时
cat api.log # 输出应用日志用于调试
exit 1 # 退出并标记作业失败
fi
done
- |
echo 📊 执行健康检查...
# 使用更简单的方法获取HTTP状态码
status_code=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:$UWSGI_PORT$HEALTH_CHECK_ENDPOINT)
body=$(curl -s http://127.0.0.1:$UWSGI_PORT$HEALTH_CHECK_ENDPOINT)
echo HTTP状态码: $status_code
echo 响应内容: $body
# 检查健康检查接口是否返回200状态码
if [ $status_code -eq 200 ]; then
echo ✅ 健康检查接口测试成功
else
echo ❌ 健康检查接口测试失败
cat api.log # 输出应用日志用于调试
exit 1 # 退出并标记作业失败
fi
after_script:
- echo "🧹 清理环境..."
- pkill -9 uwsgi || true
- deactivate || true
- echo "📋 应用日志:"
- tail -50 api.log || echo "没有找到日志文件" # 输出最后50行应用日志
artifacts:
when: on_failure # 只在作业失败时上传制品
paths:
- api.log # 上传应用日志文件
expire_in: 1 hour # 制品保留时间较短(仅用于调试)
only:
- main
- develop
- merge_requests
# 代码质量检查作业
# 这个作业检查代码质量和应用配置
code_quality:
stage: test
tags:
- myDebainTest
before_script:
- echo "🚀 开始设置Python环境..."
- python${PYTHON_VERSION} --version
- python${PYTHON_VERSION} -m venv $VENV_PATH || python3 -m venv $VENV_PATH
- source $VENV_PATH/bin/activate
- pip install --upgrade pip
- pip install -r requirements.txt
- echo "当前FLASK_ENV:" $FLASK_ENV
- export FLASK_ENV="$FLASK_ENV"
script:
- echo "🔍 代码质量检查..."
- echo "当前FLASK_ENV:" $FLASK_ENV
- pip install flake8 black || true # 安装代码检查工具
- flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics || echo "⚠️ flake8检查失败或未安装" # 代码风格检查
- python -c "import os; print('Python进程中的FLASK_ENV:', os.getenv('FLASK_ENV')); from manage import create_app; app = create_app(); print('加载的配置文件:', app.config.get('SQLALCHEMY_DATABASE_URI', '未找到'))" || echo "⚠️ 应用创建失败" # 测试应用配置加载
only:
- main
- develop
# 测试环境部署作业
# 这个作业将应用部署到测试环境
deploy_staging:
stage: deploy
tags:
- myDebainTest
script:
- echo "🚀 部署到测试环境..."
- echo "部署逻辑待实现" # 实际部署逻辑需要根据具体环境实现
environment: # 环境配置
name: staging # 环境名称
url: https://staging.example.com # 环境URL
only:
- main # 只在main分支触发
# 生产环境部署作业
# 这个作业将应用部署到生产环境
deploy_production:
stage: deploy
tags:
- myDebainTest
script:
- echo "🚀 部署到生产环境..."
- echo "部署逻辑待实现" # 实际部署逻辑需要根据具体环境实现
environment:
name: production # 环境名称
url: https://production.example.com # 环境URL
only:
- main # 只在main分支触发
when: manual # 手动触发(需要人工确认)