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

- Структура проекта
- Flask приложение
- Dockerfile для Flask
- .dockerignore
- Сборка и запуск
- Flask + PostgreSQL через Docker Compose
- Переменные окружения через .env
- Горячая перезагрузка при разработке
- Часто задаваемые вопросы
- Как Flask соединиться с базой данных в Docker?
- Gunicorn или Flask dev server в Docker?
- Как передать переменные окружения в Flask контейнер?
- Что читать дальше по 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.
Что читать дальше по Docker
Чтобы связать тему с соседними практическими материалами, дальше удобно открыть:
- Dockerfile — собрать образ приложения через Dockerfile.
- Docker Compose — поднять приложение и зависимости через Compose.
- PostgreSQL в Docker — добавить PostgreSQL к Flask-приложению.
- Redis в Docker — добавить Redis для кеша или очередей.



