Это изображение Docker теперь устарело. Там нет необходимости использовать его, вы можете просто использовать Uvicorn с --workers .
Узнайте больше об этом ниже.
Dockerfilepython3.11 , latest (dockerfile)python3.10 , (dockerfile)python3.9 , (dockerfile)python3.11-slim (Dockerfile)python3.10-slim (Dockerfile)python3.9-slim (dockerfile) Эти теги больше не поддерживаются или поддерживаются, они удаляются из репозитория GitHub, но последние версии, выдвинутые, все равно могут быть доступны в Docker Hub, если кто -то их тянет:
python3.8python3.8-slimpython3.7python3.9-alpine3.14python3.8-alpine3.10python3.7-alpine3.8python3.6python3.6-alpine3.8Последние теги даты для этих версий:
python3.8-2024-11-02python3.8-slim-2024-11-02python3.7-2024-11-02python3.9-alpine3.14-2024-03-11python3.8-alpine3.10-2024-01-29python3.7-alpine3.8-2024-03-11python3.6-2022-11-25python3.6-alpine3.8-2022-11-25 Примечание : есть теги для каждой даты сборки. Если вам нужно «прикрепить» версию изображения Docker, которую вы используете, вы можете выбрать один из этих тегов. Например tiangolo/uvicorn-gunicorn-fastapi:python3.11-2024-11-02 .
Docker Image с Uvicorn , управляемым Gunicorn для высокопроизводительных веб-приложений Fastapi в Python с автоматической настройкой производительности.
Github Repo : https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker
Docker Hub Изображение : https://hub.docker.com/r/tiangolo/uvicorn-gunicorn-fastapi/
Fastapi показал, что это веб-фреймворк Python с одним из лучших выступлений, измеряемых сторонними эталонами, благодаря тому, что он основан и работал от Starlette .
Достижимая производительность находится наравне с (и во многих случаях превосходит) Go и Node.js Frameworks.
Это изображение имеет механизм автоматической настройки, включенный для запуска ряда рабочих процессов на основе доступных ядер ЦП. Таким образом, вы можете просто добавить свой код и автоматически получить высокую производительность , что полезно в простых развертываниях .
Вы, вероятно, используете Kubernetes или подобные инструменты. В этом случае вам, вероятно, не нужно это изображение (или любое другое подобное базовое изображение ). Вероятно, вам лучше построить изображение Docker с нуля, как объяснено в Docs For Fastapi в контейнерах - Docker: Создайте изображение Docker для Fastapi.
Если у вас есть кластер машин с Kubernetes , Docker Swarm Mode, Nomad или другой аналогичной сложной системой для управления распределенными контейнерами на нескольких машинах, то вы, вероятно, захотите обрабатывать репликацию на уровне кластера вместо того, чтобы использовать диспетчер процессов (например, стрелки из Uvicorn) в каждом контейнере, что является этим изображением докера.
В этих случаях (например, с использованием Kubernetes) вы, вероятно, захотите построить изображение Docker с нуля , установить ваши зависимости и запустить один процесс Uvicorn вместо этого изображения.
Например, ваш Dockerfile может выглядеть как:
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD [ "uvicorn" , "app.main:app" , "--host" , "0.0.0.0" , "--port" , "80" ]Вы можете прочитать больше об этом в документации Fastapi о: Fastapi в контейнерах - Docker.
Если вы определенно хотите иметь несколько работников в одном контейнере, Uvicorn теперь поддерживает обработку подпроцессов, включая перезапуск мертвых. Таким образом, нет необходимости управлять несколькими работниками в одном контейнере.
Вы можете изменить пример Dockerfile свыше, добавив вариант --workers в Uvicorn, например:
FROM python:3.9
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD [ "uvicorn" , "app.main:app" , "--host" , "0.0.0.0" , "--port" , "80" , "--workers" , "4" ]Это все, что вам нужно. Вам вообще не нужно это изображение Docker. ?
Вы можете прочитать больше об этом в документах Fastapi о развертывании с Docker.
У Uvicorn не было поддержки для управления обработкой работников, включая перезапуск мертвых работников. Но теперь это так.
До этого стреляющий корни можно использовать в качестве менеджера процессов, управляющих работниками Uvicorn. Эта дополнительная сложность, которая больше не нужна.
Остальная часть этого документа хранится по историческим причинам, но, вероятно, вам это не нужно. ?
tiangolo/uvicorn-gunicorn-fastapiЭто изображение установит разумную конфигурацию на основе сервера, на котором он работает (количество доступных ядер ЦП) без жертв.
Он имеет разумные по умолчанию, но вы можете настроить его с помощью переменных среды или переопределить файлы конфигурации.
Есть также тонкие версии. Если вы хотите один из них, используйте одну из тегов сверху.
tiangolo/uvicorn-gunicorn Это изображение ( tiangolo/uvicorn-gunicorn-fastapi ) основано на Tiangolo/Uvicorn-Gunicorn .
Это изображение на самом деле делает всю работу.
Это изображение просто устанавливает FASTAPI и имеет документацию, специально предназначенную для FASTAPI.
Если вы чувствуете уверенность в своих знаниях о Uvicorn, Eunicorn и Asgi, вы можете использовать это изображение напрямую.
tiangolo/uvicorn-gunicorn-starletteЕсть и сестры .
Если вы создаете новое веб-приложение Starlette и хотите отказаться от всех дополнительных функций от Fastapi, вы должны вместо этого использовать Tiangolo/Uvicorn-Gunicorn-Starlette .
ПРИМЕЧАНИЕ : Fastapi основан на Starlette и добавляет несколько функций. Полезно для API и других случаев: проверка данных, преобразование данных, документация с OpenAPI, инъекция зависимостей, безопасность/аутентификация и другие.
Вам не нужно клонировать репо GitHub.
Вы можете использовать это изображение в качестве базового изображения для других изображений.
Предполагая, что у вас есть файл requirements.txt , у вас может быть Dockerfile как это:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /app Он ожидает файла по адресу /app/app/main.py main.py.
Или иным образом файл на /app/main.py .
И ожидать, что оно содержит переменное app с вашим приложением FastAPI.
Затем вы можете построить свое изображение из каталога, в котором есть ваш Dockerfile , например:
docker build -t myimage ./Dockerfile с: FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
COPY ./requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /appapp и введите его.main.py с: from fastapi import FastAPI
app = FastAPI ()
@ app . get ( "/" )
def read_root ():
return { "Hello" : "World" }
@ app . get ( "/items/{item_id}" )
def read_item ( item_id : int , q : str = None ):
return { "item_id" : item_id , "q" : q } .
├── app
│ └── main.py
└── Dockerfile
Dockerfile , содержащий ваш каталог app ).docker build -t myimage .docker run -d --name mycontainer -p 80:80 myimageТеперь у вас есть оптимизированный сервер FASTAPI в контейнере Docker. Автоматедован для вашего текущего сервера (и количество ядер ЦП).
Вы должны быть в состоянии проверить его в URL своего контейнера Docker, например: http://192.168.99.100/items/5?Q=someQuery или http://127.0.0.1/items/5?Q=someQuery (или эквивалент, используя ваш хост Docker).
Вы увидите что -то вроде:
{ "item_id" : 5 , "q" : " somequery " }Теперь вы можете перейти на http://192.168.99.100/docs или http://127.0.0.1/docs (или эквивалент, используя ваш хост докера).
Вы увидите автоматическую интерактивную документацию API (предоставленная UI Swagger UI):
И вы также можете перейти к http://192.168.99.100/redoc или http://127.0.0.1/redoc(or эквивалент, используя ваш хост Docker).
Вы увидите альтернативную автоматическую документацию (предоставленную Redoc):
Вы, вероятно, также захотите добавить любые зависимости для вашего приложения и прикрепить их к конкретной версии, вероятно, включая Uvicorn, стрелковой корни и Fastapi.
Таким образом, вы можете убедиться, что ваше приложение всегда работает, как и ожидалось.
Вы можете установить пакеты с командами pip в вашем Dockerfile , используя requirements.txt .
И затем вы можете обновить эти зависимости контролируемым образом, запустив свои тесты, следя за тем, чтобы все работает, но не нарушая производственное приложение, если какая -то новая версия не совместима.
Вот небольшой пример того, как вы можете установить свои зависимости, убедившись, что у вас есть закрепленная версия для каждого пакета.
Допустим, у вас есть проект, управляемый поэзией, поэтому у вас есть зависимости от пакета в файле pyproject.toml . И, возможно, файловая poetry.lock .
Тогда у вас может быть Dockerfile , используя многоступенчатое здание Docker с:
FROM python:3.9 as requirements-stage
WORKDIR /tmp
RUN pip install poetry
COPY ./pyproject.toml ./poetry.lock* /tmp/
RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
COPY --from=requirements-stage /tmp/requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
COPY ./app /appЭто будет:
./poetry.lock* (заканчивая * ), он не будет сбой, если этот файл еще не доступен.Важно скопировать код приложения после установки зависимостей, таким образом, вы можете воспользоваться преимуществами кэша Docker. Таким образом, ему не придется устанавливать все с нуля каждый раз, когда вы обновляете файлы приложений, только когда вы добавляете новые зависимости.
Это также относится к любому другому способу, которым вы используете для установки ваших зависимостей. Если Dockerfile используете requirements.txt .
Это переменные среды, которые вы можете установить в контейнере для его настройки и их значений по умолчанию:
MODULE_NAME«Модуль Python» (файл), который будет импортирован надзором, этот модуль будет содержать фактическое приложение в переменной.
По умолчанию:
app.main , если есть файл /app/app/main.py main.py илиmain , если есть файл /app/main.py Например, если ваш основной файл был по адресу /app/custom_app/custom_main.py , вы можете установить его как:
docker run -d -p 80:80 -e MODULE_NAME= " custom_app.custom_main " myimageVARIABLE_NAMEПеременная внутри модуля Python, которая содержит приложение FastAPI.
По умолчанию:
appНапример, если в вашем основном файле Python есть что -то вроде:
from fastapi import FastAPI
api = FastAPI ()
@ api . get ( "/" )
def read_root ():
return { "Hello" : "World" } В этом случае api будет переменной с приложением FASTAPI. Вы можете установить это как:
docker run -d -p 80:80 -e VARIABLE_NAME= " api " myimageAPP_MODULEСтрока с модулем Python и именем переменной передано стрелке.
По умолчанию, установите на основе переменных MODULE_NAME и VARIABLE_NAME :
app.main:app илиmain:appВы можете установить это как:
docker run -d -p 80:80 -e APP_MODULE= " custom_app.custom_main:api " myimageGUNICORN_CONFПуть к файлу конфигурации пионога питона.
По умолчанию:
/app/gunicorn_conf.py , если он существует/app/app/gunicorn_conf.py , если он существует/gunicorn_conf.py (включены по умолчанию)Вы можете установить это как:
docker run -d -p 80:80 -e GUNICORN_CONF= " /app/custom_gunicorn_conf.py " myimageВы можете использовать файл конфигурации из базового изображения в качестве отправной точки для вашей.
WORKERS_PER_COREЭто изображение будет проверять, сколько ядер ЦП доступно на текущем сервере, работающем с вашим контейнером.
Он установит количество работников на количество ядер ЦП, умноженные на это значение.
По умолчанию:
1Вы можете установить это как:
docker run -d -p 80:80 -e WORKERS_PER_CORE= " 3 " myimage Если бы вы использовали значение 3 на сервере с 2 ядрами процессора, оно запустило бы 6 рабочих процессов.
Вы также можете использовать значения с плавающей запятой.
Так, например, если у вас есть большой сервер (скажем, с 8 ядрами процессора), запускающим несколько приложений, и у вас есть приложение FASTAPI, которое, как вы знаете, не нуждается в высокой производительности. И вы не хотите тратить ресурсы сервера. Вы можете заставить его использовать 0.5 работников на CPU Core. Например:
docker run -d -p 80:80 -e WORKERS_PER_CORE= " 0.5 " myimageНа сервере с 8 ядрами процессора это заставит его запустить только 4 рабочих процесса.
ПРИМЕЧАНИЕ . По умолчанию, если WORKERS_PER_CORE равен 1 , а сервер имеет только 1 ядро ЦП, вместо запуска 1 одного работника, он запустится 2. Это во избежание плохой производительности и блокировки приложений (приложение сервера) на небольших машинах (серверная машина/облако/и т. Д.). Это может быть переопределено с помощью WEB_CONCURRENCY .
MAX_WORKERSУстановите максимальное количество работников для использования.
Вы можете использовать его, чтобы позволить изображению вычислять количество работников автоматически, но убедиться, что оно ограничено максимумом.
Это может быть полезно, например, если каждый работник использует подключение к базе данных, а ваша база данных имеет максимальный предел открытых соединений.
По умолчанию это не установлено, что означает, что это не ограничено.
Вы можете установить это как:
docker run -d -p 80:80 -e MAX_WORKERS= " 24 " myimageЭто заставит изображение начать не более 24 работников, независимо от того, сколько ядер процессоров доступно на сервере.
WEB_CONCURRENCYПереопределить автоматическое определение количества работников.
По умолчанию:
WORKERS_PER_CORE . Таким образом, на сервере с 2 ядрами, по умолчанию он будет установлен на 2 .Вы можете установить это как:
docker run -d -p 80:80 -e WEB_CONCURRENCY= " 2 " myimageЭто сделало бы образ начала 2 рабочих процесса, независимо от того, сколько ядер ЦП доступно на сервере.
HOST«Хозяин», используемый стрелком, ИП, где стреляющий в состав прослушивания прослушивает запросы.
Это хост внутри контейнера.
Так, например, если вы установите эту переменную на 127.0.0.1 , она будет доступна только внутри контейнера, а не на хосте, который он использует.
Это предусмотрено для полноты, но вы, вероятно, не должны ее менять.
По умолчанию:
0.0.0.0PORTПорт, который контейнер должен слушать.
Если вы запускаете свой контейнер в ограничительной среде, которая заставляет вас использовать какой -то конкретный порт (например, 8080 ), вы можете установить его с этой переменной.
По умолчанию:
80Вы можете установить это как:
docker run -d -p 80:8080 -e PORT= " 8080 " myimageBINDФактический хозяин и порт перешли к стреляющемуся.
По умолчанию установите на основе HOST переменных и PORT .
Так что, если вы ничего не изменили, это будет установлено по умолчанию:
0.0.0.0:80Вы можете установить это как:
docker run -d -p 80:8080 -e BIND= " 0.0.0.0:8080 " myimageLOG_LEVELУровень бревна для стрелкового коса.
Один из:
debuginfowarningerrorcritical По умолчанию установите на info .
Если вам нужно сжать больше, например, принося в жертву производительность, установите его на warning , например:
Вы можете установить это как:
docker run -d -p 80:8080 -e LOG_LEVEL= " warning " myimageWORKER_CLASSКласс, который будет использоваться стрелком для рабочих.
По умолчанию установите на uvicorn.workers.UvicornWorker .
Тот факт, что он использует Uvicorn, - это то, что позволяет использовать фреймворки ASGI, такие как FASTAPI, и это также то, что обеспечивает максимальную производительность.
Вы, вероятно, не должны менять.
Но если по какой -то причине вам нужно использовать альтернативный работник Uvicorn: uvicorn.workers.UvicornH11Worker вы можете установить его с этой переменной среды.
Вы можете установить это как:
docker run -d -p 80:8080 -e WORKER_CLASS= " uvicorn.workers.UvicornH11Worker " myimageTIMEOUTРабочие молчат больше, чем это много секунд убиты и перезапускаются.
Узнайте больше об этом в документах о надзоре: Тайм -аут.
По умолчанию установите на 120 .
Обратите внимание, что Uvicorn и Asgi Frameworks, такие как Fastapi, являются асинхровыми, а не синхронизированы. Так что, вероятно, безопасно иметь более высокие тайм -ауты, чем для работников синхронизации.
Вы можете установить это как:
docker run -d -p 80:8080 -e TIMEOUT= " 20 " myimageKEEP_ALIVEКоличество секунд, чтобы ждать запросов на подключении.
Узнайте больше об этом в документах о надзоре: Keepalive.
По умолчанию установите на 2 .
Вы можете установить это как:
docker run -d -p 80:8080 -e KEEP_ALIVE= " 20 " myimageGRACEFUL_TIMEOUTТайм -аут для изящных работников перезагрузился.
Узнайте больше об этом в документах о стрелком: Graceful Timeout.
По умолчанию установите на 120 .
Вы можете установить это как:
docker run -d -p 80:8080 -e GRACEFUL_TIMEOUT= " 20 " myimageACCESS_LOGФайл журнала доступа для записи.
По умолчанию "-" , что означает stdout (печать в журналах Docker).
Если вы хотите отключить ACCESS_LOG , установите его на пустое значение.
Например, вы можете отключить его с:
docker run -d -p 80:8080 -e ACCESS_LOG= myimageERROR_LOGФайл журнала ошибок для записи.
По умолчанию "-" , что означает Stderr (печать в журналах Docker).
Если вы хотите отключить ERROR_LOG , установите его на пустое значение.
Например, вы можете отключить его с:
docker run -d -p 80:8080 -e ERROR_LOG= myimageGUNICORN_CMD_ARGS Любые дополнительные настройки командной строки для стреляющегося могут быть переданы в переменной среды GUNICORN_CMD_ARGS .
Узнайте больше об этом в документах о надзоре: Настройки.
Эти настройки будут иметь приоритет по сравнению с другими переменными среды и любым файлом конфигурации надзора.
Например, если у вас есть пользовательский сертификат TLS/SSL, который вы хотите использовать, вы можете скопировать их на изображение Docker или установить их в контейнере и установить --keyfile и --certfile в местоположение файлов, например:
docker run -d -p 80:8080 -e GUNICORN_CMD_ARGS= " --keyfile=/secrets/key.pem --certfile=/secrets/cert.pem " -e PORT=443 myimageПРИМЕЧАНИЕ . Вместо того, чтобы обрабатывать TLS/SSL самостоятельно и настраивать его в контейнере, рекомендуется использовать «прокси -сервер для завершения TLS», такой как Traefik. Вы можете прочитать больше об этом в документации FastAPI о HTTPS.
PRE_START_PATHПуть, где найти сценарий предварительного запуска.
По умолчанию установите на /app/prestart.sh .
Вы можете установить это как:
docker run -d -p 80:8080 -e PRE_START_PATH= " /custom/script.sh " myimage Изображение включает в себя файл конфигурации Python Python по умолчанию по адресу /gunicorn_conf.py .
Он использует переменные среды, объявленные выше, чтобы установить все конфигурации.
Вы можете переопределить его, включив файл в:
/app/gunicorn_conf.py/app/app/gunicorn_conf.py/gunicorn_conf.py/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 Вы можете настроить местоположение сценария Prestart с помощью переменной среды PRE_START_PATH , описанной выше.
Программа по умолчанию, которая запускается по адресу /start.sh . Он делает все, что описано выше.
Есть также версия для разработки с живой автоматической загрузкой на:
/start-reload.shДля разработки полезно иметь возможность установить содержимое кода приложения внутри контейнера как «громкость хоста» докера, чтобы иметь возможность изменять код и проверять его вживую, без необходимости создавать изображение каждый раз.
В этом случае также полезно запустить сервер с помощью Live Auto-Reload, чтобы он переименовал автоматически при каждом изменении кода.
Дополнительный скрипт /start-reload.sh запускает Uvicorn в одиночку (без стрелка) и в одном процессе.
Это идеально подходит для развития.
Например, вместо работы:
docker run -d -p 80:80 myimageВы могли бы бежать:
docker run -d -p 80:80 -v $( pwd ) :/app myimage /start-reload.sh-v $(pwd):/app : означает, что каталог $(pwd) должен быть установлен в виде тома внутри контейнера At /app .$(pwd) : запускает pwd ("Print Working Directory") и ставит его как часть строки./start-reload.sh : добавление чего-то (например, /start-reload.sh ) в конце команды заменяет команду по умолчанию «команду». В этом случае он заменяет по умолчанию ( /start.sh ) на альтернативу разработки /start-reload.sh . Поскольку /start-reload.sh не работает с надзором, любая из конфигураций, которые вы вкладываете в файл gunicorn_conf.py не будет применяться.
Но эти переменные среды будут работать так же, как описано выше:
MODULE_NAMEVARIABLE_NAMEAPP_MODULEHOSTPORTLOG_LEVEL Короче говоря: вы, вероятно, не должны использовать Alpine для проектов Python, вместо этого использовать версии изображения slim Docker.
Вы хотите больше подробностей? Продолжить чтение?
Alpine более полезен для других языков, где вы строите статический двоичный файл на одной стадии изображения Docker (используя многоэтапное здание Docker), а затем копируете его на простое альпийское изображение, а затем просто выполнить этот двоичный. Например, используя GO.
Но для Python, поскольку Alpine не использует стандартное инструменты, используемое для построения расширений Python, при установке пакетов во многих случаях Python ( pip ) не найдет предварительно скомпилированный пакет («колесо») для альпийского. И после отладки множество странных ошибок вы поймете, что вам нужно установить много дополнительных инструментов и создать много зависимостей, чтобы использовать некоторые из этих общих пакетов Python. ?
Это означает, что, хотя исходное альпийское изображение могло быть небольшим, вы получите изображение с размером, сравнимым с размером, который вы бы получили, если бы только использовали стандартное изображение Python (на основе Debian) или в некоторых случаях еще больше. ?
И во всех этих случаях, для строительства, потребления гораздо большего количества ресурсов потребуется гораздо больше времени, потребление гораздо больше ресурсов, дольше строить зависимости, а также увеличить его углеродный след, поскольку вы используете больше времени и энергии процессора для каждой сборки. ?
Если вам нужны стройные изображения Python, вам следует вместо этого попытаться использовать slim версии, которые все еще основаны на Debian, но меньше. ?
Все теги изображения, конфигурации, переменные среды и параметры приложения протестированы.
--workers . PR #303 от @tiangolo.issue-manager.yml . PR #343 от @tiangolo.latest-changes действие GitHub. PR #340 от @tiangolo.latest-changes.yml . PR #276 от @alejsdev.README.md . PR #275 от @alejsdev.README.md . PR #274 от @alejsdev. Основные моменты этого выпуска:
python3.6-2022-11-25 .slim версию. PR #40.WORKER_CLASSTIMEOUTKEEP_ALIVEGRACEFUL_TIMEOUTACCESS_LOGERROR_LOGGUNICORN_CMD_ARGSMAX_WORKERSPRE_START_PATH env var. PR #33.tiangolo/uvicorn-gunicorn-fastapi:python3.7-2019-10-15 . PR #17./start-reload.sh , проверьте обновленную документацию. PR #6 в родительском изображении.WORKERS_PER_CORE по умолчанию в 1 , так как это показывает, что они имеют наилучшую производительность на тестах.WEB_CONCURRENCY не установлена, минимум до 2 работников. Это следует избегать плохой производительности и блокировки приложений (приложение сервера) на небольших машинах (серверный аппарат/облако/и т. Д.). Это может быть переопределено с помощью WEB_CONCURRENCY . Это применимо, например, в случае, когда WORKERS_PER_CORE установлен на 1 (по умолчанию), а сервер имеет только 1 ядро процессора. PR #6 и PR #5 в родительском изображении./start.sh запустить независимо, читая и генерируя используемые переменные среды по умолчанию. И удалить /entrypoint.sh поскольку он ничего не изменяет в системе, только считывает переменные среды. PR #4 в родительском изображении./app/prestart.sh . Этот проект лицензирован в соответствии с условиями лицензии MIT.