สร้าง Docker Container ใช้สำหรับการ Deploy ML Model

Contained everything in Docker!

Sasiwut Chaiyadecha
5 min readMar 10, 2021
docker image docker container deploy ml model heroku flask python

จากตอนก่อนหน้านี้ ได้มีการ Deploy ML Model ด้วย Git และ Heroku กันไปแล้ว ตอนนี้อยากลดขั้นตอนการทำงานของ Git ลง เพราะไม่อยากเชื่อมต่อหลาย Connection ทั้ง Git และ Heroku

ดังนั้นการใช้งาน Docker จึงเป็นทางออกที่ดี เพราะสุดท้ายแล้วสามารถ Deploy docker container ขึ้นไปที่ Heroku ได้เลยตรง ๆ โดยที่ไม่ต้องผ่าน Git ไฟล์สำหรับ Blog ตอนนี้ใช้เป็นของ Project ในตอนก่อนหน้านี้ทั้งหมด ดังนั้นสามารถดูรายละเอียดได้จาก Link ด้านล่าง

docker image docker container deploy ml model heroku flask python

Docker

Docker คืออะไร… ก่อนอื่นควรเริ่มทำความรู้จักกับ Docker ที่เป็นที่นิยมมาก สำหรับการทำงานสาย Tech ซึ่งสามารถนำปรับใช้ให้เข้างานสาย Data หรือ Risk model ได้เช่นกัน

ปัญหาที่เกิดขึ้นบ่อยครั้งสำหรับการทำงานเกี่ยวกับ Data ด้วยระบบเปิด (SAS ถึงว่าเป็นระบบปิด อาจเจอปัญหาลักษณะนี้น้อยกว่า) ในที่นี้อาจหมายถึง Python หรือ R ที่จำเป็นต้องพึ่งพาเครื่องมือจากหลาย Sources บ่อยครั้งที่การทำงานของโปรแกรมผิดพลาด เนื่องจากเวอร์ชั่นที่ไม่ตรงกัน

Docker สามารถเข้าช่วยแก้ไขปัญหานี้ได้ เพราะ Docker มีการทำงานคล้ายกับ Virtual Machine ที่เป็นเหมือนการจำลองสภาพแวดล้อมในการทำงาน ไม่ว่าจะเป็น OS หรือ Environment ต่าง ๆ จากเดิมที่เคยส่งเป็น Script ให้กับทาง User ต่อไปสามารถส่งเป็น Docker image หรือ Container เพื่อช่วยให้การทำงาน Smooth มากขึ้น

docker image docker container deploy ml model heroku flask python

Dockerfile

Dockerfile เป็นเหมือนชุดคำสั่ง ในการสั่งให้ Build image ด้วยองค์ประกอบตามที่กำหนด เช่น ใช้งานบน Service อะไร ต้องติดตั้งอะไรบ้าง เพื่อการใช้งาน Dockerfile มีความคล้ายกับ Procfile เคยใช้งานจากตอนก่อนหน้านี้

Docker image

Docker image เป็นต้นแบบก่อนเริ่มสร้าง Docker container มีการตั้งค่าหรือจำลองทุกอย่างไว้ตามที่ระบุจาก Dockerfile

Docker container

Docker container เป็น Application สุดท้ายที่เป็น Service ที่ต้องการใช้งานจริง ๆ สามารถนำ Container เพื่อไปใช้งานใน CPU, RAM หรือใน Network ต่าง ๆ ได้

docker image docker container deploy ml model heroku flask python

Build docker

Code และไฟล์ สำหรับ Project ทั้งหมด สามารถใช้ได้จากตอนก่อนหน้านี้ มีส่วนที่ต้องแก้ไขใน Python script เนื่องจากต้องปรับให้ทำงานร่วมกับ Docker container ได้

docker image docker container deploy ml model heroku flask python

ในไฟล์ app.py มีการอัพเดตเพิ่มที่

  • Line ที่ 3 Import os เข้ามาเป็นจัดการกับ Path
  • Line ที่ 27 กำหนด Post ให้เป็น 5000
  • Line ที่ 28 กำหนด Host และ Post ให้กับ Flask application เนื่องจาก Docker container ไม่สามารถชี้ไปที่ Default host ที่ 127.0.0.1 ได้ ดังนั้นจึงจำเป็นต้องใช้งานผ่าน Localhost แทน ส่วน Default post ที่มีค่า Default เป็น 5000 อยู่แล้ว แต่การระบุ Port ลักษณะนี้ช่วยไม่ให้เกิด App crash ในขั้นตอนการ Deployment ได้

ก่อนเริ่ม Build docker image และ docker container ต้องทำการติดตั้ง Docker ที่เครื่องก่อน สามารถ Download และติดตั้งได้จาก Link ด้านล่าง

เมื่อติดตั้งแล้ว ให้ลองเรียก Docker ขึ้นมาจาก Command prompt เช่น

docker --version

ถ้าไม่มี Error แล้วสามารถแสดงเวอร์ชั่นได้ แสดงว่าติดตั้งได้สมบูรณ์

ต่อมาให้สร้าง Dockerfile โดย Create emtpy file ที่ไม่ต้องระบุนามสกุลขึ้นมาจาก Editor อะไรก็ได้ จากนั้นให้ระบุ Requirments สำหรับ Docker image ตามด้านล่าง

FROM python:3.7.9-slim-busterWORKDIR /appCOPY requirements.txt .RUN pip install -r requirements.txtCOPY . .EXPOSE 5000CMD ["python", "app.py"]

ดังนั้น Project structure ประกอบไปด้วย Folder และไฟล์ตามผังด้านล่าง

templates
---index.html
app.py
model.pk
Dockerfile
requirements.txt

เริ่มอธิบาย Line by line เริ่มจาก FROM คือการระบุ Base image ว่าให้ Container เรียกใช้งาน Base ประเภทไหน ซึ่ง Application ถูกเขียนด้วย Python ดังนั้น Base image จึงต้องเป็น Python แต่ Python มีให้ใช้งานหลายเวอร์ชั่น และหลายขนาดนั้น ดังนั้นสามารถเลือกให้เหมาะสมกับ Application ได้จาก Link ด้านล่าง

WORKDIR เป็น Directory ที่จะถูกสร้างภายใน Docker image ในที่นี้ขอตั้งชื่อว่า app

COPY เป็นการ Copy dependencies file ซึ่งคือ Requirements.txt ที่ภายในระบุ Python libraries ที่จำเป็นต่อการรัน Application

RUN เป็นการสั่งให้รัน Dependencies file เพื่อติดตั้ง Libraries ใน Docker image

COPY . . เป็นการบอกให้ Copy ไฟล์ที่เหลือทั้งหมดใน Project ลงใน Docker image

EXPOSE 5000 เป็นการกำหนด Port ให้ Container สำหรับการเรียกใช้งานภายนอก Network เช่นการ Push ไปที่ Heroku เป็นต้น

CMD ["python", "app.py"] เป็น Command line ในการบอกให้ Container เริ่มทำงาน ซึ่งเหมือนเป็นการสั่งรัน Python script บน Localhost

เมื่อทุกอย่างพร้อมแล้ว สามารถเริ่ม Build docker image โดยใช้คำสั่งตามด้านล่าง

docker image build -t image-name .

ต้องใส่ . หลังจากชื่อ Docker image ด้วย ไม่งั้นจะไม่สามารถรัน Build ได้ เมื่อได้ Log return เหมือนด้านล่างแสดงว่าการสร้าง Docker image เสร็จสมบูรณ์

[+] Building 58.8s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> [2/5] WORKDIR /app 5.1s
=> [3/5] COPY requirements.txt . 0.2s
=> [4/5] RUN pip install -r requirements.txt 25.7s
=> [5/5] COPY . . 0.1s
=> exporting to image 2.4s
=> => exporting layers 2.4s
=> => writing image sha256:9b7c7ec953f3e0c421c228d07fdbb9b3ed76fdb8f37331ab8303d 0.0s
=> => naming to docker.io/library/ml-model 0.0s

สามารถตรวจสอบ Docker image ที่เพิ่ง Build ได้ด้วยคำสั่ง docker image ls เป็นการแสดง List ของ Docker image ที่ทั้งหมดในเครื่อง

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
ml-model latest 9b7c7ec953f3 2 minutes ago 352MB

ต่อมาสามารถทดลองรัน Container ได้ด้วยการระบุ Port ที่เขียนไว้ใน app.py ด้วยคำสั่ง

docker run -p 5000:5000 -d image-name

เมื่อรันคำสั่งด้านบน Terminal จะ Return ค่า Container ID กลับมาให้เก็บค่านั้นไว้ เพราะต้องใช้ในการหยุดรัน Container เมื่อ Container ทำงานแล้ว สามารถทดสอบการทำงานของ Container ได้ด้วยการเข้า localhost:5000 ผ่าน Web Browser ถ้าสามารถเข้าใช้งานได้เหมือนรูปด้านล่าง แสดงว่าการ Build image และ Run container เสร็จสมบูรณ์

docker image docker container deploy ml model heroku flask python

สามารถหยุดรัน Container ได้ด้วยคำสั่งด้านล่าง

docker container stop container-id

นอกจาก Stop container แล้วอาจต้องมีการหยุดรัน Service อื่น ๆ ที่ติดอยู่เบื้องหลังด้วย สามารถใช้คำสั่ง docker system prune เมื่อทุกอย่างที่ Local พร้อมแล้ว สามารถนำ Docker image ไป Deploy ต่อได้

Deployment with Heroku

docker image docker container deploy ml model heroku flask python

ตอนก่อนหน้านี้ มีการ Create application บนหน้าเว็บ Heroku ตอนนี้เลยขอทำทั้งหมดบน Command line เพื่อความแตกต่างบ้าง ก่อนอื่นให้ Loing เข้าไปที่ Heroku โดยใช้คำสั่ง

heroku container:login

เมื่อได้ Return กลับมาว่า Login Succeeded สามารถทำการ Create application ได้ด้วยคำสั่ง

heroku create app-name

โดยที่ app-name ให้ตั้งชื่อที่ไม่ซ้ำกับ Domain อื่น ๆ อาจต้องมีการเลือกใช้หลายชื่อหน่อย ซึ่งตอนนี้ขอใช้ชื่อว่า testingdockermlmodel ถ้าได้ Return เหมือนด้านล่างแสดงว่าสามารถใช้ชื่อ Application นั้น ๆ ได้

Creating testingdockermlmodel... done
https://testingdockermlmodel.herokuapp.com/ | https://git.heroku.com/testingdockermlmodel.git

ต่อมาเป็นการ Push container ขึ้นไปที่ Heroku ให้ใช้ Command ด้านล่าง

heroku container:push web --app app-name

ได้ถ้า Return กลับมาเป็น

Your image has been successfully pushed. You can now release it with the 'container:release' command.

สามารถทำการ Release ด้วย Command ด้านล่าง เป็นขั้นตอนสุดท้ายสำหรับการ Deployment docker container บน Heroku

heroku container:release web --app app-name

Conclusion

จบไปอีกหนึ่งรูปแบบในการ Deployment ML Model ด้วย Docker และ Heroku การทำ Docker image ช่วยลดขั้นตอนการใช้ GitHub และสามารถ Push ไปที่ Heroku ได้ทันที แต่อาจมีความยุ่งยากตอน Build docker image อยู่บ้าง

ผลจากที่ทำมาทั้งหมดในตอนนี้ สามารถเข้าไปดูได้ที่ https://testingdockermlmodel.herokuapp.com/

docker image docker container deploy ml model heroku flask python

อัพเดต

Model materials ทั้งหมดของ Blog ตอนนี้ สามารถดูได้ที่ GitHub ด้านบน

--

--

Sasiwut Chaiyadecha
Sasiwut Chaiyadecha

No responses yet