[Docker] ลดขนาด Docker Images ด้วยการทำ Multi-Stage 🚀
แบบรวบรัด(สำหรับคนมีเวลาอ่านน้อย)
- หลักการทำงานของ Multi-Stage คือ การที่เราสร้าง Container ขึ้นมามากกว่า 1 อัน เช่น เราสร้าง Container มา 2 อัน โดยให้อันแรกเป็นการดาวน์โหลดและติดตั้ง Resources หรือ Tools ที่จำเป็นต้องใช้ในการ Build Project ของเรา จากนั้น Copy เฉพาะส่วนที่เรา Build เสร็จแล้วไปไว้ใน Container ที่ 2 โดยไม่สนใจ Resources หรือ Tools ที่ใช้ในการ Build
มาเตรียมเครื่องไม้เครื่องกันก่อน 🛠
- เปิดหน้า Terminal ขึ้นมา
- ทำการติดตั้ง create-react-app
~ % npm install -g create-react-app
2. ติดตั้ง Docker
อ่านเพิ่มเติมได้ที่ Docker-Get-Started
ถ้าพร้อมแล้วมาลุยกันเลย 🔥
เริ่มที่การสร้าง create-react-app Project กันก่อน
~ % create-react-app multi-stage
~ % cd multi-stage
จากนั้นทำการสร้าง Dockerfile แล้วใส่ Instruction ตามด้านล่างนี้ได้เลย
# First Stage ...FROM node:10.22.0 as builder
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json .
COPY package-lock.json .
RUN npm install --ignore-platform
COPY . .
RUN npm run build# Second Stage ...FROM nginx:1.14.2-alpine
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
WORKDIR /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]
หลังจากนั้นก็ทำการ Build Images ด้วย
docker build -f Dockerfile -t multi-stage:latest .
มาดูกันว่าใน Dockerfile เราทำอะไรกันบ้างโดยจะขอแยกเป็น 2 ส่วน ให้เห็นภาพกันง่ายๆนะครับ
1st<Stage
- เราได้ทำการระบุ Base OS ของ Images โดยในที่นี้จะเป็น node:10.22.0
- สร้าง Directories ใหม่ใน Container
- Set WORKDIR ให้เป็น Directories ที่เราเพิ่งสร้าง
- Copy ไฟล์ต่างๆที่จำเป็นในการ Build และ Run App
- ติดตั้ง node_modules และ Dependencies ต่างๆ
- Copy ไฟล์ใน Project ทั้งหมดไปที่ WORKDIR
- จากนั้น Build Production
2nd<Stage
- เราได้ทำการระบุ Base OS ของ Images โดยในที่นี้จะเป็น nginx:1.14.2-alpine
- Copy เฉพาะตัว Production Build จาก 1st Stage ไปไว้ใน Folder
/usr/share/nginx/html
สุดท้ายแล้วเราจะได้ตัว Production Build โดยปราศจากเจ้า node_modules และ Code ของเราจึงทำให้ Container ของเรานั้นเบาหวิวสมใจปราถนา 🚀
สุดท้าย …
ในหน้า Terminal พิมพ์คำสั่ง
~ % docker run --rm -p 80:80 --name multi-stage multi-stage:latest
แล้วดูว่า App ของเราทำงานมั้ยถ้าทำงานได้จะต้องขึ้น Logo ของ React แบบนี้
จากนั้นลอง Run
~ % docker images
จากภาพตัวอย่างจะเห็น Docker Images ที่เรา Build ขึ้นมาชื่อว่า multi-stage และ <none> ซึ่งเป็นตัว Builder ที่อยู่ใน 1st Stage จะเห็นว่ามันมีขนาดถึง 1.26GB 🤯 ส่วนตัว multi-stage นั้นเหลือเพียง 16.5MB เท่านั้น ✨
ปล. หากต้องการลบ Docker Images ในกรณีที่ไม่ได้ใช้แล้วเพื่อไม่ให้เปลืองพื้นที่ให้พิมพ์
~ % docker system prune
เป็นคำสั่งที่ใช้ลบ Docker Images ใน VM ของเราเพื่อเพิ่มพื้นที่ในตัว VM ของเรา
‼️ แต่ต้องระวังหากจะนำไปใช้กับตัว Production ยังไงลองไปศึกษาคำสั่งนี้เพิ่มเติมดูก่อนจะดีที่สุดครับ
Summary
- การทำ multi-stage นั้นช่วยลดขนาดของ Docker Images อย่างมากทำให้การที่เราจะนำ Docker Images นั้นๆไปใช้นั้นสะดวกและรวดเร็วยิ่งขึ้น อีกทั้งยัง เพิ่มประสิทธิภาพของ Container ที่ Run บน Serverless ได้อีกด้วย ✅
อย่าลืม 👏 (Claps) และ 🔖 (Bookmark) บทความนี้ไว้อ่านทีหลังด้วยนะครับ