feat: 删除.drone.yml && 采用build.sh手动构建镜像

This commit is contained in:
2025-12-17 12:27:20 +08:00
parent b7726e5aa0
commit a1552008de
6 changed files with 110 additions and 133 deletions

View File

@@ -1,73 +0,0 @@
kind: pipeline
type: docker
name: build-by-tag
node:
name: pve
trigger:
event:
- tag
ref:
- refs/tags/v*
steps:
- name: build-and-push-normal
image: plugins/docker
settings:
registry: harbor.seahi.me
repo: harbor.seahi.me/stu/versions-for-swarm
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true
tags:
- ${DRONE_TAG}
build_args:
- APP_VERSION=${DRONE_TAG}
auto_tag: false
when:
ref:
exclude:
- refs/tags/*buggy*
- name: build-and-push-buggy
image: plugins/docker
settings:
registry: harbor.seahi.me
repo: harbor.seahi.me/stu/versions-for-swarm
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true
tags:
- ${DRONE_TAG}
build_args:
- APP_VERSION=${DRONE_TAG}
- BUGGY=true
auto_tag: false
when:
ref:
include:
- refs/tags/*buggy*
- name: tag-latest-if-v2.1
image: plugins/docker
settings:
registry: harbor.seahi.me
repo: harbor.seahi.me/stu/versions-for-swarm
username:
from_secret: harbor_username
password:
from_secret: harbor_password
insecure: true
tags:
- latest
build_args:
- APP_VERSION=${DRONE_TAG}
auto_tag: false
when:
ref:
- refs/tags/v2.1

View File

@@ -16,17 +16,15 @@ ENV TZ=Asia/Shanghai \
WORKDIR /app WORKDIR /app
RUN pip install flask COPY requirements.txt .
# COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
# RUN pip install --no-cache-dir -r requirements.txt
COPY app.py . COPY app.py .
EXPOSE 80 EXPOSE 80
# 添加健康检查v2.0+ 特性) # 添加健康检查v2.0+ 特性)
# 注意v1.0 版本没有 /health 端点,不应添加健康检查 HEALTHCHECK --interval=10s --timeout=3s --start-period=30s --retries=3 \
# HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \ CMD wget -q --spider http://127.0.0.1:80/health 2>&1 || exit 1
# CMD wget --no-verbose --tries=1 --spider http://localhost/health || exit 1
CMD ["python", "app.py"] CMD ["python", "app.py"]

View File

@@ -29,9 +29,32 @@
```bash ```bash
docker service create \ docker service create \
--replicas 3 \ --replicas 3 \
--name demo-app \ --name s00 \
--publish 9000:80 \ --publish 9000:80 \
--env STUDENT_ID=00 \ --env STUDENT_ID=00 \
--update-delay 10s \
--update-parallelism 1 \
harbor.seahi.me/stu/versions-for-swarm:v1.0 harbor.seahi.me/stu/versions-for-swarm:v1.0
```
### 2⃣ 部署后续版本 (v2.0)
```bash
docker service update \
--image harbor.seahi.me/stu/versions-for-swarm:v2.0 \
s00
```
### 3⃣ 部署稳定版本 (v2.1)
```bash
docker service update \
--image harbor.seahi.me/stu/versions-for-swarm:v2.1 \
s00
```
### 4⃣ 部署故障版本 (v3.0-buggy)
```bash
docker service update \
--image harbor.seahi.me/stu/versions-for-swarm:v3.0-buggy \
s00
```

81
app.py
View File

@@ -1,30 +1,40 @@
from flask import Flask, jsonify
import socket
import os import os
from datetime import datetime
import random import random
import socket
from datetime import datetime
from flask import Flask, jsonify
app = Flask(__name__) app = Flask(__name__)
# 从环境变量读取版本号 # 从环境变量读取版本号
VERSION = os.getenv('APP_VERSION', 'v1.0') VERSION = os.getenv("APP_VERSION", "v1.0")
BUGGY = os.getenv('BUGGY', 'false').lower() == 'true' BUGGY = os.getenv("BUGGY", "false").lower() == "true"
# 版本主题配置 # 版本主题配置
THEMES = { THEMES = {
'v1.0': {'color': '#4A90E2', 'name': '蓝色经典版', 'features': '基础功能'}, "v1.0": {"color": "#4A90E2", "name": "蓝色经典版", "features": "基础功能"},
'v2.0': {'color': '#50C878', 'name': '绿色升级版', 'features': '新增健康检查、API接口'}, "v2.0": {
'v2.1': {'color': '#50C878', 'name': '绿色稳定版', 'features': '性能优化、Bug修复'}, "color": "#50C878",
'v3.0-buggy': {'color': '#E74C3C', 'name': '红色测试版', 'features': '⚠️ 此版本存在已知问题'} "name": "绿色升级版",
"features": "新增健康检查、API接口",
},
"v2.1": {"color": "#50C878", "name": "绿色稳定版", "features": "性能优化、Bug修复"},
"v3.0-buggy": {
"color": "#E74C3C",
"name": "红色测试版",
"features": "⚠️ 此版本存在已知问题",
},
} }
@app.route('/')
@app.route("/")
def hello(): def hello():
# 模拟 v3.0-buggy 的问题 # 模拟 v3.0-buggy 的问题
if BUGGY and random.random() < 0.5: if BUGGY and random.random() < 0.5:
return "💥 服务异常:数据库连接失败", 500 return "💥 服务异常:数据库连接失败", 500
theme = THEMES.get(VERSION, THEMES['v1.0']) theme = THEMES.get(VERSION, THEMES["v1.0"])
return f""" return f"""
<!DOCTYPE html> <!DOCTYPE html>
@@ -39,10 +49,10 @@ def hello():
max-width: 700px; max-width: 700px;
margin: 50px auto; margin: 50px auto;
padding: 30px; padding: 30px;
background: linear-gradient(135deg, {theme['color']}22 0%, {theme['color']}44 100%); background: linear-gradient(135deg, {theme["color"]}22 0%, {theme["color"]}44 100%);
}} }}
.header {{ .header {{
background: {theme['color']}; background: {theme["color"]};
color: white; color: white;
padding: 20px; padding: 20px;
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
@@ -55,13 +65,13 @@ def hello():
box-shadow: 0 4px 6px rgba(0,0,0,0.1); box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}} }}
.highlight {{ .highlight {{
color: {theme['color']}; color: {theme["color"]};
font-weight: bold; font-weight: bold;
font-size: 1.2em; font-size: 1.2em;
}} }}
.version-badge {{ .version-badge {{
display: inline-block; display: inline-block;
background: {theme['color']}; background: {theme["color"]};
color: white; color: white;
padding: 5px 15px; padding: 5px 15px;
border-radius: 20px; border-radius: 20px;
@@ -91,7 +101,7 @@ def hello():
</head> </head>
<body> <body>
<div class="header"> <div class="header">
<h1>🚀 {theme['name']}</h1> <h1>🚀 {theme["name"]}</h1>
<div class="version-badge">版本 {VERSION}</div> <div class="version-badge">版本 {VERSION}</div>
</div> </div>
<div class="info"> <div class="info">
@@ -102,15 +112,15 @@ def hello():
</tr> </tr>
<tr> <tr>
<td>🎓 学号服务</td> <td>🎓 学号服务</td>
<td class="highlight">s{os.getenv('STUDENT_ID', '00')}</td> <td class="highlight">s{os.getenv("STUDENT_ID", "00")}</td>
</tr> </tr>
<tr> <tr>
<td>⏰ 当前时间</td> <td>⏰ 当前时间</td>
<td class="highlight">{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</td> <td class="highlight">{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}</td>
</tr> </tr>
<tr> <tr>
<td>✨ 版本特性</td> <td>✨ 版本特性</td>
<td class="highlight">{theme['features']}</td> <td class="highlight">{theme["features"]}</td>
</tr> </tr>
</table> </table>
<div class="auto-refresh">🔄 页面每3秒自动刷新观察容器变化</div> <div class="auto-refresh">🔄 页面每3秒自动刷新观察容器变化</div>
@@ -119,21 +129,26 @@ def hello():
</html> </html>
""" """
@app.route('/api/version')
@app.route("/api/version")
def version(): def version():
return jsonify({ return jsonify(
'version': VERSION, {
'hostname': socket.gethostname(), "version": VERSION,
'student_id': os.getenv('STUDENT_ID', '00'), "hostname": socket.gethostname(),
'timestamp': datetime.now().isoformat(), "student_id": os.getenv("STUDENT_ID", "00"),
'buggy': BUGGY "timestamp": datetime.now().isoformat(),
}) "buggy": BUGGY,
}
)
@app.route('/health')
@app.route("/health")
def health(): def health():
if BUGGY and random.random() < 0.3: if BUGGY and random.random() < 0.7:
return {'status': 'unhealthy'}, 503 return {"status": "unhealthy"}, 503
return {'status': 'healthy', 'version': VERSION}, 200 return {"status": "healthy", "version": VERSION}, 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80) if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)

View File

@@ -1,25 +1,38 @@
#!/bin/bash #!/bin/bash
REGISTRY="harbor.seahi.me/stu" REGISTRY="harbor.seahi.me/stu"
IMAGE_NAME="whoami-for-swarm" IMAGE_NAME="versions-for-swarm"
PLATFORMS="linux/amd64,linux/386,linux/arm64"
# 构建 v1.0 # 创建并使用支持多平台的 builder如果不存在
docker build --build-arg APP_VERSION=v1.0 \ if ! docker buildx inspect multiplatform-builder >/dev/null 2>&1; then
-t ${REGISTRY}/${IMAGE_NAME}:v1.0 . docker buildx create --name multiplatform-builder --driver docker-container --bootstrap
docker push ${REGISTRY}/${IMAGE_NAME}:v1.0 fi
docker buildx use multiplatform-builder
# 构建 v2.0 echo "🚀 开始构建所有版本..."
docker build --build-arg APP_VERSION=v2.0 \
-t ${REGISTRY}/${IMAGE_NAME}:v2.0 .
docker push ${REGISTRY}/${IMAGE_NAME}:v2.0
# 构建 v2.1 # 并行构建所有版本
docker build --build-arg APP_VERSION=v2.1 \ docker buildx build --platform ${PLATFORMS} --build-arg APP_VERSION=v1.0 \
-t ${REGISTRY}/${IMAGE_NAME}:v2.1 . -t ${REGISTRY}/${IMAGE_NAME}:v1.0 --push \
docker push ${REGISTRY}/${IMAGE_NAME}:v2.1 --cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache \
--cache-to type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache,mode=max . &
# 构建 v3.0-buggy有问题的版本 docker buildx build --platform ${PLATFORMS} --build-arg APP_VERSION=v2.0 \
docker build --build-arg APP_VERSION=v3.0-buggy --build-arg BUGGY=true \ -t ${REGISTRY}/${IMAGE_NAME}:v2.0 --push \
-t ${REGISTRY}/${IMAGE_NAME}:v3.0-buggy . --cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache \
docker push ${REGISTRY}/${IMAGE_NAME}:v3.0-buggy --cache-to type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache,mode=max . &
echo "✅ 所有版本构建完成!" docker buildx build --platform ${PLATFORMS} --build-arg APP_VERSION=v2.1 \
-t ${REGISTRY}/${IMAGE_NAME}:v2.1 --push \
--cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache \
--cache-to type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache,mode=max . &
docker buildx build --platform ${PLATFORMS} --build-arg APP_VERSION=v3.0-buggy --build-arg BUGGY=true \
-t ${REGISTRY}/${IMAGE_NAME}:v3.0-buggy --push \
--cache-from type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache \
--cache-to type=registry,ref=${REGISTRY}/${IMAGE_NAME}:buildcache,mode=max . &
# 等待所有后台任务完成
wait
echo "✅ 所有版本构建完成(支持平台: ${PLATFORMS}"

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
flask