В этой статье мы подробно рассмотрим процесс установки и настройки всех необходимых инструментов для эффективной разработки Python-приложений с использованием FastAPI, Docker и Docker Compose. Вы узнаете, как создать изолированную среду для вашего проекта, настроить отладку и обеспечить бесперебойную работу вашего приложения.
1. Установка VSCode
Visual Studio Code (VSCode) — это мощный и популярный редактор кода, который станет вашим основным инструментом разработки.
Загрузка и установка VSCode
Скачайте .deb файл для вашей виртуальной машины с официального сайта: https://code.visualstudio.com/Download
-
Установите скачанный файл, используя команду в терминале:
sudo apt install ./<file>.deb
(Замените <file> на имя скачанного .deb файла.)
Добавление репозитория VSCode (альтернативный метод)
Вы также можете добавить официальный репозиторий VSCode, чтобы получать обновления автоматически:
sudo apt-get install wget gpg
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
sudo install -D -o root -g root -m 644 packages.microsoft.gpg /etc/apt/keyrings/packages.microsoft.gpg
echo "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" | sudo tee /etc/apt/sources.list.d/vscode.list > /dev/null
rm -f packages.microsoft.gpg
sudo apt install apt-transport-https
sudo apt update
sudo apt install code # или code-insiders
Установка расширения Python в VSCode
После установки VSCode перейдите в раздел Extensions (расширения) в левой боковой панели. Введите "python" в строке поиска и установите расширение с таким же названием. Это расширение крайне полезно для разработки на Python, предоставляя подсветку синтаксиса, автодополнение и отладку.
2. Проверка и установка Docker
Docker позволяет упаковывать ваше приложение и все его зависимости в изолированные контейнеры, что упрощает развертывание и масштабирование.
Проверка установки Docker
Чтобы проверить, установлен ли Docker, выполните команду:
sudo docker -v
Если Docker не установлен или возникли ошибки, перейдите к следующему шагу.
Удаление конфликтующих пакетов
Перед установкой Docker рекомендуется удалить любые потенциально конфликтующие пакеты:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
Установка официального репозитория Docker
# Добавьте официальный ключ GPG Docker:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Добавьте репозиторий в Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Установка пакетов Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Проверка успешной установки Docker
Запустите тестовый образ hello-world, чтобы убедиться, что Docker установлен корректно:
sudo docker run hello-world
Настройка Docker без sudo
Чтобы выполнять команды Docker без использования sudo, добавьте текущего пользователя в группу docker:
sudo groupadd docker
sudo usermod -aG docker $USER
После этого перезагрузите вашу виртуальную машину, чтобы изменения вступили в силу.
3. Настройка образа для окружения Python с FastAPI
Теперь, когда VSCode и Docker установлены, мы перейдем к созданию изолированной среды для нашего Python-проекта с использованием FastAPI.
3.1. Инициализация проекта в VSCode
Откройте VSCode.
Создайте новую директорию для вашего проекта. Например, назовите её test.
3.2. Создание requirements.txt
В корневой директории вашего проекта test создайте файл requirements.txt. В этом файле будут перечислены все зависимости вашего Python-приложения:
fastapi
uvicorn
FastAPI: Высокопроизводительный веб-фреймворк для создания API на Python.
Uvicorn: Высокопроизводительный асинхронный веб-сервер, реализующий спецификацию ASGI. Он используется для запуска асинхронных приложений, таких как те, что созданы с помощью FastAPI.
3.3. Создание файла main.py
Внутри директории test создайте подпапку src, а в ней — файл main.py. Вставьте следующий пример кода FastAPI:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
3.4. Создание Dockerfile
В корневой директории проекта test создайте файл Dockerfile. Этот файл содержит инструкции для Docker по сборке вашего образа:
FROM python:3.10-slim
WORKDIR /code
COPY ./requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY ./src ./src
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "80", "--reload"]
#Пояснения к Dockerfile:
FROM python:3.10-slim: Docker скачает образ python:3.10-slim с Docker Hub. Этот образ уже включает всё необходимое для работы с Python. Вы можете выбрать любую актуальную версию с Docker Hub.
WORKDIR /code: Устанавливает рабочую директорию внутри контейнера как /code. Вы можете назвать её по своему усмотрению.
COPY ./requirements.txt ./: Копирует файл requirements.txt из вашей локальной директории в рабочую директорию контейнера.
RUN pip install --no-cache-dir -r requirements.txt: Устанавливает все зависимости, перечисленные в requirements.txt.
COPY ./src ./src: Копирует содержимое локальной папки src в папку src внутри контейнера.
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "80", "--reload"]: Команда, которая будет выполняться при запуске контейнера. В данном случае запускается uvicorn для обслуживания вашего FastAPI-приложения.
Важно: Разделяйте команды в Dockerfile вертикальными пробелами. Docker умеет кешировать каждый блок команд, что ускоряет пересборку образа при изменениях.
3.5. Сборка образа Docker и запуск контейнера
Находясь в корневой директории проекта test в терминале, выполните следующие команды:
-
Сборка образа:
docker build -t fastapi-image .
(Имя fastapi-image может быть любым.)
-
Запуск контейнера на основе созданного образа:
docker run --name fastapi-container -p 80:80 fastapi-image
fastapi-container: Имя вашего контейнера.
fastapi-image: Имя созданного вами образа.
-p 80:80: Перенаправляет порт 80 контейнера на порт 80 вашей локальной машины.
После выполнения команды вы увидите, что uvicorn запустился по адресу http://localhost. Откройте этот адрес в браузере, чтобы увидеть результат работы вашего FastAPI-приложения.
3.6. Управление контейнером
Завершение работы приложения: Нажмите Ctrl+C в терминале, где запущен контейнер.
-
Удаление контейнера:
docker rm fastapi-container
-
Запуск контейнера в фоновом режиме (detached mode):
docker run --name fastapi-container -p 80:80 -d fastapi-image
Теперь контейнер будет работать в фоновом режиме, и вы сможете продолжить пользоваться терминалом. Проверьте работу приложения на http://localhost.
3.7. Синхронизация изменений с помощью Volumes
Если вы измените код в main.py на локальной машине, вы не увидите изменений в работающем контейнере, так как файл main.py внутри контейнера не обновился. Для синхронизации изменений используйте Volumes.
Volumes — это механизм в Docker, предназначенный для хранения данных, которые должны сохраняться независимо от жизненного цикла контейнера.
-
Остановите и удалите текущий контейнер (если он запущен):
docker stop fastapi-container docker rm fastapi-container
-
Запустите контейнер с Volumes:
docker run --name fastapi-container -p 80:80 -d -v $(pwd):/code fastapi-image
-v $(pwd):/code: Привязывает текущую рабочую директорию вашей локальной машины ($(pwd)) к директории /code внутри контейнера. Теперь любые изменения в файлах на локальной машине будут немедленно отражаться в контейнере.
Теперь, если вы измените содержимое файла main.py и обновите страницу http://local, вы сразу увидите изменения.
3.8. Разработка в VSCode внутри контейнера
Теперь возникла другая проблема: VSCode на локальной машине "не знает" о зависимостях, установленных внутри контейнера (например, FastAPI). Чтобы решить это, мы будем использовать возможности удаленной разработки VSCode.
-
Установите расширения VSCode: Откройте VSCode на локальной машине и установите следующие расширения:
Docker
Dev Containers
-
Подключение к запущенному контейнеру:
Убедитесь, что ваш контейнер запущен: docker ps.
В левом нижнем углу VSCode нажмите кнопку, похожую на >< (Open a Remote Window).
Выберите опцию "Attach to Running Container...".
VSCode предложит выбрать запущенный контейнер. Выберите fastapi-container (или как вы его назвали).
-
Открытие проекта в контейнере:
VSCode запустится внутри контейнера. Откройте папку /code (или ту, которую вы указали в WORKDIR Dockerfile).
Вы увидите то же содержимое, что и на локальной машине, но с важным отличием: в файле main.py Python больше не будет "ругаться" на отсутствие FastAPI, поскольку он установлен в контейнере.
Установите расширение Python в этом новом, "удаленном" окне VSCode (внутри контейнера), если оно ещё не установлено.
Поздравляем! Теперь вы можете разрабатывать непосредственно внутри вашего Docker-контейнера.
4. Использование Docker Compose
Постоянно вводить длинные команды docker run не очень удобно. Здесь на помощь приходит Docker Compose.
Docker Compose — это инструмент для определения и запуска многоконтейнерных Docker-приложений. Он позволяет описывать инфраструктуру приложения в одном файле (docker-compose.yml) и управлять всеми сервисами как единым целым.
4.1. Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.38.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo mv /usr/local/bin/docker-compose /usr/bin/docker-compose
sudo chmod +x /usr/bin/docker-compose
Проверка версии Docker Compose
docker-compose version
Вы должны увидеть версию Docker Compose.
4.2. Настройка docker-compose.yml
-
Остановите и удалите текущий контейнер (если он запущен):
docker stop fastapi-container docker rm fastapi-container
-
В корневой директории проекта test создайте файл с именем docker-compose.yml и скопируйте в него следующий код:
services: app: build: . container_name: python-server command: uvicorn src.main:app --host 0.0.0.0 --port 80 --reload ports: - 80:80 volumes: - .:/code
services: Определяет сервисы (контейнеры), из которых состоит ваше приложение.
app: Имя вашего сервиса (можно выбрать любое).
build: .: Указывает Docker Compose, что нужно собрать образ из текущей директории (где находится Dockerfile).
container_name: Присваивает имя контейнеру (python-server).
command: Команда, которая будет запущена при старте контейнера.
ports: Перенаправляет порты (локальный:контейнер).
volumes: Монтирует текущую директорию локальной машины к /code внутри контейнера для синхронизации кода.
4.3. Запуск приложения с Docker Compose
Находясь в корневой директории проекта test в терминале, выполните:
docker-compose up
Docker Compose автоматически соберет образ (если нужно) и запустит контейнер. Проверьте работу приложения на http://localhost:80. Вы увидите, что всё работает, но теперь для запуска понадобилась всего одна команда!
4.4. Остановка приложения с Docker Compose
Чтобы остановить все сервисы, определенные в docker-compose.yml, выполните:
docker-compose down
5. Добавление нового сервиса (Redis) с Docker Compose
Docker Compose значительно упрощает добавление новых сервисов в вашу инфраструктуру. Давайте добавим Redis.
5.1. Обновление docker-compose.yml
Дополните ваш файл docker-compose.yml следующим образом:
services:
app:
build: .
container_name: python-server
command: uvicorn src.main:app --host 0.0.0.0 --port 80 --reload
ports:
- 80:80
volumes:
- .:/code
depends_on:
- redis # Добавлено: указывает зависимость от сервиса redis
redis: # Новый сервис для Redis
image: redis:alpine # Имя образа Redis с Docker Hub
depends_on: - redis: Указывает Docker Compose, что сервис app зависит от сервиса redis. Это гарантирует, что Redis будет запущен до app.
redis: image: redis:alpine: Определяет новый сервис redis и указывает, какой образ использовать (взятый с Docker Hub).
5.2. Обновление requirements.txt
Добавьте зависимость redis в ваш файл requirements.txt:
fastapi
uvicorn
redis
5.3. Пересборка образа и запуск контейнеров
Теперь пересоберите образ и запустите все сервисы с Docker Compose. Флаг --build заставит Docker Compose пересобрать образ app, а -d запустит контейнеры в фоновом режиме.
docker-compose up --build -d
#5.4. Проверка запущенных контейнеров
Убедитесь, что запустились оба контейнера (python-server и redis:alpine):
docker ps
5.5. Проверка установки Redis в VSCode (внутри контейнера)
Снова подключитесь к контейнеру через VSCode (>< -> "Attach to Running Container..." -> python-server).
Если вы пересобирали образ, вам, возможно, придется переустановить расширение Python в этом "удаленном" окне VSCode.
-
После установки расширения откройте main.py и попробуйте импортировать Redis:
import redis
Если VSCode не подсвечивает эту строку как ошибку, значит, Redis успешно установлен в контейнере, и вы можете его использовать в вашем приложении.
6. Настройка отладки (Debug)
Отладка критически важна для разработки. Давайте настроим отладку вашего Python-приложения внутри контейнера.
Закройте удаленное соединение VSCode (>< -> "Close Remote Connection").
-
Обновите requirements.txt, добавив библиотеку для отладки:
fastapi uvicorn redis debugpy
-
Добавьте порт для отладки в docker-compose.yml:
services: app: build: . container_name: python-server command: uvicorn src.main:app --host 0.0.0.0 --port 80 --reload ports: - 80:80 - 5678:5678 # Добавлено: порт для отладки volumes: - .:/code depends_on: - redis redis: image: redis:alpine
- 5678:5678: Перенаправляет порт 5678 контейнера (который будет использоваться для отладки) на порт 5678 вашей локальной машины.
-
Пересоберите образ и запустите контейнеры:
docker-compose up --build -d
Снова подключитесь VSCode к контейнеру (>< -> "Attach to Running Container..." -> python-server).
-
Внесите изменения в main.py, добавив строки для debugpy:
from fastapi import FastAPI app = FastAPI() import debugpy debugpy.listen(("0.0.0.0", 5678)) # Начинаем слушать порт для отладки @app.get("/") def read_root(): return {"Hello": "привет"}
VSCode должен определить debugpy без ошибок.
-
Настройка запуска отладчика в VSCode:
Перейдите в раздел Run and Debug (иконка жука) в левой боковой панели VSCode.
Если файла launch.json нет, нажмите "create a launch.json file".
Выберите "Remote Attach" (или "Python: Remote Attach").
Выберите localhost и укажите порт 5678.
Файл launch.json будет создан с соответствующими настройками.
-
Запуск отладчика:
Установите точку останова в вашем коде (например, на строке return {"Hello": "привет"}).
Нажмите F5 (или кнопку "Start Debugging") в VSCode.
Обновите страницу http://localhost:80 в браузере. Вы увидите, что выполнение кода остановилось на вашей точке останова, и вы можете использовать все функции отладчика VSCode.
Теперь ваша среда разработки полностью настроена для эффективной работы с Python-проектами в изолированных Docker-контейнерах, включая удобную отладку!
Комментарии (6)
shqiptar
06.07.2025 15:53у автора немного сумбурный порядок изложения, но в целом подход нравится. плюсанул. молодец
из замечаний
1)docker run --name fastapi-container -p 80:80 -d -v $(pwd):/code fastapi-image что это за извращение? в волумес можешь поместить всю папку с фастапи. и таким образом всё что пишешь в идешке - отражается и в докере - фастапи в контейнере перезагружается, а логи ты видишь в терминале идешки. если у тебя несколько контейнеров, и они засирают терминал, то этой командой docker logs -f <имя контейнера> можешь видеть логи нужного тебе контейнера в текущем времени
2) для уменьшения объёма контейнера советую в докере установить облегчённую версию питона,поставить на неё зависимости, а потом установить новый образ а зависимости ставить из старогоFROM python:3.13-slim AS builder
WORKDIR /install
RUN apt update && apt install -y build-essential
COPY requirements.txt .
RUN pip install --upgrade pip &&
pip wheel --no-deps --wheel-dir /wheels -r requirements.txtRUN useradd -m myuser
USER myuserFROM python:3.13-slim
ENV PYTHONDONTWRITEBYTECODE=1
PYTHONUNBUFFERED=1
WORKDIR /backendДобавляем самоподписной сертификат в доверенные
RUN apt-get install -y ca-certificates &&
update-ca-certificatesRUN apt update && apt-get install -y curl grep
Копируем wheels и устанавливаем зависимости
COPY --from=builder /wheels /wheels
COPY requirements.txt .
RUN pip install --no-deps --no-index --find-links=/wheels -r requirements.txt--no-deps: Не устанавливает зависимости пакетов, только те, что перечислены в requirements.txt.
--no-index: Не использует PyPI или другие индексы , т.е. не будет скачивать пакеты из интернета.
--find-links=/wheels: Ищет пакеты локально в директории /wheels , где должны лежать .whl (wheel) файлы.
-r requirements.txt: Указывает список пакетов для установки.
--no-cache-dir: Отключает кэширование загруженных пакетов. Это может быть полезно, чтобы уменьшить размер образа Docker.
COPY . .
ENTRYPOINT ["sh", "-c", "
if [ "$PROFILE" = "1" ]; then
python -m cProfile -o output.prof runserver.py;
else
uvicorn app.main:app --host 0.0.0.0 --port 8000
--ssl-keyfile /usr/local/share/ca-certificates/tls.key
--ssl-certfile /usr/local/share/ca-certificates/tls.crt
--reload;
fi"]3) не забываем про хеалсчеки, зависимости и порты
одно из решений
depends_on:
db:
condition: service_healthy
healthcheck:
test: [ "CMD", "sh", "-c", "curl -sk https://localhost:8000/health_check/ -o /dev/null -w '%{http_code}' | grep -q '200' || exit 1" ]
interval: 5s
timeout: 5s
retries: 10
networks:
devops_mynetwork:
ipv4_address: 172.20.0.12
зайди в контейнер и проверь,как отработал хеалсчек
если тебе не надо открывать порт наружу, используй expose: вместо ports:
если в контейнере надо внести запись в hosts, то есть extra_hosts:
Ryav
Добро пожаловать в 2025! У нас есть pyproject.toml.
Непонятно, на кого вообще эта статья рачситана. Кто разрабатывает внутри докер контейнера и чем вас не устраивают venv?
shqiptar
звон немножко в другом месте. такие системы очень удобны для разработчиков (фронтенд, бекенд) в случае когда у себя на компе надо развернуть всю систему, а ставить чужой стек неохота. например, зачем фронту ставить питон, а питонщику реакт или вуе. кстати,а ты сам при разработке где используешь бд - в докере или нативно?
я например,для своей команды настроил всё в докерах - и фронт,и бекенд и базы данных.причём благодаря томам фастпишник может писать код у себя в идешке, а результат видеть и в терминале и в браузере. а для фронтов это вообще замечательно - не надо ставить питон. к тому же всё это проксирую в нгинксе по доменам и работаем в https.
если у тебя есть готовое решение для командной работы - то вперёд, напиши статью, если вещь фирменная - возьмём
danilovmy
@Ryav 2025, середина. У меня пара сотен проектов, много докер файлов и практически ни одного toml. Или я что-то не то делаю, или не только через pyproject.toml можно вести разработку. Ну, к слову, правда, requrements.txt тоже стало меньше.
shqiptar
requrements.txt мне на нравтся одним - там нет дерева зависимостей. если я по ошибке поставил какойнибудь пакет,а он за собой потянул ещё несколько, то непонятно, что удалять. вроде uv показывает зависимости, но не уверен,не использовал