ในบทความนี้จะเกี่ยวข้องกับการใช้งาน Docker ร่วมกับ Django แบบเบื้องต้น ซึ่งทั้งตัว Django และตัวของ Docker เองแน่นอนว่าเป็นสิ่งที่น่าสนใจทั้งคู่ เมื่อนำทั้งสองอย่างมาใช้งานร่วมกันก็จะช่วยให้ process การทำงานเป็นไปได้อย่างลื่นไหลมากขึ้นเนื่องจากจะทำให้โค้ดที่พัฒนาอยู่เข้าใกล้ความเป็น production มากขึ้นนั่นเอง และบทความนี้เราจะมาเรียนรู้กันเรื่องของการใช้งาน Docker ร่วมกับ Django ใน Development Mode กันก่อน (หมายถึงตอนที่กำลังเขียนโค้ดอยู่) เพื่อความง่าย และจะยังไม่ได้เอาไป deploy กันจริงๆ เอาไว้เดี๋ยวรอบทความถัดๆไปครับ
มารู้จักกันก่อนว่าอะไรเอ่ยคือ Docker ถ้าพูดถึง Docker แล้วหลายๆคนน่าจะนึกถึงภาพของวาฬน่ารักๆตัวนึงซึ่งกำลังขน container กันอยู่ใช่มั้ยครับ สิ่งที่เรามักจะใช้ Docker ทำกันคือการทำสิ่งที่เรียกว่า Container ซึ่งมันคืออะไรกันเนี่ย เดี๋ยวเรามาเล่าถึงประวัติศาสตร์ของโลกของการ deploy สิ่งต่างๆกันก่อน ยุคแรกสุดเลยเวลาเราจะ deploy อะไรก็ตามนี่เราก็จะต้องมีเซิฟเวอร์เป็นของตัวเองก่อนครับ คือต้องซื้อเครื่องมาเลยเครื่องนึง จากนั้นก็ไปทำการ config ต่างๆ setup บลาๆ ซึ่งทำให้มันสามารถเชื่อมต่อกับโลกของอินเตอร์เน็ตได้
Docker (Photo: docker.com)
แน่นอนแหละครับว่าการมีเซิฟเวอร์เป็นของตัวเองก่อน เวลาจะรันอะไรก็ลำบาก แถมยังแพงอีกต่างหาก เราก็เลยมีการแบ่งเซิฟเวอร์ใช้งานกันครับ หมายความว่าเราไม่จำเป็นที่ต้องใช้เซิฟเวอร์ 1 เครื่องรัน services 1 ตัว แต่เราสามารถใช้เซิฟเวอร์เครื่องเดียวกันนี้ รันหลายๆ service พร้อมๆกันไปได้ ประหยัดเงินไปตั้งเยอะ
Server (Photo: canva.com)
แต่ปัญหาก็ยังไม่จบอยู่แค่นั้นครับ เพราะมันอาจจะปัญหาเรื่องของ Dependencies หรือ Library ต่างๆได้ ลองนึกภาพถ้าผมกำลังรัน service ตัวนึง ซึ่งใช้ Python 2 (แอบเก่า;) ) แต่ปรากฎว่ามีเพื่อนที่จะต้องการมาแชร์เครื่องด้วยกันต้องการที่จะใช้งาน Python 3 ที่นี้ก็จะเกิดปัญหาขึ้นมาครับ เพราะเวอร์ชันของ Depencdencies ที่เราต้องการมันไม่ตรงกัน!! ซึ่งแน่นอนว่าเป็นเรื่องที่ปวดหัวมากเพราะฉะนั้นจึงมีการพัฒนาสิ่งหนึ่งขึ้นมาครับ คือสิ่งที่เรียกว่า Virtual Machines (ยังไม่ถึง Docker นะครับ)
มาทำความรู้จัก VM กันสักหน่อยครับ
VM (Photo: howtogeek.com)
Virtual Machine ทำให้เราสามารถจำลองคอมพิวเตอร์ขึ้น บนคอมพิวเตอร์ได้ ที่นี้เวลาเราอยากจะรัน services อะไรเราก็แค่จำลองคอมพิวเตอร์ขึ้นมา แล้วก็ลงแค่ dependencies ที่ต้องการในคอมพิวเตอร์จำลองนั้น ก็จะหมดปัญหาเรื่อง dependencies ตีกันไปได้ครับ แน่นอนว่ามาถึงยุค Virtual Machine แล้วแต่ก็ยังสามารถพัฒนาต่อไปได้ ก็เลยถึงยุคของพระเอกเราในบทความนี้ครับก็คือ Docker นั่นเอง!! (จริงๆแล้วปัจจุบันก็มีสิ่งเจ๋งๆกว่า Docker อยู่เหมือนกันครับ แต่บทความนี้เอา Docker ก่อนแล้วกัน)
ปัญหาของ Virtual Machine คือการจะจำลองคอมพิวเตอร์ขึ้นมา 1 เครื่องเราจะต้องติดตั้งอะไรต่าง ๆ มากมาย ไม่ว่าจะเป็น OS หรือองค์ประกอบต่างๆที่ใช้ในการควบคุมเพื่อจำลองคอมพิวเตอร์ 1 เครื่องขึ้นมา (ใครเคยเล่นพวก VirtualBox จะพอรู้ครับว่ามันกินทรัพยากรสูงมากๆ) สิ่งที่ Docker ทำคือการสร้างสิ่งที่เรียกว่า Container ขึ้นมา โดย Container นึกภาพให้เหมือนกับว่าเป็น environment นึงที่ถูกสร้างขึ้นบนคอมพิวเตอร์ แล้วก็ทำหน้าที่ contain (เป็นกล่อง) สิ่งต่างๆที่เราต้องการใส่ลงไปครับนั่นก็คือการทำงานของ Docker นั่นเอง แต่ถึงแนวคิดของมันจะเรียบง่ายแต่เบื้องหลังการทำงานของมันมีความซับซ้อนพอตัวเลยครับ เช่นว่ามีการใช้งาน Linux อยู่เบื้องหลัง คอยทำหน้าที่จัดสรรทรัพยากรต่างๆ ทำงานกับ Filesystem บลาๆๆ ซึ่งตรงนี้ผมจะขอข้ามไปครับคร่าวๆของ Docker ก็จะประมาณนี้นั่นเอง
วิธีการติดตั้ง Docker ผมจะขออนุญาตข้ามไปนะครับ แต่การติดตั้งไม่ได้ซับซ้อนมากสามารถอ่านได้ที่ Docs ของ Docker โดยตรงได้เลยครับ https://docs.docker.com/get-docker/
แล้วเราจะสร้าง Container ยังไง? การสร้าง Container มีหลายวิธีครับ แต่วิธีที่เป็นที่นิยมที่สุด (เรียกได้ว่า ควรจะทำมากที่สุด) คือการสร้าง Dockerfile ขึ้นมาครับ
โดยสิ่งที่เรียกว่า Dockerfile นี้ก็จะเป็นสิ่งที่ทำหน้าที่บอกองค์ประกอบต่างๆที่เราต้องการให้ container ที่เราต้องการสร้างเป็นครับ แต่เดี๋ยวก่อน ก่อนอื่นที่เราจะเริ่มเขียน Dockerfile กันเรามาไล่เรียงกันดีกว่าว่าการจะสร้างโปรเจค django ขึ้นมาโปรเจคท์หนึ่งนั้นเราต้องทำอะไรกันบ้าง (นับตั้งแต่ 0 เพิ่งได้คอมพิวเตอร์มาเลยครับ 555) โดยสามารถทำได้ตามขั้นตอนดังต่อไปนี้
(env) pip install python
(env) pip install django
(env) django-admin startproject <ชื่อโปรเจคท์>
(env) cd <ชื่อโปรเจคท์>
(env) python manage.py runserver
หน้า default ของ django
แชว้บ~ ได้จรวดพร้อมโปรเจคท์ Django มาโปรเจคท์หนึ่ง เดี๋ยวเรามาต่อกันที่ Docker กันดีกว่าข้างบนเป็นขั้นตอนเมื่ออยากที่จะสร้างโปรเจคท์ใหม่ขึ้นมาใช่มั้ยครับ แต่ถ้าหากเราจะใช้งาน Docker เราจะต้องทำเหมือนกับว่า เราต้องการจะเอาโปรเจคท์ของเรา ไปรันในเครื่องอื่นเราจะทำยังไงกันก็อย่างแรกเลยคือเราต้องมีรายชื่อของ library python ที่เราจะใช้กันก่อนครับ ก็ใช้คำสั่ง
$ pip freeze > requirements.txt
เพื่อนำ library ต่างๆของเรามาก่อน
asgiref==3.3.1
Django==3.1.4
pytz==2020.5
sqlparse==0.4.1
เดี๋ยวเรามาไล่ขั้นตอนกันใหม่ดีกว่าว่าถ้าเรายก Django ของเราไปเครื่องเพื่อนเราจะทำยังไง เริ่มกันตั้งแต่ 0 ได้คอมมาใหม่ๆเหมือนเดิมครับ โดยมีขั้นตอนดังนี้
เมื่อได้ขั้นตอนนี้มาแล้วเดี๋ยวมาสร้างไฟล์ Dockerfile กันเลยครับ สร้างไฟล์ใหม่ชื่อ Dockerfile มาก่อน จากนั้นพิมพ์ลงไปตามนี้ครับ
Dockerfile
FROM python:3
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
โดยสิ่งที่เราเขียนไปใน Dockerfile ก็จะเป็นไปตามขั้นตอนที่เราไล่ไปในข้างบนเด๊ะๆเลย (มีแปลกๆตรง EXPOSE เดี๋ยวไว้อธิบายข้างล่างอีกทีครับ)
ก่อนอื่นเราจะต้องทำการ build ไฟล์ Dockerfile ของเราก่อนครับ ซึ่งการ Build เมื่อเสร็จสิ้นเราจะได้สิ่งที่เรียกว่า Image ออกมา เมื่อได้ Image เราจึงจะสามารถนำไปสร้าง Container ได้ครับ Build ด้วยคำสั่ง docker build -t <ชื่อ image ที่ต้องการตั้งfile
ตัวอย่างเช่น
$ pip freeze > requirements.txt
ตอนรันระวังอย่าลืม(Dot) . ด้วยนะครับ
เมื่อได้ image มาแล้วให้ใช้คำสั่งรันด้วยการรันตามนี้ครับ
$ docker run -p 8000:8000 -v $(pwd):/app <ชื่อ image ที่พึ่งตั้งไป>
Note: Windows: ไม่มีคำสั่ง pwd ใช้เป็น %cd% แทนครับ
เดี๋ยวไว้มาอธิบายกันดีกว่าว่าคำสั่งนี้มันทำอะไรได้บ้างครับ คำสั่งพื้นฐานสุดๆเลยคือ docker run <ชื่อ image> แค่เพียงเท่านี้เราก็สามารถที่จะรัน Container ได้แล้ว แต่เราเพิ่มแท็ก -p และ -v ขึ้นมาเนื่องจากว่าจำเป็นต้องมีการ config ให้เจ้า container สามารถสื่อสารกับเราได้ครับ
-p ใช้สำหรับการ map port โดยปกติแล้วเมื่อสร้าง container ขึ้นมาตัว docker จะไม่ได้มีการเชื่อมพอร์ตให้เราโดยอัตโนมัติ เราจำเป็นที่จะต้องเชื่อมเองครับ -p 8000:8000 หมายถึงเชื่อมต่อพอร์ต 8000 ของเครื่องเราเข้ากับ 8000 ของตัว container (EXPOSE ใน Dockerfile ก็มีไว้เพื่อเหตุผลเดียวกันครับ)
-v คล้ายๆกันกับการ map port แต่ว่าเรา map พื้นที่ใน harddisk ของเราแทนครับ -v $(pwd):/app ของผมคือการ map directory ปัจจุบันของผมเข้ากับ /app ในตัว container นั่นเอง pwd ใน Unix เป็นคำสั่งเพื่อแสดงที่อยู่ไดเรคทอรี่ปัจจุบันของเรา
เมื่อรันคำสั่งแล้วลองเปิด localhost:8000 ดูก็จะเห็น
รันได้เหมือนกันกับเครื่องต้นทาง
แสดงว่าการใช้งาน Docker ร่วมกับ Django ของเราเสร็จสมบูรณ์ครับ ตอนนี้ก็ถ้าใครอยากลองแก้ไขไฟล์ดูแล้วดูว่าหน้าเว็บของเราเปลี่ยนไปด้วยหรือไม่ก็สามารถลองทำได้ตามสะดวกเลยครับ สำหรับบทความนี้ก็ขอขอบคุณมากครับ เจอกันใหม่บทความหน้าครับ
การเริ่มต้นสร้างโปรเจค gui ด้วย python library อย่าง tkinter
March 1, 2021
การออกแบบหน้าตาโปรแกรม gui ของเราด้วย method อย่าง pack grid layout
March 1, 2021
ทดสอบสร้าง GUI ด้วย Python โดยนี่คืออีกหนึ่ง library ที่น่าสนใจครับ มีชื่อว่า easyGUI
Feb. 20, 2021
คอร์สนี้เป็นหนึ่งในคอร์สที่มาแรงที่สุดของปีนี้ในส่วนของ Python Web Development
฿ 2,500 1,250 บาท
คอร์สนี้เป็นหนึ่งในคอร์สที่มาแรงที่สุดของปีนี้ในส่วนของ Python Web Development
฿ 9,900 บาท
คอร์สนี้เป็นหนึ่งในคอร์สที่มาแรงที่สุดของปีนี้ในส่วนของ Python Web Development
฿ 2,500 บาท