Czas wypuścić Twój projekt w świat! Deployment to moment, gdy kod staje się produktem.
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 /wheels /wheels
18RUN pip install --no-cache /wheels/*
19
20# Application
21COPY . .
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: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 -d1"""
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"""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!