Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds

Deployment do Produkcji

Czas wypuścić Twój projekt w świat! Deployment to moment, gdy kod staje się produktem.

Docker - konteneryzacja

1# Dockerfile
2FROM python:3.11-slim as builder
3
4WORKDIR /app
5COPY requirements.txt .
6RUN pip wheel --no-cache-dir --no-deps --wheel-dir /wheels -r requirements.txt
7
8FROM python:3.11-slim
9
10WORKDIR /app
11
12# Security
13RUN useradd -m -u 1000 appuser
14USER appuser
15
16# Dependencies
17COPY --from=builder /wheels /wheels
18RUN pip install --no-cache /wheels/*
19
20# Application
21COPY --chown=appuser:appuser . .
22
23EXPOSE 8000
24CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
1# docker-compose.yml
2version: '3.8'
3
4services:
5  app:
6    build: .
7    ports:
8      - "8000:8000"
9    environment:
10      - OPENAI_API_KEY=${OPENAI_API_KEY}
11      - QDRANT_URL=http://qdrant:6333
12      - REDIS_URL=redis://redis:6379
13    depends_on:
14      - qdrant
15      - redis
16    healthcheck:
17      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
18      interval: 30s
19      timeout: 10s
20      retries: 3
21
22  qdrant:
23    image: qdrant/qdrant:latest
24    volumes:
25      - qdrant_data:/qdrant/storage
26    ports:
27      - "6333:6333"
28
29  redis:
30    image: redis:alpine
31    volumes:
32      - redis_data:/data
33
34volumes:
35  qdrant_data:
36  redis_data:

GitHub Actions - CI/CD

1# .github/workflows/deploy.yml
2name: Deploy
3
4on:
5  push:
6    branches: [main]
7
8jobs:
9  test:
10    runs-on: ubuntu-latest
11    steps:
12      - uses: actions/checkout@v4
13      - uses: actions/setup-python@v5
14        with:
15          python-version: "3.11"
16      - run: pip install -r requirements.txt
17      - run: pytest tests/ -v
18
19  build:
20    needs: test
21    runs-on: ubuntu-latest
22    steps:
23      - uses: actions/checkout@v4
24
25      - name: Build Docker image
26        run: docker build -t app:latest .
27
28      - name: Push to Registry
29        run: |
30          echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
31          docker tag app:latest ${{ secrets.DOCKER_USERNAME }}/ai-assistant:latest
32          docker push ${{ secrets.DOCKER_USERNAME }}/ai-assistant:latest
33
34  deploy:
35    needs: build
36    runs-on: ubuntu-latest
37    steps:
38      - name: Deploy to server
39        uses: appleboy/ssh-action@master
40        with:
41          host: ${{ secrets.SERVER_HOST }}
42          username: ${{ secrets.SERVER_USER }}
43          key: ${{ secrets.SSH_KEY }}
44          script: |
45            cd /app
46            docker-compose pull
47            docker-compose up -d

Cloud Deployment Options

1"""
2Opcje deploymentu:
3
41. VPS (DigitalOcean, Hetzner)
5   - Pełna kontrola
6   - Niski koszt (~$20/mies)
7   - Wymaga zarządzania
8
92. Platform as a Service
10   - Railway, Render, Fly.io
11   - Łatwy deployment
12   - Auto-scaling
13
143. Kubernetes
15   - Dla dużych systemów
16   - Wysoka dostępność
17   - Złożona konfiguracja
18
194. Serverless
20   - AWS Lambda, Google Cloud Run
21   - Pay-per-use
22   - Cold starts
23"""

Monitoring

1# Prometheus metrics
2from prometheus_client import Counter, Histogram, generate_latest
3from fastapi import Response
4
5REQUEST_COUNT = Counter('requests_total', 'Total requests', ['method', 'endpoint'])
6REQUEST_LATENCY = Histogram('request_latency_seconds', 'Request latency')
7
8@app.middleware("http")
9async def metrics_middleware(request, call_next):
10    REQUEST_COUNT.labels(request.method, request.url.path).inc()
11    with REQUEST_LATENCY.time():
12        response = await call_next(request)
13    return response
14
15@app.get("/metrics")
16async def metrics():
17    return Response(generate_latest(), media_type="text/plain")

Twój projekt jest gotowy do produkcji! W następnej lekcji - portfolio!

Przejdź do CodeWorlds