Dockerfile masing -masingpython3.12 , latest (DockerFile)python3.11 , (Dockerfile)python3.10 (Dockerfile)python3.9 , (Dockerfile) Tag ini tidak lagi didukung atau dipelihara, mereka dihapus dari repositori GitHub, tetapi versi terakhir yang didorong mungkin masih tersedia di Docker Hub jika ada yang menariknya:
python3.8python3.8-alpinepython3.7python3.6python2.7Tag tanggal terakhir untuk versi ini adalah:
python3.8-2024-10-28python3.8-alpine-2024-03-11python3.7-2024-10-28python3.6-2022-11-25python2.7-2022-11-25 Catatan : Ada tag untuk setiap tanggal pembuatan. Jika Anda perlu "menyematkan" versi gambar Docker yang Anda gunakan, Anda dapat memilih salah satu tag tersebut. Misalnya tiangolo/uwsgi-nginx-flask:python3.7-2019-10-14 .
Gambar Docker dengan UWSGI dan Nginx untuk aplikasi web Flask di Python berjalan dalam satu wadah.
Gambar Docker ini memungkinkan Anda untuk membuat aplikasi web Flask di Python yang berjalan dengan UWSGI dan Nginx dalam satu wadah.
Kombinasi UWSGI dengan Nginx adalah cara umum untuk menggunakan aplikasi web Python Flask.
Jika Anda memulai proyek baru, Anda mungkin ingin mencoba Fastapi , yang saya buat, dan di mana saya menghabiskan sebagian besar waktu saya sekarang. Ini juga tidak memerlukan gambar dasar khusus, ada instruksi dalam dokumen untuk membangun Dockerfile Anda sendiri.
Github Repo : https://github.com/tiangolo/uwsgi-nginx-flask-docker
Gambar Hub Docker : https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask/
Anda mungkin menggunakan kubernet atau alat serupa. Dalam hal ini, Anda mungkin tidak memerlukan gambar ini (atau gambar dasar serupa lainnya). Anda mungkin lebih baik membangun gambar Docker dari awal .
Jika Anda memiliki sekelompok mesin dengan Kubernetes , Docker Swarm Mode, NOMAD, atau sistem kompleks serupa lainnya untuk mengelola wadah terdistribusi pada beberapa mesin, maka Anda mungkin ingin menangani replikasi pada level cluster alih -alih menggunakan manajer proses di setiap wadah yang memulai beberapa proses pekerja , yang merupakan apa yang dilakukan oleh gambar Docker ini.
Dalam kasus tersebut (misalnya menggunakan Kubernetes) Anda mungkin ingin membangun gambar Docker dari awal , memasang dependensi Anda, dan menjalankan satu proses alih -alih gambar ini.
Misalnya, menggunakan Gunicorn Anda bisa memiliki app/gunicorn_conf.py dengan:
# Gunicorn config variables
loglevel = "info"
errorlog = "-" # stderr
accesslog = "-" # stdout
worker_tmp_dir = "/dev/shm"
graceful_timeout = 120
timeout = 120
keepalive = 5
threads = 3 Dan kemudian Anda bisa memiliki Dockerfile dengan:
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" ]Anda dapat membaca lebih lanjut tentang ide -ide ini dalam dokumentasi FASTAPI tentang: FASTAPI dalam wadah - Docker karena ide -ide yang sama akan berlaku untuk aplikasi web lain dalam wadah.
Anda dapat menginginkan manajer proses yang menjalankan beberapa proses pekerja dalam wadah jika aplikasi Anda cukup sederhana sehingga Anda tidak perlu (setidaknya belum) untuk menyempurnakan jumlah proses terlalu banyak, dan Anda bisa menggunakan default otomatis, dan Anda menjalankannya pada satu server , bukan cluster.
Anda bisa digunakan ke server tunggal (bukan cluster) dengan Docker Compose , jadi Anda tidak akan memiliki cara mudah untuk mengelola replikasi wadah (dengan Docker Compose) sambil melestarikan jaringan bersama dan menyeimbangkan beban .
Maka Anda ingin memiliki satu wadah dengan manajer proses yang memulai beberapa proses pekerja di dalamnya, seperti gambar Docker ini.
Anda juga dapat memiliki alasan lain yang akan membuatnya lebih mudah untuk memiliki satu wadah dengan beberapa proses daripada memiliki beberapa wadah dengan satu proses di masing -masing.
Misalnya (tergantung pada pengaturan Anda), Anda dapat memiliki beberapa alat seperti Exporter Prometheus di wadah yang sama yang seharusnya memiliki akses ke masing -masing permintaan yang datang.
Dalam hal ini, jika Anda memiliki banyak kontainer , secara default, ketika Prometheus datang untuk membaca metrik , itu akan mendapatkan yang untuk satu wadah setiap kali (untuk wadah yang menangani permintaan tertentu), alih -alih mendapatkan metrik yang terakumulasi untuk semua wadah yang direplikasi.
Kemudian, dalam hal ini, bisa lebih sederhana untuk memiliki satu wadah dengan banyak proses , dan alat lokal (misalnya eksportir Prometheus) pada wadah yang sama yang mengumpulkan metrik Prometheus untuk semua proses internal dan memaparkan metrik tersebut pada wadah tunggal itu.
Baca lebih lanjut tentang semuanya dalam dokumentasi FastAPI tentang: Fastapi dalam wadah - Docker, karena konsep yang sama berlaku untuk aplikasi web lain dalam wadah.
Anda tidak perlu mengkloning repo ini.
Anda dapat menggunakan gambar ini sebagai gambar dasar untuk gambar lain.
Dengan asumsi Anda memiliki file requirements.txt , Anda dapat memiliki Dockerfile seperti ini:
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 /appAda beberapa tag gambar yang tersedia tetapi untuk proyek baru Anda harus menggunakan versi terbaru yang tersedia.
Gambar Docker ini didasarkan pada tiangolo/uwsgi-nginx . Gambar Docker itu memiliki UWSGI dan Nginx yang dipasang di wadah yang sama dan dibuat menjadi dasar gambar ini.
Dockerfile dengan: FROM tiangolo/uwsgi-nginx-flask:python3.12
COPY ./app /appapp dan masukkan di dalamnyamain.py (harus dinamai seperti itu dan harus ada di direktori app Anda) dengan: 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 ) Objek aplikasi utama harus dinamai app (dalam kode) seperti dalam contoh ini.
Catatan : Bagian dengan fungsi main() adalah untuk tujuan debugging. Untuk mempelajari lebih lanjut, baca instruksi lanjutan di bawah ini.
.
├── app
│ └── main.py
└── Dockerfile
Dockerfile Anda berada, berisi direktori app Anda)docker build -t myimage .docker run -d --name mycontainer -p 80:80 myimage... dan Anda memiliki server Flask yang dioptimalkan dalam wadah Docker.
Anda harus dapat memeriksanya di URL wadah Docker Anda, misalnya: http://192.168.99.100 atau http://127.0.0.1
Jika Anda sedang membangun aplikasi frontend modern (misalnya vue, bereaksi, sudut), Anda kemungkinan besar akan menyusun versi modern JavaScript (ES2015, TypeScript, dll) menjadi versi yang kurang modern, lebih kompatibel.
Jika Anda ingin menyajikan kode frontend (dikompilasi) Anda dengan wadah Docker backend (Flask) yang sama, Anda harus menyalin kode ke wadah setelah mengkompilasinya.
Itu berarti bahwa Anda perlu menginstal semua alat frontend pada mesin bangunan (mungkin komputer Anda, server jarak jauh, dll).
Itu juga berarti bahwa Anda harus, entah bagaimana, selalu ingat untuk mengkompilasi kode frontend tepat sebelum membangun gambar Docker.
Dan itu mungkin juga berarti bahwa Anda kemudian dapat menambahkan kode frontend yang dikompilasi ke repositori git Anda (semoga Anda sudah menggunakan git, atau belajar cara menggunakan git ).
Menambahkan kode yang dikompilasi ke git adalah ide yang sangat buruk karena beberapa alasan, beberapa di antaranya adalah:
Untuk alasan ini, tidak disarankan agar Anda melayani kode frontend Anda dari wadah Docker backend (Flask) yang sama.
Ada alternatif yang jauh lebih baik untuk melayani kode frontend Anda dari wadah Docker backend (Flask) yang sama.
Anda dapat memiliki wadah Docker lain dengan semua alat frontend terpasang (node.js, dll) itu:
Untuk mempelajari spesifik proses ini untuk bangunan frontend di Docker, Anda dapat membaca:
Setelah memiliki satu wadah backend (Flask) dan satu wadah frontend, Anda perlu menyajikan keduanya.
Dan Anda mungkin ingin melayani mereka di bawah domain yang sama, di bawah jalur yang berbeda. Misalnya, aplikasi backend (Flask) di PATH /api dan frontend di jalur "root" / .
Anda kemudian dapat menggunakan Traefik untuk menanganinya.
Dan itu juga dapat secara otomatis menghasilkan sertifikat HTTPS untuk aplikasi Anda menggunakan Let's Encrypt. Semua gratis, dalam pengaturan yang sangat mudah.
Jika Anda ingin menggunakan alternatif ini, periksa generator proyek di atas, mereka semua menggunakan ide ini.
Dalam skenario ini, Anda akan memiliki 3 wadah Docker:
Anda harus dapat mengikuti instruksi yang sama seperti di bagian " QuickStart " di atas, dengan beberapa modifikasi kecil:
app/ direktori, letakkan di app/app/ .__init__.py di dalam app/app/ direktori itu.uwsgi.ini di dalam app/ direktori Anda (yang disalin ke /app/uwsgi.ini di dalam wadah).uwsgi.ini Anda, tambahkan: [uwsgi]
module = app.main
callable = app Penjelasan uwsgi.ini adalah sebagai berikut:
app.main . Jadi, di app paket ( /app/app ), dapatkan modul main ( main.py ).app ( app = Flask(__name__) ).Struktur file Anda akan terlihat seperti:
.
├── app
│ ├── app
│ │ ├── __init__.py
│ │ ├── main.py
│ └── uwsgi.ini
└── Dockerfile
...alih-alih:
.
├── app
│ ├── main.py
└── Dockerfile
Jika Anda menggunakan file statis dalam wadah yang sama, pastikan variabel lingkungan STATIC_PATH diatur sesuai, misalnya untuk mengubah nilai default /app/static to /app/app/static Anda dapat menambahkan baris ini ke Dockerfile Anda:
ENV STATIC_PATH /app/app/static... Setelah itu, semuanya harus bekerja seperti yang diharapkan. Semua instruksi lain akan berlaku secara normal.
.
├── 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
Pastikan Anda mengikuti dokumen resmi saat mengimpor modul Anda:
Misalnya, jika Anda berada di app/app/main.py dan ingin mengimpor modul di app/app/core/app_setup.py Anda akan menulisnya seperti:
from . core import app_setupatau
from app . core import app_setupapp/app/api/endpoints/user.py dan Anda ingin mengimpor objek users dari app/app/core/database.py Anda akan menulisnya seperti: from ... core . database import usersatau
from app . core . database import users Anda dapat menyesuaikan beberapa hal menggunakan variabel lingkungan.
index.html secara langsungPerhatikan : Teknik ini sudah usang, karena dapat membuat beberapa masalah dengan kerangka kerja frontend modern. Untuk detail dan alternatif yang lebih baik, baca bagian di atas.
Mengatur variabel lingkungan STATIC_INDEX menjadi 1 Anda dapat mengonfigurasi nginx untuk melayani file dalam url /static/index.html saat diminta untuk / .
Itu akan meningkatkan kecepatan karena tidak akan melibatkan UWSGI atau Python. Nginx akan melayani file secara langsung. Untuk mempelajari lebih lanjut, ikuti bagian di atas " QuickStart untuk SPAS ".
Misalnya, untuk mengaktifkannya, Anda bisa menambahkan ini ke Dockerfile Anda:
ENV STATIC_INDEX 1Secara default, gambar dimulai dengan 2 proses UWSGI berjalan. Ketika server mengalami beban tinggi, itu membuat hingga 16 proses UWSGI untuk menanganinya sesuai permintaan.
Jika Anda perlu mengkonfigurasi angka -angka ini, Anda dapat menggunakan variabel lingkungan.
Jumlah awal proses UWSGI dikendalikan oleh variabel UWSGI_CHEAPER , secara default diatur ke 2 .
Jumlah maksimum proses UWSGI dikendalikan oleh variabel UWSGI_PROCESSES , secara default diatur ke 16 .
Perlu diingat bahwa UWSGI_CHEAPER harus lebih rendah dari UWSGI_PROCESSES .
Jadi, jika, misalnya, Anda harus memulai dengan 4 proses dan tumbuh hingga maksimal 64, Dockerfile Anda bisa terlihat seperti:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV UWSGI_CHEAPER 4
ENV UWSGI_PROCESSES 64
COPY ./app /app Anda dapat mengatur ukuran file unggahan maksimum kustom menggunakan variabel lingkungan NGINX_MAX_UPLOAD , secara default memiliki nilai 0 , yang memungkinkan ukuran file unggahan tanpa batas. Ini berbeda dari nilai default Nginx 1 MB. Ini dikonfigurasi dengan cara ini karena itulah pengalaman paling sederhana yang diharapkan oleh pengembang yang tidak berpengalaman di Nginx.
Misalnya, untuk memiliki ukuran file unggahan maksimum 1 MB (default nginx) Tambahkan baris di Dockerfile Anda dengan:
ENV NGINX_MAX_UPLOAD 1mSecara default, wadah yang dibuat dari gambar ini akan mendengarkan di port 80.
Untuk mengubah perilaku ini, atur variabel lingkungan LISTEN_PORT . Anda mungkin juga perlu membuat instruksi EXPOSE Docker masing -masing.
Anda dapat melakukannya di Dockerfile Anda, itu akan terlihat seperti:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV LISTEN_PORT 8080
EXPOSE 8080
COPY ./app /appuwsgi.ini Ada file default di /app/uwsgi.ini dengan konfigurasi spesifik aplikasi (di atas konfigurasi uwsgi global).
Itu hanya berisi:
[uwsgi]
module = main
callable = appmodule = main mengacu pada file main.pycallable = app mengacu pada "aplikasi" Flask , di app variabel. Anda dapat menyesuaikan uwsgi dengan mengganti file itu dengan milik Anda, termasuk semua konfigurasi Anda.
Misalnya, untuk memperluas yang default di atas dan mengaktifkan utas, Anda dapat memiliki file:
[uwsgi]
module = main
callable = app
enable-threads = trueuwsgi.ini Kustom Anda dapat mengganti di mana gambar harus mencari file aplikasi uwsgi.ini menggunakan variabel lingkungan UWSGI_INI .
Dengan itu Anda dapat mengubah direktori default untuk aplikasi Anda dari /app ke sesuatu yang lain, seperti /application .
Misalnya, untuk membuat gambar menggunakan file di /application/uwsgi.ini , Anda dapat menambahkan ini ke Dockerfile Anda:
ENV UWSGI_INI /application/uwsgi.ini
COPY ./application /application
WORKDIR /application Catatan : WORKDIR penting, jika tidak, UWSGI akan mencoba menjalankan aplikasi di /app .
Catatan : Anda juga harus mengkonfigurasi jalur file static , baca di bawah ini.
./static/ path Anda dapat membuat nginx menggunakan jalur direktori khusus dengan file untuk melayani secara langsung (tanpa terlibat UWSGI) dengan variabel lingkungan STATIC_PATH .
Misalnya, untuk membuat nginx melayani konten statis menggunakan file di /app/custom_static/ Anda dapat menambahkan ini ke Dockerfile Anda:
ENV STATIC_PATH /app/custom_static Kemudian, ketika browser meminta file di, misalnya, http://example.com/static/index.html, nginx akan menjawab langsung menggunakan file di path /app/custom_static/index.html .
Catatan : Anda juga harus mengkonfigurasi Flask untuk menggunakannya sebagai direktori static .
Sebagai contoh lain, jika Anda perlu meletakkan kode aplikasi Anda di direktori yang berbeda, Anda dapat mengonfigurasi NGINX untuk melayani file statis dari direktori yang berbeda itu.
Jika Anda perlu memiliki file statis di /application/static/ Anda dapat menambahkan ini ke Dockerfile Anda:
ENV STATIC_PATH /application/static/static Anda juga dapat membuat nginx melayani file statis dalam URL yang berbeda, untuk itu, Anda dapat menggunakan variabel lingkungan STATIC_URL .
Misalnya, jika Anda ingin mengubah URL /static ke /content Anda dapat menambahkan ini ke Dockerfile Anda:
ENV STATIC_URL /content Kemudian, ketika browser meminta file, misalnya, http://example.com/content/index.html, nginx akan menjawab langsung menggunakan file di path /app/static/index.html .
/app/prestart.sh Jika Anda perlu menjalankan apa pun sebelum memulai aplikasi, Anda dapat menambahkan file prestart.sh ke direktori /app . Gambar akan secara otomatis mendeteksi dan menjalankannya sebelum memulai semuanya.
Misalnya, jika Anda ingin menambahkan migrasi Alembic SQL (dengan SQLalchemy), Anda dapat membuat file ./app/prestart.sh di direktori kode Anda (yang akan disalin oleh Dockerfile Anda) dengan:
#! /usr/bin/env bash
# Let the DB start
sleep 10 ;
# Run migrations
alembic upgrade head Dan itu akan menunggu 10 detik untuk memberikan database waktu untuk memulai dan kemudian menjalankan perintah alembic itu.
Jika Anda perlu menjalankan skrip python sebelum memulai aplikasi, Anda dapat membuat file /app/prestart.sh menjalankan skrip python Anda, dengan sesuatu seperti:
#! /usr/bin/env bash
# Run custom Python script before starting
python /app/my_custom_prestart_script.py Catatan : Gambar menggunakan source untuk menjalankan skrip, jadi misalnya, variabel lingkungan akan bertahan. Jika Anda tidak memahami kalimat sebelumnya, Anda mungkin tidak membutuhkannya.
Secara default, Nginx akan memulai satu "proses pekerja".
Jika Anda ingin menetapkan jumlah proses pekerja Nginx yang berbeda, Anda dapat menggunakan variabel lingkungan, NGINX_WORKER_PROCESSES .
Anda dapat menggunakan nomor tunggal tertentu, misalnya:
ENV NGINX_WORKER_PROCESSES 2 Atau Anda dapat mengaturnya ke kata kunci auto dan akan mencoba mendeteksi secara otomatis jumlah CPU yang tersedia dan menggunakannya untuk jumlah pekerja.
Misalnya, menggunakan auto , DockerFile Anda bisa terlihat seperti:
FROM tiangolo/uwsgi-nginx-flask:python3.12
ENV NGINX_WORKER_PROCESSES auto
COPY ./app /appSecara default, Nginx akan mulai dengan batas maksimum 1024 koneksi per pekerja.
Jika Anda ingin mengatur nomor yang berbeda, Anda dapat menggunakan variabel lingkungan NGINX_WORKER_CONNECTIONS , misalnya:
ENV NGINX_WORKER_CONNECTIONS 2048Itu tidak dapat melebihi batas saat ini pada jumlah maksimum file terbuka. Lihat cara mengkonfigurasinya di bagian selanjutnya.
Koneksi angka per pekerja nginx tidak dapat melebihi batas pada jumlah maksimum file terbuka.
Anda dapat mengubah batas file terbuka dengan variabel lingkungan NGINX_WORKER_OPEN_FILES , misalnya:
ENV NGINX_WORKER_OPEN_FILES 2048 Jika Anda perlu mengkonfigurasi NGINX lebih lanjut, Anda dapat menambahkan file *.conf ke /etc/nginx/conf.d/ di Dockerfile Anda.
Cukup ingat bahwa konfigurasi default dibuat selama startup dalam file di /etc/nginx/conf.d/nginx.conf dan /etc/nginx/conf.d/upload.conf . Jadi Anda tidak boleh menimpanya. Anda harus memberi nama file *.conf Anda dengan sesuatu yang berbeda dari nginx.conf atau upload.conf , misalnya: custom.conf .
Catatan : Jika Anda menyesuaikan Nginx, mungkin menyalin konfigurasi dari blog atau jawaban stackoverflow, mengingat bahwa Anda mungkin perlu menggunakan konfigurasi khusus untuk UWSGI, bukannya untuk modul lain, seperti misalnya, ngx_http_fastcgi_module .
Jika Anda perlu mengkonfigurasi NGINX lebih jauh, sepenuhnya mengesampingkan default, Anda dapat menambahkan konfigurasi NGINX khusus ke /app/nginx.conf .
Ini akan disalin ke /etc/nginx/nginx.conf dan digunakan sebagai ganti yang dihasilkan.
Perlu diingat bahwa, dalam hal ini, gambar ini tidak akan menghasilkan konfigurasi NGINX apa pun, itu hanya akan menyalin dan menggunakan file konfigurasi Anda.
Itu berarti bahwa semua variabel lingkungan yang dijelaskan di atas yang spesifik untuk nginx tidak akan digunakan.
Ini juga berarti bahwa itu tidak akan menggunakan konfigurasi tambahan dari file di /etc/nginx/conf.d/*.conf , kecuali jika Anda secara eksplisit memiliki bagian dalam file khusus /app/nginx.conf dengan:
include /etc/nginx/conf.d/*.conf;
Jika Anda ingin menambahkan file custom /app/nginx.conf tetapi tidak tahu harus mulai dari mana, Anda dapat menggunakan nginx.conf yang digunakan untuk pengujian dan menyesuaikannya atau memodifikasinya lebih lanjut.
Kombinasi UWSGI dengan Nginx adalah cara umum untuk menggunakan aplikasi web Python Flask.
Dengan kasar:
Nginx adalah server web, ia menangani koneksi HTTP dan juga dapat menyajikan file statis secara langsung dan lebih efisien.
UWSGI adalah server aplikasi, itulah yang menjalankan kode Python Anda dan berbicara dengan Nginx.
Kode Python Anda memiliki aplikasi web Flask yang sebenarnya, dan dijalankan oleh UWSGI.
Gambar Tiangolo/UWSGI-NGINX mengambil keuntungan dari gambar Docker yang ramping dan dioptimalkan yang sudah ada (berdasarkan Debian seperti yang direkomendasikan oleh Docker) dan mengimplementasikan beberapa praktik terbaik Docker.
Ini menggunakan gambar Python Docker resmi, menginstal UWSGI dan di atasnya (dengan jumlah modifikasi paling sedikit) menambahkan gambar Nginx resmi.
Dan itu mengendalikan semua proses ini dengan pengawas.
Gambar (dan tag) yang dibuat oleh repo ini didasarkan pada gambar tiangolo/uwsgi-nginx . Gambar ini menambahkan flask dan default yang masuk akal di atasnya.
Jika Anda mengikuti instruksi dan menyimpan direktori /app root di dalam wadah Anda, dengan file bernama main.py dan objek Flask bernama app di dalamnya, itu harus "hanya berfungsi".
Sudah ada file uwsgi.ini di Direktori /app dengan konfigurasi UWSGI untuk "hanya bekerja". Dan semua parameter yang diperlukan lainnya ada di file uwsgi.ini lain di gambar, di dalam /etc/uwsgi/ .
Jika Anda perlu mengubah nama file utama atau objek Flask utama, Anda harus menyediakan file uwsgi.ini Anda sendiri. Anda dapat menggunakan yang ada di repo ini sebagai templat untuk memulai (dan Anda hanya harus mengubah 2 baris yang sesuai).
Anda dapat memiliki A /app/static dan file -file tersebut akan secara efisien dilayani oleh Nginx secara langsung (tanpa melalui kode Flask Anda atau bahkan UWSGI), sudah dikonfigurasi untuk Anda. Tetapi Anda dapat mengonfigurasinya lebih lanjut menggunakan variabel lingkungan (dibaca di atas).
Supervisord menangani menjalankan UWSGI dengan file uwsgi.ini di /app (termasuk juga file di /etc/uwsgi/uwsgi.ini ) dan mulai nginx.
Ada aturan praktis yang harus Anda miliki "satu proses per kontainer".
Itu membantu, misalnya, mengisolasi aplikasi dan basis data dalam wadah yang berbeda.
Tetapi jika Anda ingin memiliki pendekatan "layanan mikro", Anda mungkin ingin memiliki lebih dari satu proses dalam satu wadah jika semuanya terkait dengan "layanan" yang sama, dan Anda mungkin ingin memasukkan kode Flask Anda, UWSGI dan Nginx dalam wadah yang sama (dan mungkin menjalankan wadah lain dengan database Anda).
Itulah pendekatan yang diambil dalam gambar ini.
Gambar ini (dan tag) memiliki beberapa file default, jadi jika Anda menjalankannya dengan sendirinya (bukan sebagai gambar dasar dari proyek Anda sendiri) Anda akan melihat aplikasi web "Hello World" default.
Saat Anda membangun Dockerfile dengan COPY ./app /app Anda mengganti file default dengan kode aplikasi Anda.
File default utama hanya di /app/main.py . Dan dalam kasus tag dengan -index , juga di /app/static/index.html .
Tetapi file -file itu membuat teks "(default)" di halaman web yang disajikan, sehingga Anda dapat memeriksa apakah Anda melihat kode default atau kode Anda sendiri yang menimpa default.
Kode aplikasi Anda harus ada di direktori wadah /app , harus memiliki file main.py dan file main.py harus memiliki app objek Flask.
Jika Anda mengikuti instruksi di atas atau menggunakan salah satu templat contoh yang dapat diunduh, Anda harus baik -baik saja.
Ada juga file /app/uwsgi.ini di dalam gambar dengan parameter default untuk UWSGI.
Contoh yang dapat diunduh termasuk salinan file uwsgi.ini yang sama untuk tujuan debugging. Untuk mempelajari lebih lanjut, baca " instruksi pengembangan lanjutan " di bawah ini.
Saat berkembang, Anda mungkin ingin membuat direktori kode Anda volume di wadah Docker Anda.
Dengan itu Anda akan memiliki file (sementara) diperbarui setiap kali Anda memodifikasinya, tanpa perlu membangun wadah Anda lagi.
Untuk melakukan ini, Anda dapat menggunakan perintah pwd (Cetak Direktori Kerja) di dalam docker run Anda dan bendera -v untuk volume.
Dengan itu Anda dapat memetakan direktori ./app Anda ke direktori wadah /app Anda.
Tetapi pertama -tama, karena Anda akan sepenuhnya mengganti direktori /app di wadah Anda (dan semua isinya) Anda harus memiliki file uwsgi.ini di direktori ./app Anda dengan:
[uwsgi]
module = main
callable = appDan kemudian Anda dapat melakukan pemetaan volume Docker.
Catatan : File uwsgi.ini termasuk dalam contoh yang dapat diunduh.
Dockerfile Anda dan direktori ./app Anda)uwsgi.ini di direktori ./app Andadocker build -t myimage ../app ) ke direktori wadah /app Anda: docker run -d --name mycontainer -p 80:80 -v $( pwd ) /app:/app myimage Jika Anda pergi ke URL wadah Docker Anda, Anda akan melihat aplikasi Anda, dan Anda harus dapat memodifikasi file di ./app/static/ dan melihat perubahan yang tercermin di browser Anda hanya dengan memuat ulang.
... Tapi, karena UWSGI memuat seluruh aplikasi web Python Flask Anda setelah dimulai, Anda tidak akan dapat mengedit kode Python Flask Anda dan melihat perubahan tercermin.
Untuk dapat (sementara) men -debug kode Flask Python Anda secara langsung, Anda dapat menjalankan wadah Anda yang menimpa perintah default (yang memulai pengawas yang pada gilirannya dimulai UWSGI dan Nginx) dan menjalankan aplikasi Anda secara langsung dengan python , dalam mode debug, menggunakan perintah flask dengan variabel lingkungannya.
Jadi, dengan semua modifikasi di atas dan membuat aplikasi Anda dijalankan langsung dengan flask , perintah Docker terakhir adalah:
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 Atau dalam kasus proyek paket, Anda akan mengatur 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=80Sekarang Anda dapat mengedit kode Flask di mesin lokal Anda dan setelah Anda menyegarkan browser Anda, Anda akan melihat perubahannya secara langsung.
Ingatlah bahwa Anda harus menggunakan ini hanya untuk debugging dan pengembangan, untuk penyebaran dalam produksi Anda tidak boleh memasang volume dan Anda harus membiarkan pengawas memulai dan membiarkannya memulai UWSGI dan Nginx (yang terjadi secara default).
Alternatif untuk langkah -langkah terakhir ini untuk bekerja ketika Anda tidak memiliki paket, tetapi hanya struktur datar dengan file tunggal (modul), kode Flask Python Anda dapat memiliki bagian itu dengan:
if __name__ == "__main__" :
# Only for debugging while developing
app . run ( host = '0.0.0.0' , debug = True , port = 80 ) ... dan Anda bisa menjalankannya dengan python main.py Tapi itu hanya akan berhasil ketika Anda tidak menggunakan struktur paket dan tidak berencana untuk melakukannya nanti. Dalam kasus tertentu, jika Anda tidak menambahkan blok kode di atas, aplikasi Anda hanya akan mendengarkan localhost (di dalam wadah), di port lain (5000) dan tidak dalam mode debug.
Juga, jika Anda ingin melakukan debugging langsung yang sama menggunakan variabel lingkungan STATIC_INDEX=1 (untuk melayani /app/static/index.html secara langsung ketika diminta untuk / ) nginx Anda tidak akan melayani secara langsung karena tidak akan berjalan (hanya aplikasi python flask Anda dalam mode debug yang akan berjalan).
from flask import Flask , send_fileDan
@ app . route ( '/' )
def route_root ():
index_path = os . path . join ( app . static_folder , 'index.html' )
return send_file ( index_path ) ... Itu memastikan aplikasi Anda juga melayani file /app/static/index.html bila diminta untuk / . Atau jika Anda menggunakan struktur paket, file /app/main/static/index.html .
Dan jika Anda menggunakan kerangka kerja spa, untuk mengizinkannya menangani URL di browser, kode Flask Python Anda harus memiliki bagian dengan:
# 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 ) ... Itu membuat Flask mengirim semua file CSS, JavaScript dan gambar saat diminta di URL root ( / ) tetapi juga memastikan bahwa frontend spa Anda menangani semua URL lain yang tidak ditentukan dalam aplikasi Flask Anda.
Begitulah cara ditulis dalam tutorial di atas dan termasuk dalam contoh yang dapat diunduh.
Jika Anda mengikuti instruksi di atas, kemungkinan pada titik tertentu, Anda akan menulis kode yang akan merusak server debugging Flask Anda dan itu akan macet.
Dan karena satu -satunya proses yang berjalan adalah server debugging Anda, yang sekarang dihentikan, wadah Anda akan berhenti.
Maka Anda harus memulai wadah Anda lagi setelah memperbaiki kode Anda dan Anda tidak akan melihat dengan sangat mudah apa kesalahan yang menghancurkan server Anda.
Jadi, saat berkembang, Anda bisa melakukan hal berikut (itulah yang biasanya saya lakukan, meskipun saya melakukannya dengan Docker Compose, seperti dalam contoh proyek):
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 Anda sekarang akan berada di dalam wadah Anda di direktori /app .
flask run --host=0.0.0.0 --port=80Anda akan melihat server debugging Flask Anda dimulai, Anda akan melihat bagaimana ia mengirimkan tanggapan ke setiap permintaan, Anda akan melihat kesalahan yang dilemparkan ketika Anda memecahkan kode, dan bagaimana mereka menghentikan server Anda, dan Anda akan dapat memulai kembali dengan sangat cepat, hanya dengan menjalankan perintah di atas lagi.
Semua tag gambar, konfigurasi, variabel lingkungan dan opsi aplikasi diuji.
issue-manager.yml . PR #385 oleh @Tiangolo.latest-changes . PR #360 oleh @Tiangolo.latest-changes.yml . PR #348 oleh @alejsdev.README.md . PR #346 oleh @alejsdev. Sorotan rilis ini:
python3.6-2022-11-25 dan 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.