如何实现完整CICD部署Docker镜像到腾讯云服务器?#2222
prompt:“请帮我生成一个.cnb.yml 文件,可以实现将 代码构建成docker 制品并推送到腾讯云镜像服务”
`stages:
services:
`
prompt:“请帮我生成一个.cnb.yml 文件,可以实现将 代码构建成docker 制品并推送到腾讯云镜像服务”
`stages:
阶段1:构建Docker镜像(关键阶段~)
- name: docker build
services:
- docker # 启用docker服务
docker:
build:
dockerfile: Dockerfile # 假设你的Dockerfile在项目根目录~
by:
- nginx.conf # 如果有需要的话,可以添加构建参数(参考之前的讨论~)
script:- echo "✨ 开始构建Docker镜像..."
- docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${CNB_COMMIT} . # 打标签+构建命令~
阶段2:登录腾讯云镜像仓库(推送前必须~)
- name: docker login
services:
- docker
script:- echo "🔑 登录腾讯云镜像仓库..."
- docker login -u ${CNB_TOKEN_USER_NAME} -p "${CNB_TOKEN}" ${CNB_DOCKER_REGISTRY} # 用上下文里的变量自动填充凭证~
阶段3:推送镜像到仓库(核心操作~)
- name: docker push
services:
- docker
script:- echo "🚀 推送Docker镜像到仓库..."
- docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:${CNB_COMMIT} # 推送最新提交的镜像~
阶段4:清理旧镜像标签(可选但推荐~只保留最新~)
- name: remove old docker tags
type: artifact:remove-tag # 使用制品清理功能
options:
name: ${CNB_REPO_SLUG_LOWERCASE} # 仓库名
tags:
- ${CNB_COMMIT} # 保留当前提交的标签,其他旧标签会被清理~
type: docker # 指定清理类型为docker镜像services:
- docker # 全局启用docker服务~
`
非常感谢!我想补充下,我想的是Git Push以后触发云构建,上传制品到cnb docker制品仓库,然后同步腾讯云服务器(或轻量云服务器)下载对应镜像并进行down和up -d操作进行替换。
以下两个示例结合着用可以实现:
https://cnb.cool/examples/ecosystem/react-docker
https://cnb.cool/examples/ecosystem/react-ssh-demo
晚点我们出一个示例好一些
以下两个示例结合着用可以实现:
https://cnb.cool/examples/ecosystem/react-docker
https://cnb.cool/examples/ecosystem/react-ssh-demo晚点我们出一个示例好一些
@youkun(哪都通在逃临时工) 非常感谢!!毕竟是自家产品,有个CNB流水线推送到腾讯云服务器的Demo 会方便更多人参考
已经更新最佳实践和相关仓库哈
examples/showcase#144
https://cnb.cool/examples/ecosystem/react-docker
@youkun(哪都通在逃临时工) Good!! 极其高效!感谢大佬!
已经更新最佳实践和相关仓库哈
examples/showcase#144
https://cnb.cool/examples/ecosystem/react-docker
@youkun(哪都通在逃临时工) Sorry 还有个问题,如何在cnb中使用dockerFile部署?部署后推送Dockerfile制品(后续一样)
例如我之前阿里云的DockerFile如下:
`FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build
-ldflags="-w -s"
-trimpath
-o XXXX ./cmd/client
FROM alpine:latest
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY --from=builder /app/XXXX .
RUN apk add curl tzdata ca-certificates dumb-init
RUN chmod +x ./XXXX &&
curl -L -o ./GeoLite2-City.mmdb https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb
VOLUME ["/app/logs"]
EXPOSE 8877
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["./XXXX"]`
在.cnb.yml应该如何编写呢...
@youkun(哪都通在逃临时工) Sorry 还有个问题,如何在cnb中使用dockerFile部署?部署后推送Dockerfile制品(后续一样)
@atsauce(Artisan) 你好
首先,Dockerfile 本身不是部署描述文件,是构建描述文件,在流水线里 docker build -f Dockerfile 后得到一个容器产物,你要部署得依赖这个产物
然后,流水线的产物你需要先持久化下来到 cnb ,也就是 docker push,后续再通过其他方式触发部署机器去拉取这个产物,当然你可以参考前面说的,在流水线中使用ssh连接到服务器,自动化拉取,但是这个过程由于产物没有持久化下来,没有办法重复部署,即使相同构建要素也没法保证产物一致。
过程和 https://cnb.cool/examples/ecosystem/react-docker/-/blob/main/.cnb.yml 里是一样的,docker build 时加上 -f 指定 Dockerfile 地址即可。
@atsauce(Artisan) 你好
首先,Dockerfile 本身不是部署描述文件,是构建描述文件,在流水线里 docker build -f Dockerfile 后得到一个容器产物,你要部署得依赖这个产物
然后,流水线的产物你需要先持久化下来到 cnb ,也就是 docker push,后续再通过其他方式触发部署机器去拉取这个产物,当然你可以参考前面说的,在流水线中使用ssh连接到服务器,自动化拉取,但是这个过程由于产物没有持久化下来,没有办法重复部署,即使相同构建要素也没法保证产物一致。过程和 https://cnb.cool/examples/ecosystem/react-docker/-/blob/main/.cnb.yml 里是一样的,docker build 时加上 -f 指定 Dockerfile 地址即可。
@anthonywan(Anthonywan) 学会(fei)了 谢谢。
希望能够完善Demo,更加多样化。
同时希望加入go mod 下载加速或香港等海外构建节点,build了59分钟,使用阿里云flow才3分钟....
是否方便提供下仓库地址,这个可能和网络因为有关,因为我不知道你的 dockerfile 里在干啥,不太能给出准确答复
但是你可以告知下你里面下载了哪些组件,如果没有敏感信息的话,将 log 下载贴上来也可以,合理的域名我们评估下可以提供加速
是在下载这个? https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb
是否方便提供下仓库地址,这个可能和网络因为有关,因为我不知道你的 dockerfile 里在干啥,不太能给出准确答复
但是你可以告知下你里面下载了哪些组件,如果没有敏感信息的话,将 log 下载贴上来也可以,合理的域名我们评估下可以提供加速
是在下载这个? https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb
@anthonywan(Anthonywan) 可能是的... 我贴出我的cnb.yml和Dockerfile脱敏配置
`.pipeline-template: &api_web_pipeline_body
docker:
image: docker:cli
services:
- docker
imports:
- https://cnb.cool/xxx/Common/-/blob/main/xxxxxx.yml
env:
CLIENT_DOCKERFILE: cmd/client/Dockerfile
WEB_DOCKERFILE: cmd/web/Dockerfile
CLIENT_IMAGE: $CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG_LOWERCASE/xxx-service-client
WEB_IMAGE: $CNB_DOCKER_REGISTRY/$CNB_REPO_SLUG_LOWERCASE/xxx-service-web
CLIENT_PORT: 8877
WEB_PORT: 8878
LOG_DIR: /data/xxx/logs
stages:
- name: Login Registry
script:
- docker login ${CNB_DOCKER_REGISTRY} -u ${CNB_TOKEN_USER_NAME} -p "${CNB_TOKEN}"
- name: Build Client Image
script:
- docker build -f ${CLIENT_DOCKERFILE} -t ${CLIENT_IMAGE}:latest .
- name: Push Client Image
script:
- docker push ${CLIENT_IMAGE}:latest
- name: Build Web Image
script:
- docker build -f ${WEB_DOCKERFILE} -t ${WEB_IMAGE}:latest .
- name: Push Web Image
script:
- docker push ${WEB_IMAGE}:latest
- name: Deploy Client Service
image: tencentcom/ssh
settings:
host: $API_REMOTE_HOST
port: $REMOTE_PORT
username: $REMOTE_USERNAME
key: $REMOTE_PRIVATE_KEY
script:
- |
set -e
sudo su - <<EOF
set -e
docker login ${CNB_DOCKER_REGISTRY} -u ${CNB_TOKEN_USER_NAME} -p "${CNB_TOKEN}"
docker pull ${CLIENT_IMAGE}:latest
docker stop xxx-service-client || true
docker rm xxx-service-client || true
mkdir -p ${LOG_DIR}
docker run -d --name xxx-service-client \
-v ${LOG_DIR}:/app/logs \
-p ${CLIENT_PORT}:${CLIENT_PORT} \
--restart=unless-stopped \
--health-cmd="curl -f http://localhost:${CLIENT_PORT}/live || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
--health-start-period=60s \
${CLIENT_IMAGE}:latest
docker ps --filter "name=xxx-service-client"
EOF
- name: Deploy Web Service
image: tencentcom/ssh
settings:
host: $API_REMOTE_HOST
port: $REMOTE_PORT
username: $REMOTE_USERNAME
key: $REMOTE_PRIVATE_KEY
script:
- |
set -e
sudo su - <<EOF
set -e
docker login ${CNB_DOCKER_REGISTRY} -u ${CNB_TOKEN_USER_NAME} -p "${CNB_TOKEN}"
docker pull ${WEB_IMAGE}:latest
docker stop xxx-service-web || true
docker rm xxx-service-web || true
mkdir -p ${LOG_DIR}
docker run -d --name xxx-service-web \
-v ${LOG_DIR}:/app/logs \
-p ${WEB_PORT}:${WEB_PORT} \
--restart=unless-stopped \
--health-cmd="curl -f http://localhost:${WEB_PORT}/live || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
--health-start-period=60s \
${WEB_IMAGE}:latest
docker ps --filter "name=xxx-service-web"
EOF
master:
push:
- name: api-web-build-and-deploy
<<: *api_web_pipeline_body
pull_request:
- name: api-web-build-and-deploy
<<: *api_web_pipeline_body`
DockerFile:
`# STEP 1: Build service
FROM golang:latest as builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build
-ldflags="-w -s"
-trimpath
-o xxx ./cmd/client
FROM alpine:latest
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY --from=builder /app/xxx .
RUN apk add curl tzdata ca-certificates dumb-init
RUN chmod +x ./xxx &&
curl -L -o ./GeoLite2-City.mmdb https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb
VOLUME ["/app/logs"]
EXPOSE 8877
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["./xxxx"]`
go mod 不知道有没有加速...
goproxy 有加速的,确认就是下载 GeoLite2-City.mmdb 撞墙了,正常都要MB/s起,但是你截图里就K/s的速度,但是 github.com 是有加速的,我们确认下这个问题
goproxy 有加速的,确认就是下载 GeoLite2-City.mmdb 撞墙了,正常都要MB/s起,但是你截图里就K/s的速度,但是 github.com 是有加速的,我们确认下这个问题
@anthonywan(Anthonywan) OK TKS
这个特性将解决什么问题?
从Codeup迁移过来, 功能很多, 也很有前途.
但是例如 Push、Build、推送到CNB Docker仓库以后, 如何使用插件等方式流水化在对应的腾讯云服务器拉取和更新镜像服务?
如果这一步做不到, 自家生态就真的一点也不完整...
再例如传统SSH插件方式手动敲命令, 那么这个流水线就真的很麻烦了...
设想的解决方案?如有