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 Image กับ UWSGI และ NGINX สำหรับ Flask Web Applications ใน Python ที่ทำงานในคอนเทนเนอร์เดียว
ภาพ นักเทียบ ท่านี้ช่วยให้คุณสร้างแอปพลิเคชันเว็บ 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 หรือเครื่องมือที่คล้ายกัน ในกรณีนี้คุณอาจ ไม่ต้องการภาพนี้ (หรือ ภาพฐานอื่น ๆ ที่คล้ายกัน ) คุณน่าจะดีกว่าใน การสร้างภาพนักเทียบท่าตั้งแต่เริ่มต้น
หากคุณมีกลุ่มเครื่องจักรที่มี Kubernetes , Docker Swarm Mode, Nomad หรือระบบที่ซับซ้อนอื่น ๆ ที่คล้ายกันเพื่อจัดการคอนเทนเนอร์แบบกระจายในหลายเครื่องคุณอาจต้องการ จัดการการจำลองแบบ ที่ ระดับคลัสเตอร์ แทนที่จะใช้ตัว จัดการ กระบวนการ ในแต่ละคอนเทนเนอร์
ในกรณีเหล่านั้น (เช่นการใช้ Kubernetes) คุณอาจต้องการสร้าง อิมเมจนักเทียบท่าตั้งแต่เริ่มต้น การติดตั้งการพึ่งพาของคุณและเรียกใช้ กระบวนการเดียว แทนภาพนี้
ตัวอย่างเช่นการใช้ 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 ดังนั้นคุณจะไม่มีวิธีที่ง่ายในการจัดการการจำลองแบบของคอนเทนเนอร์ (พร้อม Docker Compose) ในขณะที่รักษาเครือข่ายที่ ใช้ ร่วมกัน
จากนั้นคุณอาจต้องการมี คอนเทนเนอร์เดียว ที่มี ตัวจัดการกระบวนการ เริ่มต้น กระบวนการของคนงานหลายอย่าง ภายในเช่นเดียวกับภาพนักเทียบท่านี้
คุณอาจมี เหตุผลอื่น ๆ ที่จะทำให้ง่ายขึ้นที่จะมี คอนเทนเนอร์เดียว ที่มี หลายกระบวนการ แทนที่จะมี คอนเทนเนอร์หลายตัว ที่มี กระบวนการเดียว ในแต่ละอัน
ตัวอย่างเช่น (ขึ้นอยู่กับการตั้งค่าของคุณ) คุณอาจมีเครื่องมือบางอย่างเช่นผู้ส่งออก Prometheus ในคอนเทนเนอร์เดียวกันกับที่ควรเข้าถึง คำขอแต่ละคำขอ ที่มา
ในกรณีนี้หากคุณมี คอนเทนเนอร์หลายตัว โดยค่าเริ่มต้นเมื่อ Prometheus มา อ่านตัวชี้วัด มันจะได้รับ คอนเทนเนอร์เดียวในแต่ละครั้ง (สำหรับคอนเทนเนอร์ที่จัดการคำขอนั้น) แทนที่จะได้รับ การวัดสะสม สำหรับภาชนะที่จำลองทั้งหมด
จากนั้นในกรณีนั้นอาจง่ายกว่าที่จะมี คอนเทนเนอร์หนึ่งอัน ที่มี หลายกระบวนการ และเครื่องมือท้องถิ่น (เช่นผู้ส่งออกโพร) ในคอนเทนเนอร์เดียวกันที่รวบรวมตัวชี้วัดโพรโพรสำหรับกระบวนการภายในทั้งหมดและเปิดเผยตัวชี้วัดเหล่านั้นในภาชนะเดียวนั้น
อ่านเพิ่มเติมเกี่ยวกับมันทั้งหมดในเอกสาร Fastapi เกี่ยวกับ: fastapi ในคอนเทนเนอร์ - Docker เป็นแนวคิดเดียวกันนี้ใช้กับเว็บแอปพลิเคชันอื่น ๆ ในคอนเทนเนอร์
คุณไม่ต้องโคลน repo นี้
คุณสามารถใช้ภาพนี้เป็นภาพพื้นฐานสำหรับภาพอื่น ๆ
สมมติว่าคุณมี 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มีแท็กรูปภาพหลายรายการ แต่สำหรับโครงการใหม่ที่คุณควรใช้เวอร์ชันล่าสุดที่มีอยู่
ภาพนักเทียบท่านี้ขึ้นอยู่กับ tiangolo/uwsgi-nginx อิมเมจนักเทียบท่านั้นมี 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.1
หากคุณกำลังสร้างแอพพลิเคชั่นส่วนหน้าแบบทันสมัย (เช่น Vue, React, Angular) คุณอาจจะรวบรวม JavaScript เวอร์ชันที่ทันสมัย (ES2015, typeScript, ฯลฯ ) เป็นรุ่นที่ทันสมัยน้อยกว่าและเข้ากันได้
หากคุณต้องการให้บริการรหัสส่วนหน้า (คอมไพล์) ของคุณโดยคอนเทนเนอร์ Docker แบ็กเอนด์ (Flask) เดียวกันคุณจะต้องคัดลอกรหัสไปยังคอนเทนเนอร์หลังจากรวบรวม
นั่นหมายความว่าคุณจะต้องมีเครื่องมือส่วนหน้าทั้งหมดที่ติดตั้งบนเครื่องอาคาร (อาจเป็นคอมพิวเตอร์ของคุณเซิร์ฟเวอร์ระยะไกล ฯลฯ )
นั่นก็หมายความว่าคุณจะต้องจำไว้เสมอว่าจะรวบรวมรหัสส่วนหน้าก่อนที่จะสร้างภาพนักเทียบท่า
และอาจหมายความว่าคุณสามารถเพิ่มรหัสส่วนหน้าคอมไพล์ของคุณลงในพื้นที่เก็บข้อมูล git ของคุณ (หวังว่าคุณจะใช้ GIT อยู่แล้วหรือเรียนรู้วิธีใช้ git )
การเพิ่มรหัสที่รวบรวมไว้ใน Git เป็นความคิดที่แย่มากด้วยเหตุผลหลายประการบางอย่างคือ:
ด้วยเหตุผลเหล่านี้จึงไม่แนะนำให้คุณใช้รหัสส่วนหน้าจากคอนเทนเนอร์ Docker แบ็กเอนด์ (Flask) เดียวกัน
มีทางเลือกที่ดีกว่ามากในการให้บริการรหัสส่วนหน้าของคุณจากคอนเทนเนอร์ Docker (Flask) Backend (Flask) เดียวกัน
คุณสามารถมีคอนเทนเนอร์ Docker อื่นที่มีเครื่องมือส่วนหน้าทั้งหมดที่ติดตั้ง (node.js ฯลฯ ) ที่:
เพื่อเรียนรู้ข้อมูลเฉพาะของกระบวนการนี้สำหรับการสร้างส่วนหน้าใน Docker คุณสามารถอ่านได้:
หลังจากมีคอนเทนเนอร์แบ็กเอนด์ (Flask) หนึ่งอันและคอนเทนเนอร์ส่วนหน้าหนึ่งคุณต้องให้บริการทั้งสองอย่าง
และคุณอาจต้องการให้บริการภายใต้โดเมนเดียวกันภายใต้เส้นทางที่แตกต่างกัน ตัวอย่างเช่นแอพแบ็กเอนด์ (ขวด) ที่ Path /api และส่วนหน้าที่เส้นทาง "รูท" /
จากนั้นคุณสามารถใช้ traefik เพื่อจัดการสิ่งนั้น
และยังสามารถสร้างใบรับรอง HTTPS โดยอัตโนมัติสำหรับแอปพลิเคชันของคุณโดยใช้ Let's encrypt ทั้งหมดฟรีในการตั้งค่าที่ง่ายมาก
หากคุณต้องการใช้ทางเลือกนี้ให้ตรวจสอบเครื่องกำเนิดไฟฟ้าด้านบนพวกเขาทั้งหมดใช้ความคิดนี้
ในสถานการณ์นี้คุณจะมีคอนเทนเนอร์ Docker 3 ตัว:
คุณควรจะสามารถทำตามคำแนะนำเดียวกันกับในส่วน " quickstart " ด้านบนโดยมีการแก้ไขเล็กน้อย:
app/ ไดเรกทอรีให้ใส่ใน 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 แพ็คเกจ ( /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 เป็น /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 ที่ทำงานอยู่ เมื่อเซิร์ฟเวอร์กำลังรับภาระสูงจะสร้างกระบวนการ UWSGI สูงสุด 16 กระบวนการเพื่อจัดการกับความต้องการ
หากคุณต้องการกำหนดค่าตัวเลขเหล่านี้คุณสามารถใช้ตัวแปรสภาพแวดล้อม
จำนวนเริ่มต้นของกระบวนการ 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 MB มันได้รับการกำหนดค่าด้วยวิธีนี้เพราะนั่นเป็นประสบการณ์ที่ง่ายที่สุดที่นักพัฒนาที่ไม่มีประสบการณ์ใน Nginx จะคาดหวัง
ตัวอย่างเช่นการมีขนาดไฟล์อัปโหลดสูงสุด 1 MB (ค่าเริ่มต้นของ Nginx) เพิ่มบรรทัดใน Dockerfile ของคุณด้วย:
ENV NGINX_MAX_UPLOAD 1mโดยค่าเริ่มต้นคอนเทนเนอร์ที่ทำจากภาพนี้จะฟังบนพอร์ต 80
หากต้องการเปลี่ยนพฤติกรรมนี้ให้ตั้งค่าตัวแปรสภาพแวดล้อม LISTEN_PORT คุณอาจต้องสร้างคำแนะนำที่เกี่ยวข้อง EXPOSE Docker
คุณสามารถทำได้ใน 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/ path คุณสามารถทำให้ 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
หมายเหตุ : คุณจะต้องกำหนดค่า 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 จะไม่ถูกนำมาใช้
นอกจากนี้ยังหมายความว่าจะไม่ใช้การกำหนดค่าเพิ่มเติมจากไฟล์ใน /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 ใช้ประโยชน์จากภาพที่มีอยู่แล้วที่มีอยู่แล้วที่มีอยู่แล้ว (ตาม Debian ตามที่นักเทียบท่าแนะนำ) และใช้แนวทางปฏิบัติที่ดีที่สุดของ Docker หลายแห่ง
มันใช้อิมเมจ Python Docker อย่างเป็นทางการติดตั้ง UWSGI และยิ่งไปกว่านั้น (ด้วยการแก้ไขจำนวนน้อยที่สุด) จะเพิ่มภาพ Nginx อย่างเป็นทางการ
และมันควบคุมกระบวนการเหล่านี้ทั้งหมดด้วยการควบคุมดูแล
ภาพ (และแท็ก) ที่สร้างขึ้นโดย repo นี้ขึ้นอยู่กับภาพ tiangolo/uwsgi-nginx ภาพนี้เพิ่มขวดและค่าเริ่มต้นที่เหมาะสมที่ด้านบนของมัน
หากคุณทำตามคำแนะนำและเก็บไดเรกทอรีรูท /app ไว้ในคอนเทนเนอร์ของคุณด้วยไฟล์ชื่อ main.py และวัตถุขวดที่ชื่อ app ในนั้นมันควร "แค่ทำงาน"
มีไฟล์ uwsgi.ini อยู่แล้วในไดเรกทอรี /app ด้วยการกำหนดค่า UWSGI สำหรับ "แค่ทำงาน" และพารามิเตอร์ที่จำเป็นอื่น ๆ ทั้งหมดอยู่ในไฟล์ uwsgi.ini อื่นในภาพภายใน /etc/uwsgi/
หากคุณต้องการเปลี่ยนชื่อไฟล์หลักหรือวัตถุขวดหลักคุณจะต้องระบุไฟล์ uwsgi.ini ของคุณเอง คุณอาจใช้หนึ่งใน repo นี้เป็นเทมเพลตที่จะเริ่มต้นด้วย (และคุณจะต้องเปลี่ยน 2 บรรทัดที่สอดคล้องกัน)
คุณสามารถมี A /app/static และไฟล์เหล่านั้นจะได้รับการบริการอย่างมีประสิทธิภาพโดย 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
แต่ไฟล์เหล่านั้นแสดงข้อความ "(ค่าเริ่มต้น)" ในหน้าเว็บที่ให้บริการเพื่อให้คุณสามารถตรวจสอบได้ว่าคุณเห็นรหัสเริ่มต้นหรือรหัสของคุณเองที่แทนที่ค่าเริ่มต้นหรือไม่
รหัสแอพของคุณควรอยู่ในไดเรกทอรี /app ของคอนเทนเนอร์ควรมีไฟล์ main.py และไฟล์ main.py ควรมี app วัตถุขวด
หากคุณทำตามคำแนะนำข้างต้นหรือใช้เทมเพลตตัวอย่างที่ดาวน์โหลดได้อย่างใดอย่างหนึ่งคุณควรจะโอเค
นอกจากนี้ยังมีไฟล์ /app/uwsgi.ini ภายในรูปภาพด้วยพารามิเตอร์เริ่มต้นสำหรับ UWSGI
ตัวอย่างที่ดาวน์โหลดได้รวมถึงสำเนาของไฟล์ uwsgi.ini เดียวกันเพื่อจุดประสงค์ในการดีบัก หากต้องการเรียนรู้เพิ่มเติมอ่าน " คำแนะนำการพัฒนาขั้นสูง " ด้านล่าง
ในขณะที่กำลังพัฒนาคุณอาจต้องการทำให้ไดเรกทอรีรหัสของคุณมีปริมาณในคอนเทนเนอร์ Docker ของคุณ
เมื่อคุณมีการอัปเดตไฟล์ (ชั่วคราว) ทุกครั้งที่คุณแก้ไขโดยไม่จำเป็นต้องสร้างคอนเทนเนอร์ของคุณอีกครั้ง
ในการทำเช่นนี้คุณสามารถใช้คำสั่ง 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/ static/ และดูการเปลี่ยนแปลงเหล่านั้นที่สะท้อนในเบราว์เซอร์ของคุณเพียงแค่โหลดซ้ำ
... แต่เมื่อ UWSGI โหลดแอปพลิเคชันเว็บ Python Flask ทั้งหมดของคุณเมื่อเริ่มต้นคุณจะไม่สามารถแก้ไขรหัส Python Flask ของคุณและดูการเปลี่ยนแปลงที่สะท้อนได้
เพื่อให้สามารถ (ชั่วคราว) ดีบั๊กโค้ด Python Flask Live ของคุณคุณสามารถเรียกใช้คอนเทนเนอร์ของคุณเอาชนะคำสั่งเริ่มต้น (ซึ่งเริ่มการควบคุมซึ่งจะเริ่ม UWSGI และ NGINX) และเรียกใช้แอป flask เคชันของคุณโดยตรงด้วย python ในโหมดดีบัก
ดังนั้นด้วยการดัดแปลงทั้งหมดข้างต้นและทำให้แอปของคุณทำงานโดยตรงด้วย 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ตอนนี้คุณสามารถแก้ไขรหัสขวดของคุณในเครื่องในเครื่องของคุณและเมื่อคุณรีเฟรชเบราว์เซอร์ของคุณคุณจะเห็นการเปลี่ยนแปลงสด
โปรดจำไว้ว่าคุณควรใช้สิ่งนี้สำหรับการดีบักและการพัฒนาเท่านั้นสำหรับการปรับใช้ในการผลิตคุณไม่ควรติดตั้งปริมาณและคุณควรปล่อยให้การควบคุมดูแลเริ่มต้นและปล่อยให้มันเริ่ม UWSGI และ NGINX (ซึ่งเป็นสิ่งที่เกิดขึ้นตามค่าเริ่มต้น)
อีกทางเลือกหนึ่งสำหรับขั้นตอนสุดท้ายในการทำงานเมื่อคุณไม่มีแพ็คเกจ แต่เพียงโครงสร้างแบนที่มีไฟล์เดียว (โมดูล) รหัสขวดหลามของคุณอาจมีส่วนนั้นด้วย:
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) ... และคุณสามารถเรียกใช้กับ python main.py แต่นั่นจะใช้ได้เฉพาะเมื่อคุณไม่ได้ใช้โครงสร้างแพ็คเกจและไม่วางแผนที่จะทำในภายหลัง ในกรณีที่เฉพาะเจาะจงนั้นหากคุณไม่ได้เพิ่มบล็อกรหัสด้านบนแอปของคุณจะฟังเฉพาะ localhost (ภายในคอนเทนเนอร์) ในพอร์ตอื่น (5,000) และไม่ได้อยู่ในโหมดดีบัก
นอกจากนี้หากคุณต้องการทำการดีบักสดแบบเดียวกันโดยใช้ตัวแปรสภาพแวดล้อม STATIC_INDEX=1 (เพื่อให้บริการ /app/static/index.html โดยตรงเมื่อร้องขอ / ) nginx ของคุณจะไม่ให้บริการโดยตรงเพราะมันจะไม่ทำงาน
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
และถ้าคุณใช้เฟรมเวิร์กสปาเพื่อให้สามารถจัดการ URL ในเบราว์เซอร์รหัสขวดหลามของคุณควรมีส่วนด้วย:
# 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 รูท ( / ) แต่ยังทำให้แน่ใจว่า Frontend Spa ของคุณจัดการ URL อื่น ๆ ทั้งหมดที่ไม่ได้กำหนดไว้ในแอพ Flask ของคุณ
นั่นคือวิธีที่เขียนไว้ในบทช่วยสอนด้านบนและรวมอยู่ในตัวอย่างที่ดาวน์โหลดได้
หากคุณทำตามคำแนะนำข้างต้นอาจเป็นไปได้ว่าในบางจุดคุณจะเขียนโค้ดที่จะทำลายเซิร์ฟเวอร์ดีบั๊กของคุณและมันจะพัง
และเนื่องจากกระบวนการที่รันเพียงอย่างเดียวคือเซิร์ฟเวอร์การดีบักของคุณตอนนี้หยุดลงคอนเทนเนอร์ของคุณจะหยุด
จากนั้นคุณจะต้องเริ่มคอนเทนเนอร์ของคุณอีกครั้งหลังจากแก้ไขรหัสของคุณและคุณจะไม่เห็นข้อผิดพลาดที่เกิดขึ้นกับเซิร์ฟเวอร์ของคุณ
ดังนั้นในขณะที่การพัฒนาคุณสามารถทำสิ่งต่อไปนี้ (นั่นคือสิ่งที่ฉันทำตามปกติแม้ว่าฉันจะทำกับนักเทียบท่าเขียนเช่นเดียวกับในตัวอย่างโครงการ):
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 โดย @tiangololatest-changes ของ GitHub PR #360 โดย @tiangololatest-changes.yml PR #348 โดย @alejsdevREADME.md PR #346 โดย @alejsdev ไฮไลท์ของรุ่นนี้:
python3.6-2022-11-25 และ python2.7-2022-11-251.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.