How to run Django in Docker
ในการ run project ด้วย virtual enviroment แบบเดิมๆนั้นจะเป็นเพียงการแยก Python ออกมาจาก python หลักในเครื่องเท่านั้น แต่ environment อย่างอื่นก็ยังเหมือนเดิมดังภาพด้านล่างนะคับ ระหว่างการใช้ VM แบบเก่า, VE (ที่แยกเฉพาะ Python Bins & Libraries และ Docker Container
เรามาดูการ setup สำหรับ Django project กรณีใช้ Docker เลยดีกว่าครับ
- สร้าง folder projects และ test_docker ขึ้นมา
mkdir projects
mkdir test_docker
จากนั้นเปิด folder ขึ้นมาด้วย Editer อะไรก็ได้คับ (ผมใช้ Pycharm)
2. สร้าง files ขึ้นมา 3ไฟล์ ชื่อว่า Dockerfile, docker-compose.yml และ requirements.txt
touch Dockerfile
touch docker-compose.yml
touch requirements.txt
สำหรับ requirements.txt เราสามารถสั่งให้ gen แบบ auto ได้ด้วยคำสั่งด้านล่างนะคับ (แล้วค่อยมาตัด libs ที่ไม่ใช้ออกไป หรือจะสร้างแบบ manual ก็ได้และพิมพ์เพิ่มเข้าไปเอง)
pip freeze > requirements.txt
กรณีสร้างเอง ก็ให้เพิ่ม libs และ version ลงไปลักษณะนี้ แถวละ lib
Django==2.2
3. เขียน script สำหรับ Dockerfile (command ใน Dockerfile จะเป็นตัวพิมพ์ใหญ่)
FROM python:3
ENV PYTHONNBUFFERED 1
RUN mkdir /app
WORKDIR /app
COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY . /app/
4. เขียน script สำหรับ docker-compose.
docker-compose = script คำสั่งที่เอาไว้สร้าง Container หลายๆอันขึ้นมาพร้อมกัน โดยใช้คำสั่งเดียว (ดูวิธีใช้ได้จากคำสั่ง docker-compose)
version: '3'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8080
volumes:
- .:/app
ports:
- "8080:8080"
5. run คำสั่ง docker-compose ใน terminal เพื่อสร้าง project ขึ้นมา
docker-compose run web django-admin startproject mysite .
6. จากนั้นเราก็สามารถ สั่ง start containers ได้แล้วด้วยคำสั่ง
docker-compose up
เราสามารถดูว่ามี docker container อะไรบ้างที่กำลังรันอยู่โดยเปิด Terminal ใหม่และพิมพ์
docker ps
7. ในกรณีที่เราต้องการเพิ่ม app ใหม่ใน container ที่กำลังรันอยู่ สามารถทำได้แบบนี้
docker exec test_docker_web_1 python manage.py startapp greet
โดยที่
exec = คำสั่ง execute ที่ใช้กับ Container ที่กำลังใช้งานอยู่
test_docker_web_1 = ชื่อของ Container(เราต้อง mention ไปถึง)
python manage.py startapp greet = คำสั่งที่ใช้สร้าง new app in Django
จากนั้นเราจะได้ app ชื่อว่า “greet” ใน project ของเรา
8. ถ้าเราต้องการจะสร้าง api “hello” เพื่อเปิดหน้าเพจที่มีคำว่า “Hello Q” ขึ้นมาจะต้องสร้าง function ที่ greet/views.py
from django.shortcuts import render
from django.http import HttpResponse
def hello(request):
return HttpResponse("<h1>Hello Q</h1>")
9. จากนั้นให้สร้าง urls.py ขึ้นมาภายใต้ greet/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('hello', views.hello, name='hello')
]
10. ไปที่ urls.py ภายใต้ project “mysite” เพื่อผูก urls ทั้ง 2 จุดเข้าด้วยกัน
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('greet.urls'))
]
11. โดยปกติ docker ที่รันไว้จะ autorun อยู่แล้ว เมื่อเราพิมพ์ http://localhost:8080/hello ควรจะขึ้นหน้าจอ “Hello Q” ลักษณะนี้
แต่ถ้ายังไม่ขึ้นให้ stop docker แล้วสั่ง docker-compose up อีกครั้ง
ps: คำสั่งหลักๆของ Dockerfile 12 คำสั่ง ได้แก่
FROM : กำหนด Base image
LABEL : กำหนด Metadata เช่น ชือ version หรือ เจ้าของ Image
ENV : กำหนด Environment variable ภายใน Container
RUN : สำหรับติดตั้ง Package ให้ Container
COPY : copy files and folders to ContainerADD : copy files and folders to Container โดยสามารถแตกไฟล์ .tar รวมทั้งก๊อปปี้ไฟล์จาก Host ภายนอกได้CMD : สำหรับรันคำสั่งที่ต้องการ ขณะรัน Container
WORKDIR : กำหนด Working Directory ของ Container
ARG : กำหนด Variable ขณะสร้าง Image
ENTRYPOINT : สำหรับรันคำสั่งที่ต้องการขณะรัน Container
EXPOSE : กำหนด port ที่เปิดให้ Container อื่นติดต่อเข้ามา
VOLUME : สร้าง Folder เก็บข้อมูลแบบถาวรให้ Container
จบครับ ไว้พบกันใหม่ครับ
ps2: ถ้าจะใช้งาน database ก้ออย่าลืม makemigrations and migrate ด้วยนะคับ
docker exec test_docker_web_1 python manage.py makemigrations
docker exec test_docker_web_1 python manage.py migrate
docker exec -it test_docker_web_1 python manage.py createsuperuser# it = interactive ใช้เมื่อต้องการเข้า shell ใน docker
Ref:
https://www.youtube.com/watch?v=XDaQAmkDFX4&t=933s
https://sysadmin.psu.ac.th/2017/09/15/get-started-with-docker-part-7-manage-data/