[Docker] ลดขนาด Docker Images ด้วยการทำ Multi-Stage 🚀

Wasin Khaojaroen
THE EXISTING COMPANY
3 min readAug 28, 2020

--

แบบรวบรัด(สำหรับคนมีเวลาอ่านน้อย)

  • หลักการทำงานของ Multi-Stage คือ การที่เราสร้าง Container ขึ้นมามากกว่า 1 อัน เช่น เราสร้าง Container มา 2 อัน โดยให้อันแรกเป็นการดาวน์โหลดและติดตั้ง Resources หรือ Tools ที่จำเป็นต้องใช้ในการ Build Project ของเรา จากนั้น Copy เฉพาะส่วนที่เรา Build เสร็จแล้วไปไว้ใน Container ที่ 2 โดยไม่สนใจ Resources หรือ Tools ที่ใช้ในการ Build

มาเตรียมเครื่องไม้เครื่องกันก่อน 🛠

  1. เปิดหน้า Terminal ขึ้นมา
  2. ทำการติดตั้ง 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) บทความนี้ไว้อ่านทีหลังด้วยนะครับ

The existing company

--

--