داکرایز کردن Django و Nginx و Gunicorn به روش ساده

سلام و خسته نباشیداول از همه میخوام رک و روراست بگم چرا این پست رو نوشتم؛ حقیقتا من به تازگی دارم کار با داکر رو یاد می‌گیرم و وقتی تونستم یه پروژه رو داکرایز کنم خواستم اطلاعاتی که دارم رو به اشتراک بذارم که هم شاید تونستم به کسی برای یادگیری داکر انگیزه بدم و هم شاید اشخاصی که اطلاعات بیش‌تری در این حوزه دارن بتونن برای بهتر شدن کارم بهم نظری بدن و هم اینکه ذوقمو یه جایی تخلیه کنم =)))پیشنیاز‌هاآشنایی با فریمورک djangoآشنایی ابتدایی با nginxآشنایی ابتدایی با gunicornاصل کارخب خب بریم سراغ اصل کاراول از همه یه پوشه به نام dod می‌سازیم ( مخفف django on docker )هدفمون اینه که یک ایمیج داشته باشیم برای nginx که از پورت ۸۰ استفاده میکنه و ریکوئست ها رو هدایت بکنه. در کنارش یک ایمیج دیگه داشته باشیم برای جنگو و گونیکورن که ریکوئست ها رو با استفاده از شبکه داکر از nginx دریافت کنه و پردازش های لازم رو انجام بده و ریسپانس‌ها رو برگردونه.در همین جهت دو پوشه به نام های nginx و app می‌سازیم که اطلاعاتمون رو توی اونا قرار بدیم.mkdir dod && cd dod mkdir app && mkdir nginx && cd appابتدا از ساخت ایمیج جنگو و گونیکورن شروع می‌کنیم.پروژه‌ی جنگو رو می‌سازیم به نام prj.از این پروژه کافیه که اطلاعاتی از Settings.py رو به صورت متغیر محیطی دریافت کنیم؛ به همین دلیل خطوطی رو به شکل زیر تغییر می‌دیم:SECRET_KEY = os.environ.get(&quotSECRET_KEY&quot)DEBUG = bool(os.environ.get(&quotDEBUG&quot,default=0))ALLOWED_HOSTS = os.environ.get(&quotALLOWED_HOSTS&quot).split(&quot &quot)این اطلاعات به صورت متغیر محیطی تعریف می‌کنیم تا در ادامه برای ساخت ایمیج‌های مختلف از یک فایل لازم نباشه که توی کد دست ببریم و تنها تغییر اطلاعات توی Dockerfile کفایت بکنه.شما می‌توانید اطلاعات دیگه‌ای از قبیل اطلاعات اتصال به دیتابیس و... رو هم به صورت متغیر محیطی تعریف بکنید که فعلا توی این پست از این کار صرف نظر کردیم.الان باید فایل requirements.txt رو آماده کنیم و توی اون ماژول‌هایی که هنگام بیلد ایمیج نیاز هست رو بنویسیم، ما توی این مثال ساده تنها به این دو ماژول نیاز داریم :Django==3.0.4 gunicorn==19.9.0الان تنها کاری که باقی مونده نوشتن Dockerfile هست.خط به خط شروع به نوشتن می‌کنیم با هم :FROM python:3.8-alpineایمیج پایه ما ایمیج پایتون 3.8 هست. و این کار رو توسط دستورالعمل FROM توی خط اول انجام دادیم.در لایه بعدی متغیرهای محیطی را تعریف می‌کنیم :FROM python:3.8-alpine ENV SECRET_KEY 71)0c2pluviivk1!p93qouc_w017(#%x#g+2(*eo(0sf6h)vq3 ENV DEBUG 1 ENV ALLOWED_HOSTS webحالا نوبت به نصب ماژول های توی requirements.txt می‌رسه، برای این کار ابتدا فایل رو به درون کانتینر کپی می‌کنیم و سپس با استفاده از pip ماژول ها رو نصب میکنیم :FROM python:3.8-alpine ENV SECRET_KEY 71)0c2pluviivk1!p93qouc_w017(#%x#g+2(*eo(0sf6h)vq3 ENV DEBUG 1 ENV ALLOWED_HOSTS web COPY ./requirements.txt /home RUN pip install -r /home/requirements.txtبعد از اون تمامی پروژه ای که ساختیم رو به پوشه home درون کانتینر کپی میکنیم و محل کارمون (work directory ) رو پوشه پروژه منتقل می‌کنیم تا بتونیم پروژه اجرا کنیم.FROM python:3.8-alpine ENV SECRET_KEY 71)0c2pluviivk1!p93qouc_w017(#%x#g+2(*eo(0sf6h)vq3 ENV DEBUG 1 ENV ALLOWED_HOSTS web COPY ./requirements.txt /home RUN pip install -r /home/requirements.txt COPY . /home WORKDIR /home/prjبعد از همه این مراحل تنها کاری که می‌مونه اینه که دستورالعمل CMD رو اضافه بکنیم تا هنگام اجرای ایمیج پروژمون هم ران بشه:FROM python:3.8-alpine ENV SECRET_KEY 71)0c2pluviivk1!p93qouc_w017(#%x#g+2(*eo(0sf6h)vq3 ENV DEBUG 1 ENV ALLOWED_HOSTS web COPY ./requirements.txt /home RUN pip install -r /home/requirements.txt COPY . /home WORKDIR /home/prj CMD [&quotgunicorn&quot, &quot--bind&quot, &quot0.0.0.0:8080&quot, &quotprj.wsgi&quot]الان ساختار پروژه ما به این شکل هست :/home ├── requirements.txt ├── Dockerfile ├── prj ├── manage.py ├── prj │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.pyخب کارمون با ایمیج جنگو و گونیکورن فعلا تموم شده.میریم اطلاعات ایمیج nginx رو آماده می‌کنیم و بعد از اون ایمیج هامون رو بیلد میکنیم و بعدش هم اجرا میکنیم.وارد پوشه nginx بشید؛ برای استفاده از nginx تنها کافیه فایل های کانفیگ nginx رو جایگزین کانفیگ پیش‌فرض nginx بکنیم. برای این کار کافیه که فایل etc/nginx/conf.d/default.conf رو پاک کنیم و فایل کانفیگ خودمون رو به آدرس etc/nginx/conf.d کپی کنیم. پس داکرفایل ما به صورت زیر خواهد بود ( ایمیج پایه ما nginx:1.17.9 است. )FROM nginx:1.17.9 RUN rm /etc/nginx/conf.d/default.conf COPY mysite.conf /etc/nginx/conf.d/کانفیگ پروژه ما به چه شکل خواهد بود؟ با هم مینویسم :upstream web { server web1:8080; } server { listen 80; server_name localhost; location / { proxy_pass http://web; } }با این کانفیگ هر ریکوئستی که به سرور ما ارسال بشه به گروه سرورهای web توسط reverse proxy ارسال می‌شه و اطلاعات رو از اون سرور ها میگیره و برمی‌گردونه. و درون گروه سرورهای web ما تنها یک سرور تعریف کردیم به نام web1 ( نام ایمیج جنگو خودمون رو در ادامه برابر web1 قرار می‌دهیم ) تعریف کردیم که توسط پورت 8080 به آن متصل شدیم.حالا نوبت به بیلد و اجرای پروژه می‌رسه. برای بیلد از دستور های زیر استفاده می‌کنیم ( name:tag ) را با نام و تگ دلخواه خودتون جایگزین کنید :docker build -t name:tag app/ docker build -t name2:tag2 nginx/قبل از اجرای این ایمیج ها ما نیاز داریم که یک شبکه داکر بسازیم تا دو ایمیج ما از طریق این شبکه ها با هم در ارتباط باشند برای این کار از دستور زیر استفاده می‌کنیم :docker network create wnبا این دستور یک شبکه با درایور bridge به نام wn ساختیم. حالا کافیه که موقع اجرای ایمیج‌ها اونا رو عضو این شبکه کنیم.ابتدا ایمیج جنگو رو با دستور زیر ران میکنیم :docker run -itd --name web1 --network wn name:tagاگر به دستور بالا دقت کنید نام کانتینر رو برابر web1 قرار دادیم ( که بتونیم با کانتینر nginx از طریق شبکه داخلی بهش متصل بشیم )؛ همچنین کانتینر جنگو رو عضو شبکه wn کردیم.حال با دستور زیر کانتینر nginx رو ران میکنیم. مشابه فوق، با این تفاوت که پورت ۸۰ را پابلیش می‌کنیم تا بتونیم از طریق پروتکل http بهش دسترسی داشته باشیمdocker run -itd -p 80:80 --name nginx --network wn name2:tag2حالا می‌تونیم با وارد کردن آدرس 127.0.0.1 در مرورگر پروژه ران شده جنگو خودمون رو مشاهده کنیم.تامام تامام =))می‌تونید فایل‌های این پست رو به صورت کامل در این ریپوزیتوری ببینید =))منابعسایت dockerme.irبلاگ پستی مشابه به زبان انگلیسی در وبسایت testdriven.ioلازمه که تشکر کنم از آقای رفیعی و سایت خوبشون dockerme.ir که به یادگیری بنده کمک خیلی زیادی کردند.ممنونم از این که این پست رو مطالعه کردیدامیدوارم که براتون مفید باشه =))لایک و کامنت فراموش نشه...سوال یا نظری بود در خدمتم.نوشته شده با ❤️ توسط کوچیکتون حمیدرضا شجراوی =)))