มาสร้าง Docker Image กันเถอะ!
จุดเริ่มต้นการสร้าง Docker Container จากการเขียน Docker File
ในบทความนี้เราจะมาดูกันว่าตัว Docker File นี้จะเราสร้างขึ้น และเขียนรายละเอียดการกำหนดค่าให้มันยังไง พร้อมกับการนำมาทำเป็น Docker Image
สำหรับผู้เริ่มต้น เราสามารถทำความเข้าใจในหลักการพื้นฐานของ Docker ก่อนได้ที่
สร้าง Docker File
เราสามารถสร้างไฟล์ชื่อ “ DockerFile ” พิมพ์ตามนี้ได้เลย แล้วเราจะได้ไฟล์หน้าตาเป็นปลาวาฬแบกตู้คอนเทนเนอร์ประมาณนี้
ตอนนี้เราได้สร้าง Docker File ขึ้นมาแล้ว
เขียน Docker File
Docker File นั้นใช้ DSL (Domain-specific language) แบบพื้นฐาน หรือภาษาเฉพาะของมันเองในรูปแบบที่ไม่ซับซ้อน ในการเขียนหรือโปรแกรมมัน
เน้นเขียนเพื่อให้ทำงานตามลำดับขั้นตอน ก่อน-หลัง
เราเขียน Docker File ก็เพื่อใช้สร้างเป็น Docker Image ซึ่งเมื่อรัน Docker File จะเกิดการทำงานไล่ทีละบรรทัด (1 การดำเนินงาน ต่อ 1 บรรทัด) ตามที่เรากำหนด
รูปแบบของภาษาที่ใช้เขียน Docker File จะเริ่มแต่ละบรรทัดด้วย คำสั่งภาษาอังกฤษพิมพ์ใหญ่ล้วน และตามด้วยการกำหนดค่าต่างๆ ผ่านตัวอักษร กับการเว้นช่องว่าง
จากรูปตัวอย่างข้างต้นนั้น เมื่อมีคำสั่งสร้าง Docker Image มา (docker build … ดูได้ในหัวข้อด้านล่างถัดไป) ก็จะเริ่มทำงานจากบรรทัดที่ 1 จนบรรทัดสุดท้าย
FROM [--platform=<platform>] <image> [AS <name>]
“ FROM ” → คำสั่งเพื่อเรียกใช้ base image ที่จะมาเป็นสภาพแวดล้อมหลักในการทำงานสำหรับโปรเจคเรา
ในที่นี้ คือ node:11-alpine หรือก็คือ base image สำหรับงานที่ทำงานด้วย Node JS จาก Docker Hub ที่รันในระบบปฏิบัติการ Linux เวอร์ชั่น Alpine
WORKDIR /path/to/workdir
“ WORKDIR ” → คำสั่งเพื่อกำหนด Directory สำหรับการทำงานเพื่อให้คำสั่งอื่นๆที่เราจะใช้อย่างเช่น RUN, COPY และ อื่นๆ ให้ไปเริ่มต้นทำงานที่ Directory นั้น
ในที่นี้คือตั้งค่าให้ทำงานภายใน Directory ชื่อ app
เราควรกำหนดคำสั่ง WORKDIR ก่อนคำสั่งการทำงานอื่นๆเสมอ
COPY <src> <dest>
“ COPY ” → คำสั่งเพื่อการคัดลอกไฟล์ต่างๆจากที่หนึ่ง ไปไว้ยังที่ ที่เราต้องการ
RUN <command>
“ RUN ” → คำสั่งเพื่อการดำเนินการคำสั่งที่ต้องการ
ในที่นี้เราได้ทำการคัดลอกไฟล์ 3 ไฟล์ที่ใช้กำหนดเครื่องมือ และการตั้งค่าของการทำงานตัวโปรเจคเว็บคือ package.json, package-lock.json และ webpack.mix.js จากโปรเจคของเรา
แล้วในบรรทัดที่ 4 เราก็ได้ทำการสั่ง npm install เพื่อลงสิ่งต่างๆที่เรากำหนดไว้ในไฟล์ package.json ที่ได้คัดลอกมาใส่ใน Directory ชื่อ app
จากนั้นในบรรทัดที่ 5 เราได้ทำการคัดลอกไฟล์ โฟลเดอร์ในโปรเจคเราทั้งหมดมาไว้ใน Directory ชื่อ app
ใน Directory ชื่อ app ตอนนี้ก็เหมือนมีทุกอย่างครบถ้วน ตั้งแต่สภาพแวดล้อมการทำงานจนไปถึงโปรแกรมแอพพลิเคชั่นที่เราเขียนไว้ในโปรเจค ที่เหลือเราก็แค่สั่งให้เว็บเริ่มต้นทำงานในบรรทัดที่ 6
คำสั่งอื่นๆที่ใช้ใน Docker File
เราสามารถประยุกต์ใช้งานคำสั่งต่างๆให้เหมาะสมกับแต่ละตัวงานได้
ARG <name>[=<value>]"ARG" --> คำสั่งเพื่อระบุตัวแปรที่จะใช้ในการ build
Ex. ARG user=admin
ADD <src> <dest>"ADD" --> คำสั่งเพื่อการเพิ่มไฟล์ที่ต้องการเข้ามาในโฟลเดอร์ที่กำหนด
Ex. ADD someFile.js /mydir/
EXPOSE <port>"EXPOSE" --> คำสั่งเพื่อกำหนด port ให้ Docker ที่จะให้เห็นระหว่างผู้สร้างกับผู้ใช้งาน
Ex. EXPOSE 80
CMD <command> กับ ENTRYPOINT <command>"CMD", "ENTRYPOINT" --> คำสั่งเพื่อการสั่งให้ทำงานบางสิ่งที่เราต้องการ
Ex. CMD "npm run serve"
Ex. ENTRYPOINT "npm run serve"
VOLUME ["/dataPath"]"VOLUME" --> คำสั่งเพื่อการกำหนด directory path สำหรับเก็บไฟล์ที่เราต้องการ
Ex. VOLUME /myVol
ENV <key>=<value>"ENV" --> คำสั่งเพื่อการกำหนดค่าตัวแปรสำหรับสภาพแวดล้อมในการทำงาน
Ex. ENV API_ENDPOINT=https://api.website.com/
ONBUILD [INSTRUCTION]"ONBUILD" --> คำสั่งเพื่อการกำหนดการทำงาน โดยที่จะทำงานเฉพาะเมื่อถูกเรียกใช้เป็น base image เท่านั้น
Ex. ONBUILD ADD . /app/src
LABEL <key>=<value> <key>=<value>"LABEL" --> คำสั่งเพื่อการกำหนด หรือสร้าง metadata ให้กับ Image
Ex. LABEL version="1.0" "description": "This is description"
HEALTHCHECK [OPTIONS] CMD command"HEALTHCHECK" --> คำสั่งเพื่อเช็คสภาพการทำงานของ container (ล่ม หรือ ปกติ)
Ex. HEALTHCHECK --interval=5m --timeout=3s
CMD curl -f http://localhost:5000/ || exit 1
STOPSIGNAL signal"STOPSIGNAL" --> คำสั่งเพื่อการหยุดการทำงานของ container
Ex. STOPSIGNAL anyString
สามารดูรายละเอียด และตัวอย่างเพิ่มเติมได้ที่เว็บไซต์ทางการเรื่องคำสั่ง DockerFile
รัน Docker File (ใช้งาน Docker File)
เราจะสร้าง Docker Image จาก Docker File ได้โดยสั่งงาน “ docker build ”
docker build {imagePath}
เมื่อทำงานจะมีการนำ DockerFile ที่ imagePath ที่ระบุไว้มาสร้าง Docker Image
หรือเราจะสร้างแบบระบุ ชื่อ กับ Tag ให้กับ Docker Image ก็ใช้คำสั่ง
docker build -t imageName:tagName image01
คำสั่งนี้จะทำงานโดย
- เข้าไปหา DockerFile ที่ image01/ (path ที่เก็บ DockerFile) หาก DockerFile อยู่ที่ root เราก็แค่พิมพ์ “ . ” อย่างเช่น
docker build -t imageName:tagName .
- จากนั้น DockerFile จะถูกเอามาเริ่มสร้างเป็น Docker Image
- เมื่อสร้างเสร็จ ก็ตั้งชื่อให้ Image ที่ได้ออกมาว่า imageName
- และตั้งชื่อ Tag ให้กับ Docker Image นั้นๆว่า tagName
จุดประสงค์ของการตั้งชื่อ Image กับ Tag (ผ่านการกำหนด option “ -t ” )
เพื่อที่เราจะได้จัดเก็บ Image ตามกลุ่ม หรือหมวดหมู่ของมันด้วย ชื่อของ Image
และกำหนดเวอร์ชั่น หรือรุ่นของ Image ด้วย Tag
เพราะเราอาจมี Image ที่ถูกสร้างขึ้นจาก ข้อมูลใน Docker File ที่แตกต่างกันไม่น้อยก็มาก แต่มันเป็น Image สำหรับงานๆเดียวกัน ใช้ในจุดประสงค์เดียวกัน ซึ่งจะเป็นการดีถ้าเราแยกสร้าง Image ตามชื่องาน แล้วระบุเวอร์ชั่นเพื่อการทดสอบการทำงาน โดยหากมีเวอร์ชั่นใดๆที่เราใช้งานแล้วเกิดข้อผิดพลาด เราก็ยังสามารถเรียกใช้งาน Image ในเวอร์ชั่นที่เสถียร และทำงานได้ดีกลับมาใช้งานได้อยู่
และเราสามารถสร้าง Docker Image จาก Docker File ที่มีอยู่แล้วตามเว็บได้โดยการสร้าง Docker Image แบบรีโมทโดยใช้คำสั่ง
docker build [OPTIONS] -f- PATH
Ex. docker build -t myImage:1.0 -f- https://github.com/docker-lib/foo.git
ตอนนี้เราก็ได้สร้าง Docker Image จาก Docker File แล้ว
ในบทความถัดไปเราจะมาจัดการกับ Docker Image ให้สร้างออกมาเป็น Docker Container แล้วใช้งานตัว container กันครับ