وقتی میخواهیم اپلیکشن های Go رو containerize کنیم ساخت image ضروری است. build یک image با حجم زیاد به این معنی است که شما به دیتا های بیشتری برای انتقال بین image repository، CI/CD و deploy نیاز دارید. ایجاد یک image کوچکتر برای صرفه جویی در زمان ضروری است.
در این مطلب ، نحوه کاهش image کانتینر برنامه های Go خود را با استفاده از Docker بررسی خواهیم کرد.
یک برنامه با زبان Golang داریم به صورت زیر:
از پکیج httprouter استفاده کردیم تا از دستور go mod download در dockerfile استفاده کنیم.
یک Dockerfile میسازیم:
این Dockerfile رو با تگ example:initial بیلد میکنیم:
این image ایی که بیلد کردیم سایزش 337 مگ شد. حالا باید Dockerfile رو بهتر کنیم:
ساخت مولتی استیج به ما کمک می کند تا چیزهای بی اهمیت را در image پایه رها کنید و شروع به استفاده از یک image جدید برای اجرای برنامه های خود کنیم.
FROM golang:1.17.3-alpine3.14 as base
همانطور که می بینیم، می توانیم برای استیج های خودمون نام بذاریم، بنابراین اگر می خواهیم چیزهایی را از آن استیج کپی کنیم، می توانید نام استیج را در خط COPY وارد می کنیم.
می توانیم از یکdistroless image به عنوان image رانر خودمون برای کوچکتر کردن image خود استفاده کنید. همچنین برای برخی از زبان های برنامه نویسی دیگر نیز موجود است. با توجه به مستندات آن:
“Distroless” images contain only your application and its runtime dependencies. They do not contain package managers, shells or any other programs you would expect to find in a standard Linux distribution.
در مورد مثالی که از فلگ CGO_ENABLED=0 استفاده میکنید، میتوانید از gcr.io/distroless/static به عنوان یک image رانر استفاده کنید. اما اگر نیاز دارید که فلگ ها روشن باشند، باید از gcr.io/distroless/base با مراجعه به اسناد استفاده کنید.
بیایید دوباره بیلد کنیم و آن را به این صورت تگ میگذاریم example:multistage
بیاید باز هم image را بهتر کنیم:
ابزار UPX به ما کمک می کند اندازه باینری خودمون را کمتر کنیم، و تنها مختص برنامه های Go نیست. می توانید UPX را در خط 4 نصب کنید و برای استفاده از کش سازنده، دستور UPX را در خط 13 اجرا کنید. upx -9 به این معنی است که می خواهیم بهتر فشرده سازی کنیم، می توانید با استفاده از upx -h فلگ های موجود را ببینید.
داکرفایل خودمون رو با تگ example:with-upx بیلد میکنیم:
برای غیرفعال کردن symbol table و DWARF generation که قرار است دیتا هایی برای دیباگ ایجاد کند، فلگ های -ldflags "-s -w" را اضافه کنید. با استفاده از دستور go tool link -h می توانید سایر گزینه های موجود را مشاهده کنید.
بیایید dockerfile جدید رو با تگ example:latest بیلد کنیم:
همچنین میتوانید از مراحل این مطلب برای بیلد image کانتینر دیگری در کنار برنامههای Go استفاده کنید. به خصوص بیلد چند استیجی ای که بیش از نیمی از اندازه image را کاهش می دهد. اما با این حال، فقط شما می دانید چه چیزی برای شما بهترین است.
منابع:
https://jmrobles.medium.com/gos-best-friend-upx-the-executable-compressor-e4f4872f1d8a
https://medium.com/@treeder/multi-stage-docker-builds-for-creating-tiny-go-images-e0e1867efe5a