Optimize Docker Build

Share
Optimize Docker Build

สัปดาห์ที่แล้วผมได้ไป Odd-e boring gathering ที่หางโจวมา ชาว Odd-e ทั่วโลกจะมาเจอกันปีละ 2 ครั้งเพื่อแลกเปลี่ยนความรู้กัน

ครั้งนี้ ผมเลือกที่จะร่วมกันสร้าง product ขึ้นมาด้วยกันกับเพื่อนๆชาว Odd-e เราทำ Sprint 5 วัน รับ item มา 2 item จาก product owner เราตกลงกันว่าเราจะ pair programming กันทุกลมหายใจ มี techical requirement นิดหน่อยว่า architecture ต้องเป็นอย่างไร และทุกอย่างต้อง run อยู่ใน docker หลังตกลงกันเสร็จแล้ว sprint ก็เริ่มต้น

ทุก ๆ คน เก่งกันมาก ๆ ผมได้เรียนรู้เยอะมาก สมศักดิ์ศรีทีมที่สมาชิกแต่ละคนเป็นโค้ชมือพระกาฬจากทั่วโลกมารวมตัวกันจริง ๆ

จบ sprint ปรากฏว่าไม่มีห่าอะไรเสร็จเลย… เวลาส่วนใหญ่เราเสียไปกับการ download maven package กับ download npm package สิ่งสำคัญที่ผมได้เรียนรู้จากประสบการณ์ sprint นี้คือ

เวลาเขียน docker file ให้แยกจังหวะ download dependency libraries กับ compile code ออกจากกัน

ลองดูตัวอย่าง Dockerfile ด้านล่าง

FROM maven:slim as build-stage
COPY ./ ./
RUN mvn install
CMD mvn spring-boot:run

(Gist) https://gist.github.com/juacompe/1733f108197e6eb22b5e2e9180547e70

ตั้งต้นจาก maven image แล้ว copy code แล้วก็สั่ง build แล้วก็ run ดูตรงไปตรงมา ปัญหาคือ ทุก ๆ ครั้งที่เราแก้โค้ด บรรทัดที่ 2 จะ dirty แล้วมันจะต้องทำ mvn install ใหม่ (ซึ่งจังหวะนี้จะ download libs ทั้งหลาย) ทุกครั้ง…

ลองมาดูอันที่แยกจังหวะ download กับจังหวะ build กัน

FROM maven:slim
# copy pom file
COPY ./pom.xml ./
# download all dependency libraries
RUN mvn dependency:go-offline -B
# copy the rest of the code
COPY ./ ./
# build package
RUN mvn install
CMD mvn spring-boot:run

(Gist) https://gist.github.com/juacompe/6b522ed46f26c4953657d7264ed13703
separate library downloading and package building

พอแก้เป็นแบบนี้ ตราบใดที่ pom.xml ไม่ถูกแก้ ตอนสั่ง docker build มันจะใช้ cache ไปจนถึงบรรทัดที่ 7 ( COPY ./ ./ ) ซึ่งทำให้ไม่ต้อง download libs ทั้งหลายใหม่ ทำให้มันเร็วขึ้นมาก

นอกจากนี้ ขณะที่เรากำลังแก้ Dockerfile เราไม่ได้แก้โค้ดเลย แต่พอสั่งบรรทัดที่ 7 ที่มัน copy ทุกอย่าง มันก็จะต้อง build ใหม่ทุกครั้ง ทำไงดี?

เราสามารถกำหนด file ที่เราจะไม่ copy เข้าไปใน image ได้ ใน file ชื่อ .dockerignore ครับ

Dockerfile
.dockerignore
.git/


(Gist) https://gist.github.com/juacompe/d09c0fb42c166af643591ed01b00f25d
.dockerignore

file นี้ระบุว่า ไอ้ file Dockerfile ,.dockerignore และ.git เนี่ย ไม่ต้องเอาเข้าไปนะ เพราะใน container ไม่จำเป็นต้องใช้

เพียงแค่นี้ เราก็สามารถ get feedback เร็ว ๆ เวลาที่เราแก้ Dockerfile แล้วจะลอง run docker build ดูได้แล้วครับ

ถ้าอยากประหยัดเวลามากกว่านี้ทำไง?

มี 3 ทางถ้าอยาก optimize มากกว่านี้ ประกอบด้วย 1 ทางสวย ๆ และอีก 2 ทางสกปรก ๆ หน่อย

ทางแรก คือ สร้าง dockerhub ขึ้นมา host เอง เพื่อจะได้ไม่ต้องไป load image จาก internet ทางนี้สวยสุด ทำยากไหม? แล้วแต่ความชำนาญ ผมเห็น Chai Feng (เพื่อนจาก Odd-e ทีมเซี่ยงไฮ้) ทำ 10 นาที

ทางที่สองคือ สร้าง docker image ใหม่ที่ download dependency libs เสร็จแล้ว แล้ว push ขึ้น docker hub เพื่อใช้เป็น base image ต่อให้ pom.xml เปลี่ยน ก็ download เพิ่มไม่เยอะ

ทางที่สามคือ mount path ที่ใช้ในการเก็บ dependency libraries (~/.m2e/) ออกมาใส่เครื่อง host แบบนี้เราจะได้ใช้ประโยชน์จาก caching ของ maven เอง

ถ้าเป็น node project ทำไง?

ใช้ idea เดียวกันครับ คือ copy package.json กับ package-lock.json เข้าไปก่อน แล้ว run npm install แยกกันกับ npm build

credit: http://whitfin.io/speeding-up-maven-docker-builds/ สำหรับคำสั่ง download mvn dependencies

ref: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/

Read more

กฎของจั๊วะ

กฎของจั๊วะ

ปีนี้ที่อายุ 44 ผม Reflect ตัวเอง และพบว่าหลักการใช้ชีวิตของผมได้มาจากหนังสือ The Seven Habits of Highly Effective People เยอะมาก ใน Habit ทั้ง 7 นี้จะมีเกร็ดเล็กเกร็ดน้อยที่ผมไปศึกษามา แล้วค่อย ๆ เติมเข้าไปเพื่อทำให้ Habit นั

By Chokchai
ขยายกิจการองค์กร

ขยายกิจการองค์กร

อีกบทเรียนที่ผมได้จากหนังสือ Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency ของ Tom DeMarco คือมุมมองใหม่สำหรับการเติบโตของบริษัท ตลอดมา ผมมักจะต่อต้านการแก้ปัญหางานไม่ทันด้วยการเพิ่มคน เพราะการเพิ่มคนเป็นกลยุทธ์ระดับองค์กร แต่งานไม่ทั

By Chokchai
คนไม่ใช่สิ่งทดแทนกันได้ (People are not Fungible)

คนไม่ใช่สิ่งทดแทนกันได้ (People are not Fungible)

ในปี 2546 นักศึกษาคณะวิทยาศาสตร์ที่เรียนอยู่ที่ศูนย์รังสิตมาตลอดแบบผม ได้มีโอกาสเข้าเมืองไปเรียนที่ธรรมศาสตร์ ท่าพระจันทร์ เป็นครั้งแรก นอกจากจะตื่นตาตื่นใจกับของอร่อยมากมายรอบมหาวิทยาลัยแล้ว บรรยากาศที่ศูนย์ท่าพระจันทร์มันมีมนต์ขลังแปลก ๆ ตัวผมได้

By Chokchai
ทำไม System Analyst ถึงไม่เชื่อ Design จากทีม

ทำไม System Analyst ถึงไม่เชื่อ Design จากทีม

บ่อยครั้งที่ผมได้ยินน้อง ๆ ออดส์ทีม (ODT) เล่าว่า งานที่ทำอยู่ไม่ท้าทายเลย เพราะเพียงได้รับ Specification มาจาก System Analyst (SA) หรือ Tech Lead ที่เป็นพนักงาน แล้วน้องก็มีหน้าที่เขียนโค้ดตามนั้นไปอย่างเดียว บ่

By Chokchai