Optimize Docker Build

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

คนไม่ใช่สิ่งทดแทนกันได้ (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
เวลาอู้

เวลาอู้

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

By Chokchai