Python — FastAPI / Django konteynerda

~15 daq · Docker · Real loyihalar

Muammodan boshlaylik

Python loyihalarida "mening kompyuterimda ishlaydi" muammosi ayniqsa og'ir:

  • Python 3.9 va 3.12 — turli sintaksis va kutubxona versiyalari
  • venv unutildi — paketlar tizim Python iga o'rnatildi
  • numpy, psycopg, Pillow — C kutubxonalarini talab qiladi, Windows da bir xil, Linux da boshqa
  • requirements.txt da versiyalar qotirilmagan — har bir o'rnatishda boshqa natija

Docker bularning hammasini bitta izchil muhitga yig'adi.


Asos image tanlash

Image Hajm Qachon
python:3.13 ~1 GB Kompilyatsiya vositalari kerak bo'lsa (faqat build bosqichida)
python:3.13-slim ~150 MB ✅ Ko'pchilik holatlar uchun
python:3.13-alpine ~60 MB ⚠️ Ko'pincha tavsiya etilmaydi

Alpine da Python uchun muammo (17-dars): ko'p paketlar Linux uchun tayyor "wheel" lar bilan keladi, lekin ular glibc uchun — Alpine (musl) uchun emas. Natija: pip install pandas noldan kompilyatsiya qilinadi — 20+ daqiqa va ko'p xato. Python uchun — -slim.


FastAPI — Dockerfile

# syntax=docker/dockerfile:1
FROM python:3.13-slim AS base
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /app

# ===== build: wheel lar =====
FROM base AS build
RUN apt-get update \
 && apt-get install -y --no-install-recommends build-essential libpq-dev \
 && rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip wheel --wheel-dir /wheels -r requirements.txt

# ===== production =====
FROM base AS production
RUN apt-get update \
 && apt-get install -y --no-install-recommends libpq5 \
 && rm -rf /var/lib/apt/lists/* \
 && useradd --create-home --uid 1000 ilova
COPY --from=build /wheels /wheels
RUN pip install /wheels/* && rm -rf /wheels
COPY --chown=ilova:ilova . .
USER ilova
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]
  • PYTHONUNBUFFERED=1 — muhim: busiz print va loglar buferlanadi va docker logs da kechikib (yoki umuman) ko'rinmaydi
  • PYTHONDONTWRITEBYTECODE=1 — .pyc fayllar yozilmasin
  • Multi-stage: kompilyator (build-essential) va -dev kutubxonalar faqat build bosqichida; production da faqat runtime kutubxona (libpq5)
  • pip wheel → pip install /wheels/* — kompilyatsiya qilingan paketlar ko'chiriladi
  • --host 0.0.0.0 — 9-dars

requirements.txt — versiyalar qotirilgan

fastapi==0.115.6
uvicorn[standard]==0.34.0
sqlalchemy==2.0.36
psycopg[binary]==3.2.3

fastapi (versiyasiz) — har build da boshqa versiya. Docker ning "bir xil muhit" va'dasi buziladi. pip freeze > requirements.txt yoki uv / poetry lock fayllari.

[!TIP] uv — Python uchun zamonaviy, juda tez paket menejeri. Dockerfile da: COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv va uv pip install --system -r requirements.txt — pip dan 10-100 barobar tezroq.


Django

FROM python:3.13-slim
ENV PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
WORKDIR /app
RUN useradd --create-home ilova
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=ilova:ilova . .
RUN python manage.py collectstatic --noinput
USER ilova
EXPOSE 8000
CMD ["gunicorn", "loyiha.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]
  • manage.py runserver — faqat ishlab chiqish uchun. Production da — gunicorn (yoki ASGI uchun uvicorn)
  • collectstatic — statik fayllar build paytida; ular Nginx yoki whitenoise orqali beriladi
  • Migratsiyalar — alohida xizmat (28-dars): python manage.py migrate

compose.yaml

services:
  api:
    build:
      context: .
      target: production
    restart: unless-stopped
    ports:
      - "127.0.0.1:8000:8000"
    environment:
      DATABASE_URL: postgresql://app:${DB_PASSWORD:?}@baza:5432/ilova
    depends_on:
      migrate:
        condition: service_completed_successfully

  migrate:
    build:
      context: .
      target: production
    command: ["alembic", "upgrade", "head"]          # Django: python manage.py migrate
    environment:
      DATABASE_URL: postgresql://app:${DB_PASSWORD}@baza:5432/ilova
    depends_on:
      baza:
        condition: service_healthy

  worker:
    build:
      context: .
      target: production
    command: ["celery", "-A", "app.worker", "worker", "--loglevel=info"]
    restart: unless-stopped
    depends_on: [redis]

  baza:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ilova
    volumes:
      - pg-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d ilova"]
      interval: 5s
      retries: 20

  redis:
    image: redis:7-alpine

volumes:
  pg-data:

Celery worker — xuddi shu image, boshqa command.

Ishlab chiqish

# compose.override.yaml
services:
  api:
    build:
      target: base
    command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]
    volumes:
      - ./:/app

--reload + bind mount — hot reload (20-dars). base bosqichida paketlar yo'q — ularni o'rnatadigan dev bosqichini qo'shing yoki Compose Watch (30-dars).


Odatiy muammolar

Loglar ko'rinmayapti — PYTHONUNBUFFERED=1.

pg_config executable not found / gcc: not found — -slim da kompilyator yo'q. psycopg[binary] ishlating yoki build bosqichiga build-essential libpq-dev qo'shing.

ModuleNotFoundError — WORKDIR va import yo'llari; PYTHONPATH=/app.

Konteyner ichida venv kerakmi? — Odatda yo'q: konteynerning o'zi izolyatsiya. Multi-stage da venv ni bosqichlar orasida ko'chirish usuli ham mavjud (/opt/venv).


Nima uchun shunday?

Nima uchun Python uchun Alpine — yomon tanlov, Node.js uchun esa normal?

Ekotizimga bog'liq. Node.js paketlarining aksariyati sof JavaScript — ular qaysi C kutubxonasi ustida ishlashiga befarq. Python esa ilmiy va ma'lumotlar bilan ishlash uchun C/C++/Fortran da yozilgan kutubxonalarga (numpy, pandas, scipy) juda bog'liq. PyPI ularni manylinux (glibc) uchun oldindan kompilyatsiya qilingan holda beradi — -slim da bir soniyada o'rnatiladi. Alpine (musl) uchun esa ko'pincha tayyor variant yo'q — va har bir build da noldan kompilyatsiya. Kichik hajm uchun yo'qotilgan vaqt va barqarorlik — arzimaydi.


Xulosa

Eslab qoling:

  • Python uchun — -slim, Alpine emas
  • PYTHONUNBUFFERED=1 — loglar darhol; PYTHONDONTWRITEBYTECODE=1
  • Multi-stage: build bosqichida kompilyator va pip wheel, production da faqat runtime
  • requirements.txt da versiyalar qotirilgan; uv — tez
  • Production server: FastAPI — uvicorn --host 0.0.0.0; Django — gunicorn, runserver emas
  • Migratsiyalar va Celery — alohida xizmatlar, bitta image
  • Root siz foydalanuvchi

Keyingi dars

36-dars: React / Vite frontend — build va Nginx bilan berish