Dockerfile ذات الصلةpython3.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 مع UWSGI و NGINX لتطبيقات الويب Flask في Python تعمل في حاوية واحدة.
تتيح لك صورة Docker إنشاء تطبيقات الويب Flask في Python التي تعمل مع UWSGI و NGINX في حاوية واحدة.
مزيج من UWSGI مع Nginx هو وسيلة شائعة لنشر تطبيقات الويب Python Flask.
إذا كنت تبدأ مشروعًا جديدًا ، فقد ترغب في تجربة Fastapi ، التي أنشأتها ، وأين أقضي معظم وقتي الآن. كما أنه لا يحتاج إلى صورة أساسية مخصصة ، فهناك تعليمات في المستندات لإنشاء Dockerfile الخاصة بك.
github repo : https://github.com/tiangolo/uwsgi-nginx-flask-docker
Docker Hub Image : https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
ربما تستخدم kubernetes أو أدوات مماثلة. في هذه الحالة ، ربما لا تحتاج إلى هذه الصورة (أو أي صورة أساسية مماثلة أخرى). ربما تكون أفضل حالًا في بناء صورة Docker من الصفر .
إذا كان لديك مجموعة من الآلات التي تحتوي على Kubernetes أو وضع سرب Docker أو Nomad أو أي نظام معقد مشابه آخر لإدارة الحاويات الموزعة على أجهزة متعددة ، فربما ترغب في التعامل مع النسخ المتماثل على مستوى الكتلة بدلاً من استخدام مدير العملية في كل حاوية تبدأ عمليات العامل المتعددة ، وهو ما تفعله صورة Docker هذه.
في هذه الحالات (على سبيل المثال ، باستخدام kubernetes) ، ربما ترغب في إنشاء صورة Docker من نقطة الصفر ، وتثبيت تبعياتك ، وتشغيل عملية واحدة بدلاً من هذه الصورة.
على سبيل المثال ، باستخدام Gunicorn ، يمكن أن يكون لديك 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) مع الحفاظ على الشبكة المشتركة وموازنة التحميل .
بعد ذلك ، قد ترغب في الحصول على حاوية واحدة مع مدير عملية يبدأ العديد من عمليات العمال في الداخل ، كما تفعل صورة Docker هذه.
قد يكون لديك أيضًا أسباب أخرى من شأنها أن تجعل من السهل الحصول على حاوية واحدة مع عمليات متعددة بدلاً من وجود حاويات متعددة مع عملية واحدة في كل منها.
على سبيل المثال (اعتمادًا على الإعداد الخاص بك) ، يمكن أن يكون لديك أداة مثل مصدر Prometheus في نفس الحاوية التي يجب أن تتمكن من الوصول إلى كل من الطلبات التي تأتي.
في هذه الحالة ، إذا كان لديك حاويات متعددة ، بشكل افتراضي ، عندما جاء بروميثيوس لقراءة المقاييس ، فإنه سيحصل على الحاوية الواحدة في كل مرة (للحاوية التي تعاملت مع هذا الطلب المعين) ، بدلاً من الحصول على المقاييس المتراكمة لجميع الحاويات المتكررة.
بعد ذلك ، في هذه الحالة ، قد يكون من الأسهل أن يكون لديك حاوية واحدة مع عمليات متعددة ، وأداة محلية (مثل مصدر بروميثيوس) على نفس الحاوية التي تجمع مقاييس بروميثيوس لجميع العمليات الداخلية وفضح تلك المقاييس على تلك الحاوية الفردية.
اقرأ المزيد عن ذلك كله في وثائق Fastapi حول: Fastapi في الحاويات - Docker ، حيث تنطبق نفس المفاهيم على تطبيقات الويب الأخرى في الحاويات.
ليس عليك استنساخ هذا الريبو.
يمكنك استخدام هذه الصورة كصورة أساسية للصور الأخرى.
على افتراض أن لديك requirements.txt ملف. 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... ولديك خادم قارورة محسّن في حاوية Docker.
يجب أن تكون قادرًا على التحقق من ذلك في عنوان URL لحاوية Docker ، على سبيل المثال: http://192.168.99.100 أو http://127.0.0.1
إذا كنت تقوم ببناء تطبيقات الواجهة الأمامية الحديثة (مثل Vue ، React ، Angular) ، فمن المحتمل أن تقوم بتجميع نسخة حديثة من JavaScript (ES2015 ، TypeScript ، إلخ) إلى إصدار أقل توافقًا وأكثر توافقًا.
إذا كنت ترغب في تقديم رمز الواجهة الأمامية (المترجمة) بواسطة حاوية Docker (Flask) ذات الواجهة الخلفية (Flask) ، فسيتعين عليك نسخ الرمز إلى الحاوية بعد تجميعها.
هذا يعني أنك ستحتاج إلى تثبيت جميع أدوات الواجهة الأمامية على جهاز البناء (قد يكون جهاز الكمبيوتر الخاص بك ، خادم بعيد ، إلخ).
هذا يعني أيضًا أنه سيتعين عليك ، بطريقة ما ، تذكر دائمًا تجميع رمز الواجهة الأمامية قبل إنشاء صورة Docker.
وقد يعني ذلك أيضًا أنه يمكنك بعد ذلك إضافة رمز الواجهة الأمامية المترجمة إلى مستودع git الخاص بك (نأمل أن تستخدم GIT بالفعل ، أو تعلم كيفية استخدام git ).
تعد إضافة الكود المترجم إلى GIT فكرة سيئة للغاية لعدة أسباب ، بعضها هي:
لهذه الأسباب ، لا ينصح بخدمة رمز الواجهة الأمامية من نفس الحاوية الخلفية (Flask) Docker.
هناك بديل أفضل بكثير لخدمة رمز الواجهة الأمامية الخاصة بك من نفس الحاوية الخلفية (Flask) Docker.
يمكنك الحصول على حاوية Docker أخرى مع تثبيت جميع أدوات الواجهة الأمامية (node.js ، إلخ) التي:
لمعرفة تفاصيل هذه العملية لبناء الواجهة الأمامية في Docker ، يمكنك قراءة:
بعد الحصول على حاوية خلفية واحدة (قارورة) وحاوية الواجهة الأمامية ، تحتاج إلى خدمة كلاهما.
وقد ترغب في خدمتهم تحت نفس المجال ، تحت مسار مختلف. على سبيل المثال ، تطبيق الواجهة الخلفية (Flask) في المسار /api والواجهة الأمامية في مسار "الجذر" / .
يمكنك بعد ذلك استخدام Trafik للتعامل مع ذلك.
ويمكنه أيضًا إنشاء شهادات HTTPS تلقائيًا لتطبيقك باستخدام Let's Encrypt. كل ذلك مجانًا ، في إعداد سهل للغاية.
إذا كنت ترغب في استخدام هذا البديل ، فتحقق من مولدات المشروع أعلاه ، فكلها تستخدم هذه الفكرة.
في هذا السيناريو ، سيكون لديك 3 حاويات Docker:
يجب أن تكون قادرًا على اتباع نفس الإرشادات كما في قسم " QuickStart " أعلاه ، مع بعض التعديلات البسيطة:
app/ الدليل ، ضعه في app/app/ .__init__.py داخل هذا app/app/ الدليل.uwsgi.ini داخل app/ الدليل الخاص بك (يتم نسخه على /app/uwsgi.ini uwsgi.ini داخل الحاوية).uwsgi.ini الخاص بك ، أضف: [uwsgi]
module = app.main
callable = app شرح uwsgi.ini كما يلي:
app.main . لذلك ، في app الحزمة ( /app/app ) ، احصل على الوحدة main ( main.py ).app ( 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 ولا بيثون. سوف Nginx يخدم الملف مباشرة. لمعرفة المزيد ، اتبع القسم أعلاه " QuickStart for SPAS ".
على سبيل المثال ، لتمكينه ، يمكنك إضافة هذا إلى Dockerfile :
ENV STATIC_INDEX 1بشكل افتراضي ، تبدأ الصورة بعملية 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 . قد تحتاج أيضًا إلى إنشاء تعليمات Docker 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 مهمًا ، وإلا فإن UWSGI ستحاول تشغيل التطبيق في /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.
ملاحظة : سيتعين عليك أيضًا تكوين Flask لاستخدام ذلك كدليل static .
كمثال آخر ، إذا كنت بحاجة إلى وضع رمز التطبيق الخاص بك في دليل مختلف ، فيمكنك تكوين NGINX لخدمة تلك الملفات الثابتة من هذا الدليل مختلف.
إذا كنت بحاجة إلى الحصول على الملفات الثابتة في /application/static/ يمكنك إضافة هذا إلى Dockerfile :
ENV STATIC_PATH /application/static/static يمكنك أيضًا جعل 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 إلى الدليل /app . ستكتشف الصورة وتشغيلها تلقائيًا قبل بدء كل شيء.
على سبيل المثال ، إذا كنت ترغب في إضافة Alembic SQL Migrations (مع 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.
/app/nginx.conf يعني أيضًا أنه لن يستخدم تكوينات إضافية من الملفات في /etc/nginx/conf.d/*.conf .
include /etc/nginx/conf.d/*.conf;
إذا كنت ترغب في إضافة ملف custom /app/nginx.conf ولكن لا تعرف من أين تبدأ ، فيمكنك استخدام nginx.conf المستخدمة في الاختبارات وتخصيصه أو تعديله بشكل أكبر.
مزيج من UWSGI مع Nginx هو وسيلة شائعة لنشر تطبيقات الويب Python Flask.
تقريبا:
Nginx هو خادم ويب ، ويهتم باتصالات HTTP ويمكن أيضًا تقديم ملفات ثابتة بشكل مباشر وأكثر كفاءة.
UWSGI هو خادم تطبيق ، وهذا ما يدير رمز Python الخاص بك ويتحدث مع Nginx.
يحتوي رمز Python الخاص بك على تطبيق Flask Web الفعلي ، ويتم تشغيله بواسطة UWSGI.
تستفيد الصورة Tiangolo/UWSGI-NGINX من صور Docker النحيفة والمحسّنة الموجودة بالفعل (استنادًا إلى Debian على النحو الموصى بها من قبل Docker) وتنفذ العديد من أفضل ممارسات Docker.
يستخدم صورة Python Docker الرسمية ، ويقوم بتثبيت UWSGI وفوق ذلك (مع أقل قدر من التعديلات) يضيف صورة Nginx الرسمية.
ويتحكم في كل هذه العمليات مع Supervisord.
تعتمد الصورة (والعلامات) التي تم إنشاؤها بواسطة هذا الريبو على صورة Tiangolo/UWSGI-NGINX . تضيف هذه الصورة قارورة وافتراضات معقولة فوقها.
إذا اتبعت الإرشادات وحافظت على دليل /app الجذر في الحاوية الخاصة بك ، مع ملف يسمى main.py وكائن قارورة يسمى app فيه ، يجب أن "يعمل فقط".
يوجد بالفعل ملف uwsgi.ini في دليل /app مع تكوينات UWSGI لـ "مجرد العمل". وجميع المعلمات المطلوبة الأخرى موجودة في ملف uwsgi.ini آخر في الصورة ، داخل /etc/uwsgi/ .
إذا كنت بحاجة إلى تغيير اسم الملف الرئيسي أو كائن Flask الرئيسي ، فسيتعين عليك توفير ملف uwsgi.ini الخاص بك. يمكنك استخدام واحد في هذا الريبو كقالب للبدء به (وسيتعين عليك فقط تغيير الخطين المقابلان).
يمكن أن يكون لديك A /app/static Directory وسيتم تقديم هذه الملفات بكفاءة بواسطة Nginx مباشرة (دون المرور عبر رمز القارورة أو حتى UWSGI) ، تم تكوينه بالفعل لك. ولكن يمكنك تكوينه بشكل أكبر باستخدام متغيرات البيئة (اقرأ أعلاه).
يعتني Supervisord بتشغيل UWSGI مع ملف uwsgi.ini في ملف /app (بما في ذلك أيضًا الملف في /etc/uwsgi/uwsgi.ini ) وبدء nginx.
هناك قاعدة من الإبهام التي يجب أن يكون لديك "عملية واحدة لكل حاوية".
يساعد ذلك ، على سبيل المثال ، على عزل التطبيق وقاعدة البيانات الخاصة به في حاويات مختلفة.
ولكن إذا كنت ترغب في الحصول على نهج "الخدمات الصغيرة" ، فقد ترغب في الحصول على أكثر من عملية في حاوية واحدة إذا كانت جميعها مرتبطة بنفس "الخدمة" ، وقد ترغب في تضمين رمز القارورة الخاص بك و 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.
إذا اتبعت الإرشادات أعلاه أو استخدمت أحد قوالب المثال القابلة للتنزيل ، فيجب أن تكون على ما يرام.
يوجد أيضًا ملف A /app/uwsgi.ini داخل الصور مع المعلمات الافتراضية لـ UWSGI.
تتضمن الأمثلة القابلة للتنزيل نسخة من نفس ملف uwsgi.ini لأغراض التصحيح. لمعرفة المزيد ، اقرأ " تعليمات التطوير المتقدمة " أدناه.
أثناء التطوير ، قد ترغب في جعل دليل الرمز الخاص بك وحدة تخزين في حاوية Docker الخاصة بك.
مع ذلك ، ستحقق ملفاتك (مؤقتًا) في كل مرة تقوم فيها بتعديلها ، دون الحاجة إلى إنشاء الحاوية الخاصة بك مرة أخرى.
للقيام بذلك ، يمكنك استخدام Command pwd (دليل عمل طباعة) داخل docker run و Flag -v للمجلدات.
مع ذلك ، يمكنك تعيين دليل ./app إلى دليل الحاوية /app .
لكن أولاً ، نظرًا لأنك ستحل محل الدليل /app تمامًا في الحاوية الخاصة بك (وجميع محتوياته) ، ستحتاج إلى الحصول على ملف uwsgi.ini في دليل ./app الخاص بك مع:
[uwsgi]
module = main
callable = appوبعد ذلك يمكنك القيام برسم خرائط حجم Docker.
ملاحظة : يتم تضمين ملف uwsgi.ini في الأمثلة القابلة للتنزيل.
Dockerfile ودليل ./app الخاص بك)uwsgi.ini في دليل ./app الخاص بكdocker 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 الخاص بك ، يمكنك تشغيل الحاوية الخاصة بك التي تتجاوز الأمر الافتراضي (الذي يبدأ Supervisord والذي بدوره يبدأ 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يمكنك الآن تحرير رمز القارورة الخاص بك في جهازك المحلي وبمجرد تحديث متصفحك ، سترى التغييرات مباشرة.
تذكر أنه يجب عليك استخدام هذا فقط لتصحيح الأخطاء والتطوير ، للنشر في الإنتاج ، يجب ألا تقوم بتثبيت مجلدات ويجب أن تدع Supervisord تبدأ وتركها تبدأ UWSGI و NGINX (وهو ما يحدث افتراضيًا).
بديل لهذه الخطوات الأخيرة للعمل عندما لا يكون لديك حزمة ، ولكن مجرد بنية مسطحة مع ملفات مفردة (وحدات) ، يمكن أن يكون رمز قارورة Python الخاص بك هذا القسم مع:
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 .
وإذا كنت تستخدم إطار عمل SPA ، للسماح له بالتعامل مع عناوين URL في المتصفح ، يجب أن يكون رمز قارورة Python الخاص بك القسم مع:
# 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 وملفات الصور عند الطلب في عنوان URL للجذر ( / ) ولكن أيضًا يتأكد من أن سبا الواجهة الأمامية الخاصة بك يتعامل مع جميع عناوين URL الأخرى التي لم يتم تعريفها في تطبيق 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 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سترى بدء تشغيل خادم تصحيح الأخطاء ، سترى كيف يرسل ردود على كل طلب ، سترى الأخطاء التي يتم إلقاؤها عند كسر الرمز الخاص بك ، وكيف يوقفون الخادم الخاص بك ، وستتمكن من إعادة تشغيله بسرعة كبيرة ، عن طريق تشغيل الأمر أعلاه مرة أخرى.
يتم اختبار جميع علامات الصور والتكوينات ومتغيرات البيئة وخيارات التطبيق.
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.