Hostim Docs

Деплой Python-приложения

Эта статья дополняет общие правила из «Что нужно, чтобы деплой прошёл» конкретикой для Python. Если вкратце: нужны два файла в корне репозитория — список зависимостей и команда запуска.

Шаг 1. Зависимости — requirements.txt

Все пакеты, которые использует приложение, должны быть перечислены в requirements.txt (или в pyproject.toml / Pipfile) в корне репозитория. Nixpacks определит Python по этому файлу и установит указанное.

Частая причина провала: пакет установлен локально через pip install, но не записан в файл. Зафиксируйте зависимости командой:

pip freeze > requirements.txt

Отдельно проследите, чтобы в списке был сервер запуска, если это Web-сервис: gunicorn или uvicorn. Локально вы могли запускать приложение встроенным сервером, а на платформе его нужно объявить явно.

Шаг 2. Команда запуска — Procfile

Nixpacks не угадывает, чем запускать Python-приложение. Укажите это в файле Procfile (без расширения) в корне репозитория — одна строка вида <имя>: <команда>. Переменная $PORT в команде подставляется автоматически.

Дальше — готовые примеры под два типа сервисов.

Пример: Web-сервис

Web-сервис принимает HTTP-запросы и получает домен. Приложение обязано слушать порт из переменной PORT на адресе 0.0.0.0 (иначе домен вернёт 502 — см. общую статью). Продакшн-серверы gunicorn и uvicorn делают это через параметры запуска, приведённые ниже.

FastAPI

requirements.txt:

fastapi
uvicorn

main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    return {"status": "ok"}

Procfile:

web: uvicorn main:app --host 0.0.0.0 --port $PORT

Flask

requirements.txt:

flask
gunicorn

app.py:

from flask import Flask

app = Flask(__name__)

@app.get("/")
def root():
    return {"status": "ok"}

Procfile:

web: gunicorn app:app --bind 0.0.0.0:$PORT

Запись app:app означает «файл app.py, объект app». Для gunicorn в main.py это было бы main:app.

Встроенный сервер Flask (app.run()) для продакшена не предназначен, но если вы его используете — привязка к порту обязательна: app.run(host="0.0.0.0", port=int(os.environ["PORT"])).

Пример: Worker-сервис (Telegram-бот)

Worker работает в фоне, не принимает HTTP и не имеет домена. Порт слушать не нужно, а токены и ключи читаются из переменных окружения сервиса.

requirements.txt:

python-telegram-bot

bot.py:

import os
from telegram.ext import Application, CommandHandler

async def start(update, context):
    await update.message.reply_text("Привет")

app = Application.builder().token(os.environ["BOT_TOKEN"]).build()
app.add_handler(CommandHandler("start", start))
app.run_polling()

Procfile:

worker: python bot.py

Значение BOT_TOKEN задаётся в переменных окружения сервиса — см. «Переменные окружения и секреты».

Версия Python

По умолчанию берётся актуальная стабильная версия. Если нужна конкретная, задайте переменную окружения сервиса NIXPACKS_PYTHON_VERSION (например, 3.12).

Частые ошибки

СимптомПричинаРешение
ModuleNotFoundError при запускеПакет не указан в requirements.txtДобавьте его и пересоберите
Сборка прошла, но контейнер сразу останавливаетсяНет Procfile или неверная командаПроверьте имя объекта приложения (app:app) и путь к файлу
Домен отдаёт 502Приложение слушает 127.0.0.1 или фиксированный портСлушайте $PORT на 0.0.0.0
Бот не отвечает, в логах ошибка про токенТокен захардкожен или не заданЗадайте BOT_TOKEN в переменных окружения

Дальше