正在学习
7.5 Deploying with Claude-Guided CI/CD
System setup
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
Install runtime deps
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
Copy app
COPY app.py .
Expose port and launch
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]
docker-compose.yml (optional local “prod-like” run)
version: "3.9"
services:
taskflow:
build: .
image: taskflow:local
ports:
- "8000:8000"
restart: unless-stopped
Run locally:
docker compose up --build
visit http://localhost:8000/health
deploy.sh
This script runs on your remote server (or via SSH) to pull and restart the service using a simple container. It is idempotent and safe to re-run.
#!/usr/bin/env bash
deploy.sh – pull and restart TaskFlow service
Usage (on remote host or via SSH): ./deploy.sh
Example: ./deploy.sh ghcr.io/your-org/taskflow:main-abc123
set -euo pipefail
IMAGE_TAG="${1:-}"
APP_NAME="taskflow"
PORT="${PORT:-8000}"
if [[ -z "$IMAGE_TAG" ]]; then
echo "Usage: $0
exit 1
fi
echo "[deploy] pulling $IMAGE_TAG"
docker pull "$IMAGE_TAG"
Create a network once; ignore if it exists
docker network create app_net >/dev/null 2>&1 || true
echo "[deploy] stopping old container (if any)"
docker rm -f "$APP_NAME" >/dev/null 2>&1 || true
echo "[deploy] starting new container"
docker run -d \
--name "$APP_NAME" \
--restart unless-stopped \
--network app_net \
-p 8000:8000 \
"$IMAGE_TAG"
Health check
echo "[deploy] waiting for health endpoint..."
for i in {1..20}; do
if curl -fsS "http://127.0.0.1:${PORT}/health" >/dev/null; then
echo "[deploy] healthy"
exit 0
fi
sleep 1
done
echo "[deploy] health check failed; printing logs"
docker logs "$APP_NAME" || true
exit 1
Make it executable on the remote host:
chmod +x deploy.sh
.github/workflows/ci.yml
This GitHub Actions workflow runs tests (if present), builds and pushes the image to GitHub Container Registry (GHCR), then deploys over SSH by invokingdeploy.sh on your server.
name: ci-cd
on:
push:
branches: [ "main" ]
workflow_dispatch: {}
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/taskflow
jobs:
test:
runs-on: ubuntu-latest
steps:
uses: actions/checkout@v4
uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: |
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Install test deps if present
pip install pytest || true
Run tests if tests exist
if ls -1 test*.py tests 2>/dev/null; then
pytest -q
else
echo "No tests found; skipping."
fi
build-and-push:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
uses: actions/checkout@v4
name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract short SHA
id: vars
run: echo "SHORT_SHA=GITHUB_OUTPUT
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
{{ env.IMAGE_NAME }}:latest
{{ env.IMAGE_NAME }}:main-${{ steps.vars.outputs.SHORT_SHA }}
deploy:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Prepare image tag
id: vars
run: echo "IMAGE={{ env.IMAGE_NAME }}:main-GITHUB_OUTPUT
- name: Deploy over SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
script: |
set -e
cd ${{ secrets.DEPLOY_PATH }}
./deploy.sh "${{ steps.vars.outputs.IMAGE }}"
Secrets to set in your repo settings
- DEPLOY_HOST– your server’s hostname or IP
- DEPLOY_USER– SSH user with Docker permissions
- DEPLOY_KEY– private key for that user (read-only to the repo)
- DEPLOY_PATH– directory on the server that containsdeploy.sh
Remote host one-time setup
- Install Docker.
- Copydeploy.shto${DEPLOY_PATH}and make it executable.
- Ensure the SSH user can run Docker (e.g., add todockergroup).
Local Dry Run
You can simulate the build step locally:
docker build -t taskflow:dev .
docker run -p 8000:8000 --rm taskflow:dev
#
Clarification Table
| Stage | What Happens | Claude’s Contribution | Outcome |
| --- | --- | --- | --- |
| Test | Install deps, run pytest if tests exist | Tighten assertions, add missing tests, explain failures | Failing code never ships |
| Build | Container image from Dockerfile | Suggest slimmer base images, multi-stage builds, health check endpoints | Repeatable runtime |
| Push | Tag and publish to registry | Enforce semantic tags, generate release notes | Deterministic artifact |
| Deploy | Remote script pulls tag and restarts container | Propose safe backoff, health checks, rollback command | Predictable rollout |
| Observe | Health probe and logs | Summarize logs, propose alerts and metrics | Faster incident response |
You now have a clean CI/CD path that anyone on your team can understand at a glance. Tests gate changes, the container ensures consistent runtime, and a tiny deploy script provides safe, idempotent rollouts with health checks. Claude’s role is to keep this loop tight: summarizing diffs into release notes, proposing safer deploy logic, and generating tests when features change. In the next section, you’ll extend this deployment with configurable environments—dev, staging, and production—with Claude helping you manage secrets, configuration drift, and promotion policies.
## 7.6 Lessons Learned and Improvements
Every deployment pipeline teaches its own lessons. Working through a Claude-guided CI/CD setup demonstrates how powerful automation becomes when paired with reasoning intelligence. This final section revisits what worked, what can be refined, and how to continuously evolve your build–test–deploy loop with Claude as an ever-present development partner. The goal is not just to have a functional pipeline, but one that is self-documenting, reliable, and adaptable—qualities Claude is uniquely positioned to reinforce.
Concept Development
The CI/CD pipeline you built in the previous section follows a modern DevOps principle: automate everything that can fail silently. Each automation step—testing, containerizing, deploying—serves as a defense against human error. Yet, the integration of Claude into this loop elevates it beyond a mechanical process. Claude adds cognitive automation: the ability to reason about changes, detect patterns, and propose improvements before failures reach production.
The lessons can be summarized around four pillars of maturity:
1. Consistency Over Speed: The fastest pipeline is worthless if it produces inconsistent outcomes. Claude helps maintain naming conventions, synchronize Docker tags, and enforce coding standards across environments.
2. Test Depth Matters: Unit tests are good; semantic tests are better. Claude can analyze API schemas, propose property-based tests, and explain gaps between business logic and specification.
3. Deployment Should Be Observable: Health checks and log collection must be embedded into every rollout. Claude can parse your deployment logs to identify non-fatal but critical patterns (like slow startups or warnings) that humans might miss.
4. Iteration Never Ends: Every pipeline is a living system. Claude’s ability to summarize diffs and generate improvement proposals makes continuous refinement natural, not burdensome.
Hands-On Example: Using Claude for Pipeline Improvement Proposals
After several successful deployments of the TaskFlow API, suppose your logs begin to show longer startup times due to dependency bloat. You can prompt Claude directly to help improve this pipeline step.
Prompt Example
“Claude, our Docker build step takes over two minutes and the image size has grown past 1GB. Please analyze this Dockerfile and suggest optimizations for build speed and image size.”
Claude might respond with structured, context-aware suggestions such as:
- Replace `python:3.11-slim` with a multi-stage build that compiles dependencies in one layer and copies only runtime artifacts to the final image.
- Use `pip install --no-cache-dir` along with a pinned `requirements.txt` to reduce rebuild times.
- Introduce a `.dockerignore` file to exclude unnecessary files like `.git`, tests, and local caches.
The following improved Dockerfile incorporates these changes:
```dockerfile
练习题
What is the purpose of setting ENV PYTHONDONTWRITEBYTECODE=1 in the Dockerfile?
Which command is used to expose port 8000 in the Dockerfile?
EXPOSE 8000PORT 8000OPEN 8000LISTEN 8000Which steps are included in the deploy.sh script for restarting the TaskFlow service? (Select all that apply)
The docker compose up --build command is used to build and run the Docker Compose configuration locally.
The command to make the deploy.sh script executable on the remote host is ___.
What is the purpose of the health check in the deploy.sh script?
Which GitHub Actions workflow job is responsible for building and pushing the Docker image to GHCR?
testbuild-and-pushdeployci-cdWhich files are required for the Dockerized FastAPI + GitHub Actions + SSH Deploy example? (Select all that apply)
app.pyrequirements.txtDockerfiledeploy.sh.github/workflows/ci.ymlThe WORKDIR /app command in the Dockerfile sets the working directory to /app inside the container.
The command to run tests in the GitHub Actions workflow is ___.
What is the role of the requirements.txt file in the Docker setup?
Which command is used to start the TaskFlow service in the deploy.sh script?
docker start taskflowdocker run -d --name taskflow ...docker compose updocker exec taskflowWhich steps are performed by the GitHub Actions workflow during deployment? (Select all that apply)
The COPY app.py . command in the Dockerfile copies the app.py file from the host machine to the container's working directory.
The command to log in to GHCR in the GitHub Actions workflow is ___.
What is the purpose of the EXPOSE 8000 command in the Dockerfile?
Which command is used to simulate the build step locally?
docker build -t taskflow:dev .docker compose up --builddocker run -p 8000:8000 --rm taskflow:devdocker pull taskflow:devWhich of the following are required repository secrets for the GitHub Actions workflow? (Select all that apply)
DEPLOY_HOSTDEPLOY_USERDEPLOY_KEYDEPLOY_PATHGITHUB_TOKENIn the Dockerfile, what is the purpose of the EXPOSE 8000 instruction, and how does it relate to API testing concepts?
Which steps in the CI/CD pipeline (ci.yml) ensure deterministic deployments, and how do they relate to FastAPI testing practices?
The health check in deploy.sh (curl to /health endpoint) verifies that the API meets the requirement of being demonstrably correct under normal conditions, as described in prior knowledge point kp_7_4_001.
The _______ instruction in the Dockerfile copies the application files into the container, which is a prerequisite for _______ tests to execute against the running service.
Explain how the CI/CD pipeline's 'build-and-push' job (ci.yml) supports the principle of consistent runtime environments for API testing.
登录后解锁笔记、知识点解析、AI 问答
立即登录