Python Flask в Docker — деплой приложения с нуля

Берём простое Flask-приложение и деплоим его в Docker — шаг за шагом: Dockerfile → сборка → запуск → docker compose с PostgreSQL. Полный туториал от нуля.

Вся рубрика Docker: уроки, команды и практические сценарии

Структура проекта

flask-app/
├── app.py              # Flask приложение
├── requirements.txt    # зависимости Python
├── Dockerfile          # инструкция сборки образа
├── .dockerignore       # исключить лишнее
└── docker-compose.yml  # запуск с PostgreSQL

Flask приложение

# app.py
from flask import Flask, jsonify
import os

app = Flask(__name__)

@app.route("/")
def index():
    return jsonify({
        "message": "Hello from Docker!",
        "env": os.getenv("ENV", "dev"),
        "version": "1.0"
    })

@app.route("/health")
def health():
    return jsonify({"status": "ok"})

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
# requirements.txt
flask==3.0.0
gunicorn==21.2.0

Dockerfile для Flask

# Dockerfile
FROM python:3.12-slim

# Не буферизовать stdout/stderr — логи сразу видны в docker logs
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

# Сначала зависимости (кэш слоёв — изменения кода не сбросят этот слой)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Потом остальной код
COPY . .

EXPOSE 5000

# Gunicorn — production WSGI сервер (не Flask dev server)
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "app:app"]

.dockerignore

# .dockerignore
__pycache__/
*.pyc
*.pyo
.env
.git/
*.md
venv/
.venv/
.pytest_cache/
*.egg-info/

Сборка и запуск

# Собрать образ
docker build -t flask-app:1.0 .

# Проверить что образ создался
docker images | grep flask-app

# Запустить
docker run -d -p 5000:5000 --name flask-app flask-app:1.0

# Проверить
curl http://localhost:5000
# {"env":"dev","message":"Hello from Docker!","version":"1.0"}

curl http://localhost:5000/health
# {"status":"ok"}

# Логи
docker logs flask-app
docker logs -f flask-app   # следить

# Войти в контейнер
docker exec -it flask-app bash

Flask + PostgreSQL через Docker Compose

# docker-compose.yml
version: "3.9"

services:
  app:
    build: .
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql://myuser:secret@db:5432/mydb
      - ENV=production
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U myuser -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pgdata:

Подключение к PostgreSQL в app.py:

# app.py — подключение к PostgreSQL
import psycopg2
import os

DATABASE_URL = os.getenv("DATABASE_URL")

def get_db():
    return psycopg2.connect(DATABASE_URL)

@app.route("/users")
def users():
    conn = get_db()
    cur = conn.cursor()
    cur.execute("SELECT id, email FROM users LIMIT 10")
    rows = cur.fetchall()
    cur.close()
    conn.close()
    return jsonify(rows)
# Запустить всё
docker compose up -d

# Проверить
docker compose ps
curl http://localhost:5000

# Логи
docker compose logs -f app

Переменные окружения через .env

# .env (НЕ коммитить в git — добавить в .gitignore)
DB_PASSWORD=mysecretpassword
SECRET_KEY=supersecretkey123
ENV=production
# docker-compose.yml с .env
services:
  app:
    env_file: .env
  db:
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}

Горячая перезагрузка при разработке

# docker-compose.dev.yml — дополнение для разработки
services:
  app:
    volumes:
      - .:/app   # монтируем код с хоста в контейнер
    command: ["flask", "run", "--debug", "--host=0.0.0.0"]
    environment:
      - FLASK_ENV=development
      - FLASK_DEBUG=1
# Запуск с dev-конфигурацией
docker compose -f docker-compose.yml -f docker-compose.dev.yml up

# Теперь изменения в app.py → Flask автоматически перезапустится

Часто задаваемые вопросы

Как Flask соединиться с базой данных в Docker?

В Docker Compose имя сервиса = hostname. Если база называется db в docker-compose.yml — подключаться как postgresql://user:pass@db:5432/dbname. Ключевой момент: db в строке подключения — это имя сервиса, не localhost. Убедись что app и db в одной сети (в Compose — автоматически). Используй depends_on с condition: service_healthy чтобы app не стартовал до готовности PostgreSQL.

Gunicorn или Flask dev server в Docker?

В продакшне — всегда Gunicorn (или uWSGI). Flask dev server — однопоточный, не предназначен для нагрузки. Gunicorn запускает несколько worker процессов: gunicorn --workers 2 --bind 0.0.0.0:5000 app:app. Для разработки в контейнере — можно Flask dev server с --debug для автоперезагрузки при изменении кода.

Как передать переменные окружения в Flask контейнер?

Три способа: 1) -e KEY=VALUE при docker run. 2) env_file: .env в docker-compose.yml. 3) environment: секция в docker-compose.yml. В Flask читать: os.getenv("KEY", "default"). Секреты (пароли) — всегда через переменные окружения, никогда не хардкодить в коде или Dockerfile.

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x