
🚀 利用 OneDev + Portainer 实现丝滑的 CI/CD 部署流程
在现代 DevOps 流程中,实现从代码提交到服务上线的自动化部署已经成为一种标准操作。而我们今天要介绍的是如何使用 OneDev 配合 Portainer 打造一个轻量、中文友好、丝滑的 CI/CD 工作流。
OneDev 自带中文界面、支持 Git 仓库和 CI/CD 管道,而且内置 Docker Registry,几乎可以零门槛搭建自己的 DevOps 平台。结合 Portainer 强大的 Docker Stack 管理能力,我们可以轻松实现如下流程:
Git 推送代码 → OneDev 构建镜像 → 推送至本地 Registry → 调用 Portainer API 更新部署
📦 准备工作
1. 在 Git 项目根目录中添加以下两个文件:
Dockerfile:用于构建应用镜像
# 以 Node.js 为例
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install && npm run build
CMD ["npm", "start"]
docker-compose.yml:用于部署 Stack 到 Portainer
version: '3.8'
services:
app:
image: localhost:5000/my-app:latest
restart: always
ports:
- "8080:3000"
🛠 配置 OneDev 的构建工作流
步骤一:创建 CD 工作流
打开 OneDev 项目,点击左侧「代码」菜单,代码顶部有"通过 添加 .onedev-buildspec.yml 启用构建支持", 点击"添加"
Checkout Code
Docker Image / Build Image
Execute Commands
容器可以选择urlimages/curl:latest
用来CURL请求API.
命令行中添加安装jq来方便处理json字符串
apk add --no-cache jq
部署:
设置要部署到portainer的stack_name. endpointdId
portainer_url为portainer的域名
@secret:portainer_token@ 中的"portainer_token"为构建设置的变量名称
stack_name="test"
endpoint=5
portainer_url="https://test.uqoo.cc"
# 安装 jq(仅 Alpine 可用)
apk add --no-cache jq
# 获取 stack_id
get_stack_id() {
curl -s -H "X-API-KEY: @secret:portainer_token@" "${portainer_url}/api/stacks" |
jq ".[] | select(.Name==\"${stack_name}\") | .Id"
}
# 更新 stack
update_stack() {
local local_stack_id=$1
echo "update stack: ${local_stack_id}"
# 将 compose 文件转为 JSON 字符串
content=$(jq -Rs . < docker-compose.yml)
# 构造 JSON 并发送
curl -X PUT -H "Content-Type: application/json" \
-H "X-API-KEY: @secret:portainer_token@" \
-d '{"prune": true, "pullImage": true, "stackFileContent": '"${content}"'}' \
"${portainer_url}/api/stacks/${local_stack_id}?endpointId=${endpoint}"
}
# 创建 stack
create_stack() {
curl -X POST "${portainer_url}/api/stacks/create/standalone/file?endpointId=${endpoint}" \
-H "X-API-KEY: @secret:portainer_token@" \
-F "Name=${stack_name}" \
-F "file=@@docker-compose.yml"
}
# 判断是否存在 stack
stack_id=$(get_stack_id)
if [ -n "$stack_id" ]; then
echo "update stack."
update_stack "$stack_id"
else
echo "create new stack."
create_stack
fi
步骤二:设置变量(建议使用 OneDev 的 Secret 功能)
PORTAINER_TOKEN
:Portainer API 的访问令牌DOCKER_REGISTRY
:默认是localhost:5000
,你也可以指定其他私有 Registry 地址
📡 配置 Portainer
登录 Portainer 后台
确保已开启 API 功能(启用认证)
创建
Access Token
,用于 OneDev 调用
✅ 整体流程图
开发者提交代码
↓
OneDev Git 仓库
↓
OneDev CD 工作流触发
↓
构建镜像 + 推送到本地 Registry
↓
调用 Portainer API 更新 Stack
↓
应用服务丝滑上线 ✨
🎯 总结
使用 OneDev + Portainer,可以不依赖 GitHub Actions、Jenkins、Harbor 等复杂平台,在本地就能搭建出一个完整、高效、中文友好的 CI/CD 环境。尤其适合中小团队或内网部署需求。
因时间有限省略了比较简单CI流程,仅描述难度较高的CD
portainer api的官方网站. 当前文章所使用的api的版本为2.27.6