เมื่อใช้ Docker กับ Spring แล้ว CI เราไม่มี Java…

หลังจากได้มีโอกาสอ่านบทความของคุณ Phayao Boonon ไปวันก่อน เกี่ยวกับการสร้าง Image ของ Docker กับ Spring
แล้วคิดถึงโปรเจ็คเก่าที่เคยทำด้วย spring เหมือนกันที่ใช้ท่าเดียวกันกับพี่เค้า แต่พอดีบริษัทเก่าผมมีปัญหาคือ
ผมไม่สามารถ build docker โดยใช้ maven ได้เนื่องจาก CI-Server ของบริษัทไม่ได้ติดตั้ง java ไว้ (ใช้ gitlab runner) ทำให้ไม่มี maven มา build docker ให้ ซึ่งตอนแรกผมก็หาวิธีการต่างๆ มาแก้ไขปัญหาเพราะทีม Infra ไม่ได้ติดตั้ง java ให้ จนไปจบท่าสุดท้ายที่ใช้ Docker in Docker (ไม่รู้จะท่ายากไปไหน) กินเวลาไปเกือบสัปดาห์แต่สุดท้าย project นั้นก็ไม่ได้ทำให้เป็น Auto-Deploy รวมถึง project อื่นที่ทำด้วย java, spring ก็พับความฝันเรื่อง CI ไป
แต่พอได้อ่านบทความพี่เค้าแล้ว ผมก็ปิ้งขึ้นได้ว่า อะ! วันก่อนเพิ่งดู Docker Multi-Stage ไปนี่นา
ไม่รอช้าจัดการลอง Refactor Dockerfile ในทันที
จากไฟล์เก่า
# สมัยก่อนไม่ได้ใช้ alpine
FROM java:8VOLUME /tmpADD drools-0.0.1-SNAPSHOT.jar app.jarRUN bash -c 'touch /app.jar'ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
เพิ่มเป็น 2 stage
# stage 1 build ด้วย mvnw ( mvnw จะ download mvn ให้ auto ถ้าไม่มี)
FROM openjdk:8-jdk-alpineCOPY . /project/WORKDIR /project/RUN ./mvnw packageRUN ls /project/target/# stage 2 เอา jar file มารันFROM openjdk:8-jdk-alpineVOLUME /tmpENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]# copy file จาก stage ที่ 0 มาใช้COPY --from=0 /project/target/drools-0.0.1-SNAPSHOT.jar /app.jar
แล้วเปลี่ยนจากคำสั่ง
mvnw packageมาเป็น
docker build -f ./src/main/docker/Dockerfile -t <ชื่อ tag> .เท่านี้เราก็จะสามารถทำ Auto-Deploy ได้โดยไม่ต้องใช้ java แล้วนะครับ แต่มันจะ build ช้าๆ หน่อยเพราะ maven จะดึงใหม่ทุกครั้ง
แต่ถ้าไม่อยากรอ ให้มันทำ caching ลองใช้ maven plugin เพิ่มนะครับ
เรื่องนี้สอนให้รู้ว่า บางครั้งถ้า เรายังไม่เข้าใจเครื่องมือที่เราใช้ดีพอ อย่างที่ผมไม่เข้าใจ docker multi-stage ในวันนั้น ผมคงทำ Task นี้จบไปตั้งแต่ชม.แรกแล้ว…
ถ้ารู้สึกว่า เริ่มมีบางอย่างเริ่มซับซ้อน ต้องลองถอยไปมองภาพกว้างก่อนว่า มันซับซ้อน หรือ เราทำให้มันซับซ้อนเอง
