🧱 1. 创建一个基础 Flask 项目
项目结构:
1 2 3 4 5 6 7 8
| flask-demo/ ├── app.py ├── requirements.txt ├── Dockerfile ├── start.sh └── .github/ └── workflows/ └── docker.yml
|
app.py
1 2 3 4 5 6
| from flask import Flask app = Flask(__name__)
@app.route('/') def hello(): return "Hello from multi-arch Flask Docker in production mode!"
|
requirements.txt
start.sh
1 2 3 4 5 6 7 8 9 10
| #!/bin/bash
WORKERS=${WORKERS:-4}
echo "🚀 Starting Gunicorn with $WORKERS workers..."
exec gunicorn -w "$WORKERS" -b 0.0.0.0:5000 app:app
|
🐋 2. 编写多平台 Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12
| FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN chmod +x start.sh
CMD ["./start.sh"]
|
⚙️ 3. 本地构建 & 推送多平台镜像(可选)
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
| #!/bin/bash set -e
IMAGE_NAME="cloudsmithy/flask-demo" PLATFORMS="linux/amd64,linux/arm64" BUILDER_NAME="multiarch"
TAG=$(git describe --tags --abbrev=0 2>/dev/null || date +%Y%m%d)
echo "🔖 使用镜像 tag:$TAG" echo "📦 构建并推送镜像:" echo " - $IMAGE_NAME:$TAG" echo " - $IMAGE_NAME:latest"
if ! docker info | grep -q "Username: cloudsmithy"; then echo "🔐 正在登录 Docker Hub..." docker login -u cloudsmithy fi
if ! docker buildx inspect "$BUILDER_NAME" &> /dev/null; then docker buildx create --name "$BUILDER_NAME" --use else docker buildx use "$BUILDER_NAME" fi
docker buildx inspect --bootstrap
docker buildx build --platform "$PLATFORMS" \ -t "$IMAGE_NAME:$TAG" \ -t "$IMAGE_NAME:latest" \ --push .
|
🚀 4. 设置 GitHub Actions 自动推送镜像
在 .github/workflows/docker.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 37 38 39 40 41 42 43 44 45 46 47 48 49
| name: Build and Push Docker Image
on: push: tags: - 'v*'
jobs: build-and-push: runs-on: ubuntu-latest
steps: - name: Checkout source code uses: actions/checkout@v4
- name: Check DockerHub secrets run: | if [ -z "${{ secrets.DOCKER_USERNAME }}" ] || [ -z "${{ secrets.DOCKER_PASSWORD }}" ]; then echo "❌ ERROR: DOCKER_USERNAME or DOCKER_PASSWORD is missing" exit 1 fi
- name: Set up QEMU uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 with: install: true
- name: Docker login uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract tag name id: vars run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Build and push Docker image (multi-arch + latest) uses: docker/build-push-action@v5 with: context: . push: true platforms: linux/amd64,linux/arm64 tags: | cloudsmithy/flask-demo:${{ env.TAG }} cloudsmithy/flask-demo:latest
|
🔐 5. 配置 GitHub Secrets
在仓库的 Settings → Secrets → Actions 中添加:
| Name | Value |
|---|
DOCKER_USERNAME | 你的 Docker Hub 用户名 |
DOCKER_PASSWORD | 你的 Docker Hub Token(推荐) |
🏁 6. 触发构建 & 发布流程
1 2
| git tag v1.0.0 git push origin v1.0.0
|
GitHub Actions 会自动:
- 构建支持 x86 + ARM 的镜像
- 推送到 Docker Hub:
cloudsmithy/flask-demo:v1.0.0cloudsmithy/flask-demo:latest
✅ 7. 结果验证
1 2
| docker pull cloudsmithy/flask-demo:latest docker run -p 5000:5000 cloudsmithy/flask-demo:latest
|