Dockerfilepython3.12 , latest (dockerfile)python3.11 , (dockerfile)python3.10 (Dockerfile)python3.9 , (dockerfile) Эти теги больше не поддерживаются или поддерживаются, они удаляются из репозитория GitHub, но последние версии, выдвинутые, все равно могут быть доступны в Docker Hub, если кто -то их тянет:
python3.8python3.8-alpinepython3.7python3.6python2.7Последние теги даты для этих версий:
python3.8-2024-10-28python3.8-alpine-2024-03-11python3.7-2024-10-28python3.6-2022-11-25python2.7-2022-11-25 Примечание : есть теги для каждой даты сборки. Если вам нужно «прикрепить» версию изображения Docker, которую вы используете, вы можете выбрать один из этих тегов. Например tiangolo/uwsgi-nginx-flask:python3.7-2019-10-14 .
Docker Image с UWSGI и Nginx для Flask Web Applications в Python , работающих в одном контейнере.
Это изображение Docker позволяет создавать веб -приложения Flask в Python , которые работают с UWSGI и Nginx в одном контейнере.
Комбинация UWSGI с NGINX является распространенным способом развертывания веб -приложений Python Flask.
Если вы начинаете новый проект, вы можете попробовать Fastapi , который я создал, и где я провожу большую часть своего времени. Он также не нуждается в пользовательском базовом изображении, в документах есть инструкции по созданию собственного Dockerfile .
Github Repo : https://github.com/tiangolo/uwsgi-nginx-flask-docker
Docker Hub Изображение : https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
Вы, вероятно, используете Kubernetes или подобные инструменты. В этом случае вам, вероятно, не нужно это изображение (или любое другое подобное базовое изображение ). Вам, вероятно, лучше построить изображение Docker с нуля .
Если у вас есть кластер машин с Kubernetes , Docker Swarm Mode, Nomad или другой аналогичной сложной системой для управления распределенными контейнерами на нескольких машинах, то вы, вероятно, захотите обрабатывать репликацию на уровне кластера вместо использования диспетчера процессов в каждом контейнере, который запускает несколько рабочих процессов , что делает это изображение Docker.
В этих случаях (например, использование Kubernetes) вы, вероятно, захотите построить изображение Docker с нуля , установить ваши зависимости и запустить один процесс вместо этого изображения.
Например, с помощью стреляющегося у вас может быть файловое app/gunicorn_conf.py с:
# Gunicorn config variables
loglevel = "info"
errorlog = "-" # stderr
accesslog = "-" # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3 И тогда у вас может быть Dockerfile с:
FROM python:3.12
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD [ "gunicorn" , "--conf" , "app/gunicorn_conf.py" , "--bind" , "0.0.0.0:80" , "app.main:app" ]Вы можете прочитать больше об этих идеях в документации FastAPI о: FastAPI в контейнерах - Docker, так как те же идеи будут применяться к другим веб -приложениям в контейнерах.
Вы можете хотеть, чтобы диспетчер процессов запускал несколько рабочих процессов в контейнере, если ваше приложение достаточно простое , чтобы вам не нужно (по крайней мере, пока), чтобы точно настроить количество процессов слишком много, и вы можете просто использовать автоматизированный по умолчанию, и вы запускаете его на одном сервере , а не в кластере.
Вы можете развернуть на один сервер (не кластер) с Docker Compose , так что у вас не будет простого способа управления репликацией контейнеров (с Docker Compose) при сохранении общей сети и балансировки нагрузки .
Тогда вы могли бы захотеть иметь один контейнер с диспетчера процессов, запускающего несколько рабочих процессов внутри, как это делает это изображение Docker.
У вас также могут быть и другие причины , которые облегчат наличие одного контейнера с несколькими процессами вместо того, чтобы иметь несколько контейнеров с одним процессом в каждом из них.
Например (в зависимости от вашей настройки) у вас может быть какой -то инструмент, такой как экспортер Prometheus в том же контейнере, который должен иметь доступ к каждому из представленных запросов .
В этом случае, если бы у вас было несколько контейнеров , по умолчанию, когда Прометеус пришел к прочтению метрик , он каждый раз получал бы один для одного контейнера (для контейнера, который обрабатывал этот конкретный запрос) вместо получения накопленных метрик для всех реплицированных контейнеров.
Затем, в этом случае, может быть проще иметь один контейнер с несколькими процессами и локальный инструмент (например, экспортер Prometheus) на одном и том же контейнере, собирающем метрики Prometheus для всех внутренних процессов и выявляя эти метрики на этом единственном контейнере.
Узнайте больше об этом в документации FastAPI о: FastAPI в контейнерах - Docker, так как те же концепции применимы к другим веб -приложениям в контейнерах.
Вам не нужно клонировать это репо.
Вы можете использовать это изображение в качестве базового изображения для других изображений.
Предполагая, что у вас есть файл requirements.txt , у вас может быть Dockerfile как это:
FROM tiangolo/uwsgi-nginx-flask:python3.12
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /appДоступно несколько тегов изображений, но для новых проектов вы должны использовать последнюю доступную версию.
Это изображение Docker основано на Tiangolo/Uwsgi-Nginx . На этом изображении Docker Uwsgi и Nginx были установлены в том же контейнере и было сделано как основание этого изображения.
Dockerfile с: FROM tiangolo/uwsgi-nginx-flask:python3.12
COPY ./app /appapp и введите егоmain.py (он должен быть назван таким образом и должен быть в вашем каталоге app ) с помощью: from flask import Flask
app = Flask ( __name__ )
@ app . route ( "/" )
def hello ():
return "Hello World from Flask"
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) Основной объект приложения должен быть назван app (в коде), как в этом примере.
ПРИМЕЧАНИЕ . Раздел с функцией main() предназначен для целей отладки. Чтобы узнать больше, прочитайте расширенные инструкции ниже.
.
├── app
│ └── main.py
└── Dockerfile
Dockerfile , содержащий ваш каталог app )docker build -t myimage .docker run -d --name mycontainer -p 80:80 myimage... и у вас есть оптимизированный сервер Flask в контейнере Docker.
Вы должны быть в состоянии проверить его в URL -адресе вашего контейнера Docker, например: http://192.168.99.100 или http://127.0.0.1
Если вы строите современные приложения для фронта (например, Vue, React, Angular), вы, скорее всего, будете собирать современную версию JavaScript (ES2015, TypeScript и т. Д.) Для менее современной, более совместимой версии.
Если вы хотите обслуживать свой (скомпилированный) фронтальный код с помощью такого же бэкэнд -контейнера Docker, вам придется скопировать код в контейнер после его составления.
Это означает, что вам потребуется все инструменты Frontend, установленные на строительном компьютере (это может быть ваш компьютер, удаленный сервер и т. Д.).
Это также означает, что вам придется, как -то, всегда помнить, чтобы собрать код Frontend прямо перед созданием изображения Docker.
И это также может означать, что тогда вам может придется добавить свой скомпилированный код фронта в свой репозиторий git (надеюсь, вы уже используете GIT или изучите, как использовать git ).
Добавление скомпилированного кода в GIT - очень плохая идея по нескольким причинам, некоторые из них:
По этим причинам не рекомендуется обслуживать код фронта из того же бэкэнд (колба) контейнера.
Существует гораздо лучшая альтернатива обслуживанию вашего кода фронта из того же бэкэнд (колба) контейнера.
Вы можете иметь еще один контейнер Docker со всеми установленными инструментами Frontend (node.js и т. Д.), Который:
Чтобы узнать специфику этого процесса для фронтального здания в Docker, вы можете прочитать:
После одного бэкэнд (колба) контейнера и одного контейнера для фронта необходимо обслуживать их обоих.
И вы можете захотеть обслуживать их под одной и той же доменом под другим путем. Например, приложение Backend (Flask) на пути /api и фронт на «корневой» пути / .
Затем вы можете использовать Traefik, чтобы справиться с этим.
И это также может автоматически генерировать сертификаты HTTPS для вашего приложения с помощью Let's Encrypt. Все бесплатно, в очень легкой настройке.
Если вы хотите использовать эту альтернативу, проверьте генераторы проекта выше, все они используют эту идею.
В этом сценарии у вас будет 3 контейнера Docker:
Вы должны быть в состоянии следовать тем же инструкциям, что и в разделе « QuickStart » выше, с некоторыми незначительными модификациями:
app/ каталог, поместите его в приложение Directory app/app/ .__init__.py внутри этого app/app/ каталог.uwsgi.ini в ваше app/ каталог (который копируется в /app/uwsgi.ini внутри контейнера).uwsgi.ini добавьте: [uwsgi]
module = app.main
callable = app Объяснение uwsgi.ini заключается в следующем:
app.main . Итак, в app Package ( /app/app ) получите main модуль ( main.py ).app Object ( app = Flask(__name__) ).Ваша структура файла будет выглядеть как:
.
├── app
│ ├── app
│ │ ├── __init__.py
│ │ ├── main.py
│ └── uwsgi.ini
└── Dockerfile
...вместо:
.
├── app
│ ├── main.py
└── Dockerfile
Если вы используете статические файлы в одном и том же контейнере, убедитесь, что переменная среды STATIC_PATH установлена соответственно, например, для изменения значения по умолчанию /app/static to /app/app/static вы можете добавить эту строку в свой Dockerfile :
ENV STATIC_PATH /app/app/static... после этого все должно работать, как и ожидалось. Все остальные инструкции будут применяться нормально.
.
├── app
│ ├── app
│ │ ├── api
│ │ │ ├── api.py
│ │ │ ├── endpoints
│ │ │ │ ├── __init__.py
│ │ │ │ └── user.py
│ │ │ ├── __init__.py
│ │ │ └── utils.py
│ │ ├── core
│ │ │ ├── app_setup.py
│ │ │ ├── database.py
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ ├── main.py
│ │ └── models
│ │ ├── __init__.py
│ │ └── user.py
│ └── uwsgi.ini
└── Dockerfile
Убедитесь, что вы следите за официальными документами при импорте своих модулей:
Например, если вы находитесь в app/app/main.py и хотите импортировать модуль в app/app/core/app_setup.py вы бы написали его как:
from . core import app_setupили
from app . core import app_setupapp/app/api/endpoints/user.py и хотите импортировать объект users из app/app/core/database.py вы бы написали его как: from ... core . database import usersили
from app . core . database import users Вы можете настроить несколько вещей, используя переменные среды.
index.html напрямуюПримечание : этот метод устарел, поскольку он может создать несколько вопросов с современными фронтальными рамками. Для деталей и лучших альтернатив прочитайте раздел выше.
Установка переменной среды STATIC_INDEX на 1 Вы можете настроить Nginx для обслуживания файла в url /static/index.html при запросе / .
Это улучшит скорость, поскольку это не будет включать UWSGI и Python. Nginx будет служить файлу напрямую. Чтобы узнать больше, следуйте разделу выше « QuickStart for Spas ».
Например, чтобы включить это, вы можете добавить это в свой Dockerfile :
ENV STATIC_INDEX 1По умолчанию изображение начинается с 2 -х процессов UWSGI. Когда сервер испытывает высокую нагрузку, он создает до 16 процессов UWSGI, чтобы справиться с ним по требованию.
Если вам нужно настроить эти номера, вы можете использовать переменные среды.
Начальное число процессов UWSGI контролируется переменной UWSGI_CHEAPER , по умолчанию, установленной 2 .
Максимальное количество процессов UWSGI контролируется переменной UWSGI_PROCESSES , по умолчанию, установленной 16 .
Имейте в виду, что UWSGI_CHEAPER должен быть ниже, чем UWSGI_PROCESSES .
Так, если, например, вам нужно начать с 4 процессов и вырасти до 64, ваш Dockerfile может выглядеть как:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV UWSGI_CHEAPER 4
ENV UWSGI_PROCESSES 64
COPY ./app /app Вы можете установить пользовательский максимальный размер файла загрузки, используя переменную среды NGINX_MAX_UPLOAD , по умолчанию она имеет значение 0 , которое позволяет неограниченное количество файлов файлов загрузки. Это отличается от значения дефолта Nginx 1 МБ. Это настроено таким образом, потому что это самый простой опыт, который ожидает неопытный разработчик в Nginx.
Например, чтобы иметь максимальный размер файла загрузки 1 МБ (по умолчанию nginx) добавьте строку в свой Dockerfile с:
ENV NGINX_MAX_UPLOAD 1mПо умолчанию контейнер, изготовленный из этого изображения, будет прослушать в порту 80.
Чтобы изменить это поведение, установите переменную среды LISTEN_PORT . Вам также может потребоваться создать соответствующую инструкцию EXPOSE .
Вы можете сделать это в своем Dockerfile , это будет выглядеть как:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV LISTEN_PORT 8080
EXPOSE 8080
COPY ./app /appuwsgi.ini Существует файл по умолчанию в /app/uwsgi.ini с конкретными приложениями конфигурациями (в дополнение к глобальным конфигурациям uwsgi ).
Он содержит только:
[uwsgi]
module = main
callable = appmodule = main относится к файлу main.pycallable = app относится к Flask «приложение» в app переменной. Вы можете настроить uwsgi , заменив этот файл собственным, включая все ваши конфигурации.
Например, чтобы расширить приведенный выше по умолчанию и включить потоки, у вас может быть файл:
[uwsgi]
module = main
callable = app
enable-threads = trueuwsgi.ini Вы можете переопределить, где изображение должно искать файл приложения uwsgi.ini с использованием переменной среды UWSGI_INI .
При этом вы можете изменить каталог по умолчанию для вашего приложения из /app на что -то другое, например /application .
Например, чтобы изображение использовала файл в /application/uwsgi.ini , вы можете добавить это в свой Dockerfile :
ENV UWSGI_INI /application/uwsgi.ini
COPY ./application /application
WORKDIR /application Примечание WORKDIR /app
Примечание . Вам также придется настроить путь static файлов, прочитанный ниже.
./static/ Путь Вы можете заставить nginx использовать путь пользовательского каталога с файлами, которые будут непосредственно служить (без участия UWSGI) с переменной среды STATIC_PATH .
Например, чтобы Nginx обслуживал статический контент, используя файлы в /app/custom_static/ вы можете добавить это в свой Dockerfile :
ENV STATIC_PATH /app/custom_static Затем, когда браузер попросил файл, например, http://example.com/static/index.html, Nginx ответит непосредственно, используя файл в path /app/custom_static/index.html custom_static/index.html.
Примечание : вам также придется настроить колбу, чтобы использовать ее в качестве static каталога.
В качестве другого примера, если вам нужно было поместить код приложения в другой каталог, вы можете настроить Nginx для обслуживания этих статических файлов из этого различного каталога.
Если вам нужно было иметь статические файлы в /application/static/ вы можете добавить это в свой Dockerfile :
ENV STATIC_PATH /application/static/static URL Вы также можете заставить nginx служить статическим файлам в другом URL, для этого вы можете использовать переменную среды STATIC_URL .
Например, если вы хотите изменить URL /static на /content вы можете добавить это в свой Dockerfile :
ENV STATIC_URL /content Затем, когда браузер попросил файл, например, http://example.com/content/index.html, Nginx ответит непосредственно, используя файл в Path /app/static/index.html .
/app/prestart.sh Если вам нужно что -либо запустить перед запуском приложения, вы можете добавить файл prestart.sh в Directory /app . Изображение автоматически обнаружит и запустит его перед началом всего.
Например, если вы хотите добавить миграции SQL Alembic SQL (с SQLALCHEMY), вы можете создать файл ./app/prestart.sh в свой каталог кода (который будет скопирован вашим Dockerfile ) с::
#! /usr/bin/env bash
# Let the DB start
sleep 10 ;
# Run migrations
alembic upgrade head И будет ждать 10 секунд, чтобы дать базе данных некоторое время, чтобы запустить, а затем запустить эту команду alembic .
Если вам нужно запустить скрипт Python перед запуском приложения, вы можете сделать файл /app/prestart.sh запустить свой скрипт Python, с чем -то вроде:
#! /usr/bin/env bash
# Run custom Python script before starting
python /app/my_custom_prestart_script.py Примечание . Изображение использует source для запуска сценария, поэтому, например, переменные среды будут сохраняться. Если вы не понимаете предыдущего предложения, вам, вероятно, не нужно.
По умолчанию Nginx запустит один «работник -процесс».
Если вы хотите установить другое количество рабочих процессов NGINX, вы можете использовать переменную среды NGINX_WORKER_PROCESSES .
Вы можете использовать определенный единственный номер, например:
ENV NGINX_WORKER_PROCESSES 2 Или вы можете установить его на auto ключевого слова, и оно попытается автоматически определить количество доступных процессоров и использовать его для количества работников.
Например, используя auto , ваш DockerFile может выглядеть так:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV NGINX_WORKER_PROCESSES auto
COPY ./app /appПо умолчанию Nginx начнется с максимального предела 1024 соединений на одного работника.
Если вы хотите установить другой номер, вы можете использовать переменную среды NGINX_WORKER_CONNECTIONS , например:
ENV NGINX_WORKER_CONNECTIONS 2048Он не может превышать текущий предел на максимальном количестве открытых файлов. Посмотрите, как настроить его в следующем разделе.
Числовые подключения на работника Nginx не могут превышать предел максимального количества открытых файлов.
Вы можете изменить предел открытых файлов с переменной среды NGINX_WORKER_OPEN_FILES , например:
ENV NGINX_WORKER_OPEN_FILES 2048 Если вам нужно настраивать Nginx дальше, вы можете добавить *.conf файлы в /etc/nginx/conf.d/ в вашем Dockerfile .
Просто помните, что конфигурации по умолчанию создаются во время запуска в файле по адресу /etc/nginx/conf.d/nginx.conf и /etc/nginx/conf.d/upload.conf . Так что вы не должны перезаписать их. Вы должны назвать ваш *.conf -файл с чем -то другим, чем nginx.conf или upload.conf , например: custom.conf .
Примечание . Если вы настраиваете Nginx, возможно, копируете конфигурации из блога или ответ StackOverflow, имейте в виду, что вам, вероятно, необходимо использовать конфигурации, специфичные для UWSGI, а не для других модулей, например, ngx_http_fastcgi_module .
Если вам необходимо настройка Nginx еще дальше, полностью переопределите по умолчанию, вы можете добавить пользовательскую конфигурацию Nginx в /app/nginx.conf .
Он будет скопирован в /etc/nginx/nginx.conf и используется вместо сгенерированного.
Имейте в виду, что в этом случае это изображение не будет генерировать ни одну из конфигураций NGINX, оно только копирует и использует ваш файл конфигурации.
Это означает, что все переменные среды, описанные выше, специфичные для Nginx, не будут использоваться.
Это также означает, что он не будет использовать дополнительные конфигурации из файлов в /etc/nginx/conf.d/*.conf , если только у вас нет явно в разделе в своем пользовательском файле /app/nginx.conf с:
include /etc/nginx/conf.d/*.conf;
Если вы хотите добавить пользовательский файл /app/nginx.conf , но не знаете, с чего начать, вы можете использовать nginx.conf , используемый для тестов и настроить его или изменить его дальше.
Комбинация UWSGI с NGINX является распространенным способом развертывания веб -приложений Python Flask.
Грубо:
Nginx - это веб -сервер, он заботится о подключениях HTTP, а также может обслуживать статические файлы напрямую и эффективнее.
UWSGI - это сервер приложений, это то, что запускает ваш код Python, и он разговаривает с Nginx.
Ваш код Python имеет фактическое веб -приложение Flask и управляется UWSGI.
Изображение Tiangolo/Uwsgi-Nginx использует уже существующие тонкие и оптимизированные изображения Docker (на основе Debian, как рекомендовано Docker), и реализует некоторые из лучших практик Docker.
Он использует официальное изображение Python Docker, устанавливает UWSGI, а сверх этого (с наименьшим количеством модификаций) добавляет официальное изображение Nginx.
И он контролирует все эти процессы с помощью супервизирования.
Изображение (и теги), созданное этим репо, основано на изображении Tiangolo/Uwsgi-Nginx . Это изображение добавляет колбу и разумные по умолчанию поверх него.
Если вы следуете инструкциям и сохраните корневую каталог /app в вашем контейнере, с файлом с именем main.py и объектом Flask с именем app , оно должно «просто работать».
У уже есть файл uwsgi.ini в каталоге /app с конфигурациями UWSGI, чтобы он «просто работал». И все остальные необходимые параметры находятся в другом файле uwsgi.ini в изображении, внутри /etc/uwsgi/ .
Если вам нужно изменить имя основного файла или основной объект Flask, вам нужно предоставить свой собственный файл uwsgi.ini . Вы можете использовать тот, который в этом репо в качестве шаблона для начала (и вам придется только изменить 2 соответствующие строки).
Вы можете иметь A /app/static Directory, и эти файлы будут эффективно обслуживаться Nginx напрямую (не проходя через код Flask или даже UWSGI), он уже настроен для вас. Но вы можете настроить его дальше, используя переменные среды (прочитано выше).
Superissord заботится о запуске UWSGI с файлом uwsgi.ini в файле /app (включая также файл в /etc/uwsgi/uwsgi.ini ) и начинающий nginx.
Есть эмпирическое правило, которое у вас должно быть «один процесс на контейнер».
Это помогает, например, изолировать приложение и его базу данных в разных контейнерах.
Но если вы хотите иметь подход «микро-услуги», вы можете получить более одного процесса в одном контейнере, если они все связаны с одной и той же «службой», и вы можете включить код Flask, UWSGI и Nginx в одном и том же контейнере (и, возможно, запустите другой контейнер в базу данных).
Это подход, принятый на этом изображении.
У этого изображения (и тегов) есть некоторые файлы по умолчанию, поэтому, если вы запустите его само по себе (не как базовое изображение вашего собственного проекта), вы увидите веб -приложение «Hello World» по умолчанию.
Когда вы создаете Dockerfile с помощью COPY ./app /app вы замените эти файлы по умолчанию кодом приложения.
Основной файл по умолчанию состоит только в /app/main.py . И в случае тегов с -index , также в /app/static/index.html static/index.html.
Но эти файлы видят текст «(по умолчанию)» на обслуживаемой веб -странице, чтобы вы могли проверить, видите ли вы код по умолчанию или свой собственный код, переопределяющий по умолчанию.
Код вашего приложения должен быть в каталоге контейнера /app , он должен иметь файл main.py и что файл main.py должен иметь app объекта Flask.
Если вы следуете инструкциям выше или используете один из загружаемых примеров шаблонов, вы должны быть в порядке.
Существует также файл /app/uwsgi.ini внутри изображений с параметрами по умолчанию для UWSGI.
Загружаемые примеры включают копию того же файла uwsgi.ini для целей отладки. Чтобы узнать больше, прочитайте « Инструкции по продвинутой разработке » ниже.
Во время разработки вы можете сделать свой каталог кода в вашем контейнере Docker.
При этом у вас будет обновляться ваши файлы (временно) каждый раз, когда вы их изменяете, без необходимости снова создавать контейнер.
Для этого вы можете использовать команду pwd (распечатать рабочий каталог) внутри вашего docker run и флага -v для объемов.
С этим вы можете сопоставить свой каталог ./app с каталогом вашего контейнера /app .
Но сначала, поскольку вы будете полностью заменить каталог /app в вашем контейнере (и все его содержимое), вам понадобится файл uwsgi.ini в вашем каталоге ./app с:
[uwsgi]
module = main
callable = appИ тогда вы можете сделать картирование объема Docker.
Примечание . Файл uwsgi.ini включен в загружаемые примеры.
Dockerfile и своим каталогом ./app )uwsgi.ini в вашем каталоге ./appdocker build -t myimage ../app ) с каталогом вашего контейнера /app : docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app myimage Если вы зайдете в URL -адрес контейнера Docker, вы должны увидеть свое приложение, и вы сможете изменить файлы в ./app/static/ и увидеть эти изменения, отраженные в вашем браузере, просто перезагрузти
... но, когда UWSGI загружает все ваше веб -приложение Python Flask после того, как оно запустится, вы не сможете редактировать код своего Python Flask и увидеть отраженные изменения.
Чтобы иметь возможность (временно) отлаживать свой код Python Flask Live, вы можете запустить свой контейнер, переопределяя команду по умолчанию (которая запускает SuperSord, которое, в свою очередь, начинает UWSGI и Nginx) и запустить ваше приложение напрямую с помощью python , в режиме отладки, используя команду flask с переменными окружающей среды.
Таким образом, со всеми приведенными выше модификациями и заставкой вашего приложения запустить непосредственно с помощью flask , окончательная команда Docker будет:
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main.py -e FLASK_DEBUG=1 myimage flask run --host=0.0.0.0 --port=80 Или в случае проекта пакета, вы установите FLASK_APP=main/main.py :
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main/main.py -e FLASK_DEBUG=1 myimage flask run --host=0.0.0.0 --port=80Теперь вы можете отредактировать код Flask в своей локальной машине, и как только вы обновите свой браузер, вы увидите изменения вживую.
Помните, что вы должны использовать это только для отладки и разработки, для развертывания в производстве вы не должны устанавливать объемы, и вы должны позволить супервизирую начать и позволить ему начать UWSGI и Nginx (что происходит по умолчанию).
Альтернатива для этих последних шагов для работы, когда у вас нет пакета, но просто плоская структура с отдельными файлами (модули), ваш код Fython Flask может иметь этот раздел с:
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) ... и вы можете запустить его с python main.py Но это будет работать только тогда, когда вы не используете структуру пакета и не планируете делать это позже. В этом конкретном случае, если вы не добавили приведенный выше блок кода, ваше приложение будет слушать только localhost (внутри контейнера), в другом порту (5000), а не в режиме отладки.
Кроме того, если вы хотите сделать ту же живую отладку, используя переменную среды STATIC_INDEX=1 (для обслуживания /app/static/index.html непосредственно при запросе / ), ваш nginx не будет обслуживать его напрямую, так как оно не будет запущено (только ваше приложение Python Flask в режиме отладки будет запущено).
from flask import Flask , send_fileи
@ app . route ( '/' )
def route_root ():
index_path = os . path . join ( app . static_folder , 'index.html' )
return send_file ( index_path ) ... Это гарантирует, что ваше приложение также обслуживает файл /app/static/index.html при запросе / . Или, если вы используете структуру пакета, файл /app/main/static/index.html static/index.html.
И если вы используете SPA Framework, чтобы позволить ему обрабатывать URL -адреса в браузере, ваш код Fython Flask должен иметь раздел с:
# Everything not declared before (not a Flask route / API endpoint)...
@ app . route ( '/<path:path>' )
def route_frontend ( path ):
# ...could be a static file needed by the front end that
# doesn't use the `static` path (like in `<script src="bundle.js">`)
file_path = os . path . join ( app . static_folder , path )
if os . path . isfile ( file_path ):
return send_file ( file_path )
# ...or should be handled by the SPA's "router" in front end
else :
index_path = os . path . join ( app . static_folder , 'index.html' )
return send_file ( index_path ) ... Это заставляет Flask отправлять все файлы CSS, JavaScript и Image по запросу в URL -адресе корня ( / ), но также гарантируют, что ваш спа -салон занимается всеми другими URL -адресами, которые не определены в вашем приложении Flask.
Вот как это написано в учебнике выше и включено в загружаемые примеры.
Если вы следуете приведенным выше инструкциям, вероятно, что в какой -то момент вы напишете код, который сломает ваш сервер отладки колбы, и он будет сбой.
А поскольку единственным запуском процесса был ваш сервер отладки, который теперь остановлен, ваш контейнер прекратится.
Тогда вам придется снова запустить контейнер после исправления кода, и вы не будете очень легко увидеть, какая ошибка, которая сбоят ваш сервер.
Итак, во время развития вы могли бы сделать следующее (это то, что я обычно делаю, хотя я делаю это с Docker Compose, как в примере проектов):
docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main.py -e FLASK_DEBUG=1 myimage bash -c " while true ; do sleep 10 ; done "FLASK_APP=main/main.py : docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app -e FLASK_APP=main/main.py -e FLASK_DEBUG=1 myimage bash -c " while true ; do sleep 10 ; done "docker exec -it mycontainer bash Теперь вы будете находиться в вашем контейнере в каталоге /app .
flask run --host=0.0.0.0 --port=80Вы увидите начало вашего сервера отладки Flask, вы увидите, как он отправляет ответы на каждый запрос, вы увидите ошибки, когда вы нарушаете свой код, и как они останавливают ваш сервер, и вы сможете запустить его очень быстро, просто запустив команду выше.
Все теги изображения, конфигурации, переменные среды и параметры приложения протестированы.
issue-manager.yml . PR #385 от @tiangolo.latest-changes действие GitHub. PR #360 от @tiangolo.latest-changes.yml . PR #348 от @alejsdev.README.md . PR #346 от @alejsdev. Основные моменты этого выпуска:
python3.6-2022-11-25 и python2.7-2022-11-25 .1.17.10 .3.11 .-index sufix tags.-index (use ENV STATIC_INDEX 1 instead).2020-05-04 .tiangolo/uwsgi-nginx-flask:python3.8-2019-10-14 . PR #154./start.sh and /app/prestart.sh functionality to parent image. PR #134.2019-02-02:
uwsgi-nginx and PR #121./app/nginx.conf file that overrides the generated one. PR #51 in the parent image uwsgi-nginx and PR #122.2019-01-01:
2018-12-29:
2018-11-23:
2018-09-22:
2018-06-22:
NGINX_WORKER_CONNECTIONS to set the maximum number of Nginx worker connections and NGINX_WORKER_OPEN_FILES to set the maximum number of open files. Thanks to ronlut in this PR.2018-06-22:
Improvements from parent image:
Make uWSGI require an app to run, instead of going in "full dynamic mode" while there was an error. Supervisord doesn't terminate itself but tries to restart uWSGI and shows the errors. Uses need-app as suggested by luckydonald in this comment.
Correctly handled graceful shutdown of uWSGI and Nginx. Thanks to desaintmartin in this PR.
2018-02-04:
It's now possible to set the number of Nginx worker processes with the environment variable NGINX_WORKER_PROCESSES . Thanks to naktinis in this PR.
2018-01-14:
python2.7-alpine3.7 and python3.6-alpine3.7 .2017-12-10:
/app/prestart.sh script to run arbitrary code before starting the app (for example, Alembic - SQLAlchemy migrations). The documentation for the /app/prestart.sh is in the main README./app is part of the PYTHONPATH environment variable. That allows global imports from several places, easier Alembic integration, etc. 2017-12-08: Now you can configure which port the container should listen on, using the environment variable LISTEN_PORT thanks to tmshn in this PR.
2017-09-10: Updated examples and sample project to work with SPAs even when structuring the app as a package (with subdirectories).
2017-09-02:
flask run commands, that allows running a package application while developing more easily.2017-08-10: Many changes:
python3.6 , python3.6-index , python.3.5 , python3.5-index , python2.7 and python2.7-index . All the other images are deprecated in favor is this ones.latest will point to Python 3.6 and the other tags will be removed.tiangolo/uwsgi-nginx that improved this image too.index.html directly: STATIC_INDEXNGINX_MAX_UPLOADuwsgi.ini file (that allows using a custom directory different than /app ): UWSGI_INI (using the ideas by @bercikr in #5 )../static/ path: STATIC_PATH/static/ URL: STATIC_URLDockerfile with: FROM tiangolo/uwsgi-nginx-flask:python3.6
COPY ./app /appand then customize with environment variables.
This project is licensed under the terms of the Apache license.