paint-brush
بهینه سازی تصاویر Docker چیزی فراتر از یک کار انجام شده استتوسط@aleksandrov
تاریخ جدید

بهینه سازی تصاویر Docker چیزی فراتر از یک کار انجام شده است

توسط Igor Alexandrov17m2025/01/30
Read on Terminal Reader

خیلی طولانی؛ خواندن

این مقاله بخشی از مجموعه پست‌هایی است که در آن تمام خطوط Dockerfile پیش‌فرض را مرور می‌کنم و بهترین روش‌ها و بهینه‌سازی‌ها را توضیح می‌دهم. مقاله اول فقط بهینه سازی کاهش اندازه تصویر را بررسی می کند.
featured image - بهینه سازی تصاویر Docker چیزی فراتر از یک کار انجام شده است
Igor Alexandrov HackerNoon profile picture
0-item


این مقاله بخشی از مجموعه پست‌هایی است که در آن تمام خطوط Dockerfile پیش‌فرض Rails را طی می‌کنم و بهترین روش‌ها و بهینه‌سازی‌ها را توضیح می‌دهم.


تصاویر Docker را می‌توان به روش‌های مختلفی بهینه کرد که شامل کاهش اندازه تصویر، بهینه‌سازی عملکرد ساخت، بهترین شیوه‌های امنیت و قابلیت نگهداری، و بهینه‌سازی‌های ویژه برنامه‌ها می‌شود، اما محدود به آن نمی‌شود. در مقاله اول، من فقط بهینه سازی کاهش اندازه تصویر را لمس می کنم و دلیل اهمیت آنها را توضیح می دهم.

چرا اندازه تصویر را بهینه کنیم؟

مانند هر فرآیند دیگر توسعه نرم‌افزار، هر توسعه‌دهنده دلایل خود را فهرست می‌کند که چرا می‌خواهد ساخت‌های Docker خود را سریع‌تر کند. من دلایلی را که برای من مهم هستند فهرست می کنم.

ساخت و استقرار سریعتر

تصاویر کوچکتر سریعتر ساخته می شوند زیرا فایل ها و لایه های کمتری باید پردازش شوند. این کار بهره وری توسعه دهندگان را به ویژه در طول چرخه های توسعه تکراری بهبود می بخشد. عکس‌های کوچک‌تر زمان کمتری می‌برند تا به رجیستری فشار داده شوند و در حین استقرار از آن خارج شوند. این امر به ویژه در خطوط لوله CI/CD که کانتینرها اغلب ساخته و مستقر می شوند بسیار مهم است.

کاهش هزینه های ذخیره سازی و استفاده از پهنای باند شبکه

تصاویر کوچکتر ذخیره کمتری را در رجیستری های کانتینر، ماشین های توسعه محلی و سرورهای تولید مصرف می کنند. این امر هزینه های زیرساختی را به ویژه برای استقرار در مقیاس بزرگ کاهش می دهد. تصاویر کوچکتر هنگام انتقال بین سرورها از پهنای باند کمتری استفاده می کنند، به ویژه زمانی که تصاویر را به صورت محلی یا در خطوط لوله CI/CD می سازید و آنها را به یک رجیستری فشار می دهید.


ما در سال 2022 3.2 میلیون دلار در فضای ابری خرج کردیم... می‌خواهیم حدود 7 میلیون دلار در هزینه‌های سرور در طول پنج سال پس از خروج از ابر صرفه‌جویی کنیم.» دیوید هاین مایر هانسون - HEY World

بهبود عملکرد و امنیت

تصاویر کوچکتر برای بارگیری و اجرا به منابع کمتری (مثلاً CPU، RAM) نیاز دارند که عملکرد کلی برنامه‌های کانتینری را بهبود می‌بخشد. زمان‌های راه‌اندازی سریع‌تر به این معنی است که خدمات شما سریع‌تر آماده می‌شوند، که برای مقیاس‌پذیری و سیستم‌های در دسترس بسیار مهم است. تصاویر پایه حداقل مانند alpine یا debian-slim حاوی بسته‌های از پیش نصب شده کمتری هستند که خطر سوء استفاده از نرم‌افزارهای وصله نشده یا غیرضروری را کاهش می‌دهد.


علاوه بر همه موارد ذکر شده در بالا، حذف فایل‌ها و ابزارهای غیرضروری حواس‌پرتی را هنگام تشخیص مشکلات به حداقل می‌رساند و منجر به نگهداری بهتر و کاهش بدهی فنی می‌شود.

بررسی تصاویر داکر

برای دریافت پارامترهای مختلف تصویر، از جمله اندازه، می‌توانید به Docker Desktop نگاه کنید یا دستور docker images را در ترمینال اجرا کنید.


 ➜ docker images REPOSITORY TAG IMAGE ID CREATED SIZE kamal-dashboard latest 673737b771cd 2 days ago 619MB kamal-proxy latest 5f6cd8983746 6 weeks ago 115MB docs-server latest a810244e3d88 6 weeks ago 1.18GB busybox latest 63cd0d5fb10d 3 months ago 4.04MB postgres latest 6c9aa6ecd71d 3 months ago 456MB postgres 16.4 ced3ad69d60c 3 months ago 453MB


دانستن اندازه تصویر به شما تصویر کاملی نمی دهد. شما نمی دانید داخل تصویر چیست، چند لایه دارد یا هر لایه چقدر بزرگ است. لایه تصویر داکر یک لایه سیستم فایل غیرقابل تغییر و فقط خواندنی است که جزئی از تصویر داکر است. هر لایه نشان دهنده مجموعه ای از تغییرات ایجاد شده در سیستم فایل تصویر است، مانند افزودن فایل ها، تغییر تنظیمات یا نصب نرم افزار.


تصاویر Docker به صورت تدریجی، لایه به لایه ساخته می شوند و هر لایه مطابق با یک دستورالعمل در Dockerfile است. برای دریافت لایه های تصویر، می توانید دستور docker history را اجرا کنید.


 ➜ docker history kamal-dashboard:latest IMAGE CREATED CREATED BY SIZE COMMENT 673737b771cd 4 days ago CMD ["./bin/thrust" "./bin/rails" "server"] 0B buildkit.dockerfile.v0 <missing> 4 days ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0 <missing> 4 days ago ENTRYPOINT ["/rails/bin/docker-entrypoint"] 0B buildkit.dockerfile.v0 <missing> 4 days ago USER 1000:1000 0B buildkit.dockerfile.v0 <missing> 4 days ago RUN /bin/sh -c groupadd --system --gid 1000 … 54MB buildkit.dockerfile.v0 <missing> 4 days ago COPY /rails /rails # buildkit 56.2MB buildkit.dockerfile.v0 <missing> 4 days ago COPY /usr/local/bundle /usr/local/bundle # b… 153MB buildkit.dockerfile.v0 <missing> 4 days ago ENV RAILS_ENV=production BUNDLE_DEPLOYMENT=1… 0B buildkit.dockerfile.v0 <missing> 4 days ago RUN /bin/sh -c apt-get update -qq && apt… 137MB buildkit.dockerfile.v0 <missing> 4 days ago WORKDIR /rails 0B buildkit.dockerfile.v0 <missing> 3 weeks ago CMD ["irb"] 0B buildkit.dockerfile.v0 <missing> 3 weeks ago RUN /bin/sh -c set -eux; mkdir "$GEM_HOME";… 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV PATH=/usr/local/bundle/bin:/usr/local/sb… 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV BUNDLE_SILENCE_ROOT_WARNING=1 BUNDLE_APP… 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV GEM_HOME=/usr/local/bundle 0B buildkit.dockerfile.v0 <missing> 3 weeks ago RUN /bin/sh -c set -eux; savedAptMark="$(a… 78.1MB buildkit.dockerfile.v0 <missing> 3 weeks ago ENV RUBY_DOWNLOAD_SHA256=018d59ffb52be3c0a6d… 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV RUBY_DOWNLOAD_URL=https://cache.ruby-lan… 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV RUBY_VERSION=3.4.1 0B buildkit.dockerfile.v0 <missing> 3 weeks ago ENV LANG=C.UTF-8 0B buildkit.dockerfile.v0 <missing> 3 weeks ago RUN /bin/sh -c set -eux; mkdir -p /usr/loca… 19B buildkit.dockerfile.v0 <missing> 3 weeks ago RUN /bin/sh -c set -eux; apt-get update; a… 43.9MB buildkit.dockerfile.v0 <missing> 3 weeks ago # debian.sh --arch 'arm64' out/ 'bookworm' '… 97.2MB debuerreotype 0.15


از آنجایی که من قبلاً نظریه ای در مورد تصاویر و لایه ها ارائه کرده ام، زمان آن رسیده است که Dockerfile را بررسی کنیم. با شروع از Rails 7.1، Dockerfile با برنامه جدید Rails تولید می شود. در زیر نمونه ای از آنچه ممکن است به نظر برسد آورده شده است.


 # syntax=docker/dockerfile:1 # check=error=true # Make sure RUBY_VERSION matches the Ruby version in .ruby-version ARG RUBY_VERSION=3.4.1 FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base # Rails app lives here WORKDIR /rails # Install base packages # Replace libpq-dev with sqlite3 if using SQLite, or libmysqlclient-dev if using MySQL RUN apt-get update -qq && \ apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives # Set production environment ENV RAILS_ENV="production" \ BUNDLE_DEPLOYMENT="1" \ BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_WITHOUT="development" # Throw-away build stage to reduce size of final image FROM base AS build # Install packages needed to build gems RUN apt-get update -qq && \ apt-get install --no-install-recommends -y build-essential curl git pkg-config libyaml-dev && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives # Install application gems COPY Gemfile Gemfile.lock ./ RUN bundle install && \ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ bundle exec bootsnap precompile --gemfile # Copy application code COPY . . # Precompile bootsnap code for faster boot times RUN bundle exec bootsnap precompile app/ lib/ # Precompiling assets for production without requiring secret RAILS_MASTER_KEY RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile # Final stage for app image FROM base # Copy built artifacts: gems, application COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" COPY --from=build /rails /rails # Run and own only the runtime files as a non-root user for security RUN groupadd --system --gid 1000 rails && \ useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ chown -R rails:rails db log storage tmp USER 1000:1000 # Entrypoint prepares the database. ENTRYPOINT ["/rails/bin/docker-entrypoint"] # Start server via Thruster by default, this can be overwritten at runtime EXPOSE 80 CMD ["./bin/thrust", "./bin/rails", "server"]


در زیر فهرستی از رویکردها و قوانینی را که در Dockerfile بالا اعمال می‌شود تا اندازه تصویر نهایی کارآمد باشد، ارائه خواهم داد.

بهینه سازی نصب بسته ها

من مطمئن هستم که فقط نرم افزارهای مورد نیاز را در دستگاه توسعه محلی خود نگه می دارید. همین امر باید در مورد تصاویر داکر نیز اعمال شود. در مثال‌های زیر، من دائماً Dockerfile استخراج‌شده از Rails Dockerfile بالا را بدتر می‌کنم. من آن را به عنوان نسخه اصلی Dockerfile ارجاع خواهم داد.

قانون شماره 1: از حداقل تصاویر پایه استفاده کنید

 FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base


تصویر پایه نقطه شروع Dockerfile است. این تصویری است که برای ایجاد ظرف استفاده می شود. تصویر پایه اولین لایه در Dockerfile است و تنها لایه ای است که توسط خود Dockerfile ایجاد نشده است.


تصویر پایه با دستور FROM و به دنبال آن نام و تگ تصویر مشخص می شود. تگ اختیاری است و اگر مشخص نشده باشد از latest تگ استفاده می شود. تصویر پایه می تواند هر تصویر موجود در Docker Hub یا هر رجیستری دیگر باشد.


در Dockerfile about، ما از تصویر ruby با تگ 3.4.1-slim استفاده می کنیم. تصویر ruby ، تصویر رسمی روبی موجود در داکر هاب است. تگ 3.4.1-slim یک نسخه باریک از تصویر Ruby است که بر اساس تصویر debian-slim ساخته شده است. در حالی که تصویر debian-slim یک نسخه حداقلی از تصویر Debian Linux است که برای اندازه بهینه شده است. به جدول زیر نگاه کنید تا متوجه شوید که تصویر slim چقدر کوچکتر است.


 ➜ docker images --filter "reference=ruby" REPOSITORY TAG IMAGE ID CREATED SIZE ruby 3.4.1-slim 0bf957e453fd 5 days ago 219MB ruby 3.4.1-alpine cf9b1b8d4a0c 5 days ago 99.1MB ruby 3.4.1-bookworm 1e77081540c0 5 days ago 1.01GB


از ژانویه 2024، نسخه فعلی دبیان کتاب کرم و نسخه قبلی bullseye نام دارد.


219 مگابایت به جای 1 گیگابایت - یک تفاوت بزرگ. اما اگر تصویر alpine حتی کوچکتر باشد چه؟ تصویر alpine بر اساس توزیع آلپاین لینوکس است که یک توزیع لینوکس فوق العاده سبک است که برای اندازه و امنیت بهینه شده است. Alpine از کتابخانه musl (به جای glibc ) و busybox (مجموعه فشرده ای از ابزارهای یونیکس) به جای همتایان GNU استفاده می کند. در حالی که از نظر فنی امکان استفاده از تصویر alpine برای اجرای Rails وجود دارد، در این مقاله به آن نمی پردازم.

قانون شماره 2: لایه ها را به حداقل برسانید

 RUN apt-get update -qq && \ apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev && \ rm -rf /var/lib/apt/lists /var/cache/apt/archives


هر دستور RUN ، COPY و FROM در Dockerfile یک لایه جدید ایجاد می کند. هرچه لایه های بیشتری داشته باشید، اندازه تصویر بزرگتر است. به همین دلیل است که بهترین تمرین ترکیب چند دستور در یک دستورالعمل RUN است. برای نشان دادن این موضوع، اجازه دهید به مثال زیر نگاه کنیم.


 # syntax=docker/dockerfile:1 # check=error=true # Make sure RUBY_VERSION matches the Ruby version in .ruby-version ARG RUBY_VERSION=3.4.1 FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base RUN apt-get update -qq RUN apt-get install --no-install-recommends -y curl RUN apt-get install --no-install-recommends -y libjemalloc2 RUN apt-get install --no-install-recommends -y libvips RUN apt-get install --no-install-recommends -y libpq-dev RUN rm -rf /var/lib/apt/lists /var/cache/apt/archives CMD ["echo", "Whalecome!"]


من دستورالعمل RUN را به چندین خط تقسیم کرده ام که بدیهی است آنها را برای انسان قابل خواندن تر می کند. اما چگونه بر اندازه تصویر تأثیر می گذارد؟ بیایید تصویر را بسازیم و آن را بررسی کنیم.


 ➜ time docker build -t no-minimize-layers --no-cache -f no-minimize-layers.dockerfile . 0.31s user 0.28s system 2% cpu 28.577 total


ساخت تصویر 28 ثانیه طول کشید، در حالی که ساخت نسخه اصلی با لایه های کمینه تنها 19 ثانیه طول می کشد ( تقریباً 33٪ سریعتر ).


 ➜ time docker build -t original --no-cache -f original.dockerfile . 0.25s user 0.28s system 2% cpu 19.909 total


بیایید اندازه تصاویر را بررسی کنیم.


 ➜ docker images --filter "reference=*original*" --filter "reference=*no-minimize*" REPOSITORY TAG IMAGE ID CREATED SIZE original latest f1363df79c8a 8 seconds ago 356MB no-minimize-layers latest ad3945c8a8ee 43 seconds ago 379MB


تصویر با لایه های کوچک شده 23 مگابایت کوچکتر از تصویر بدون لایه های کوچک است. این کاهش 6 درصدی در اندازه است. در حالی که به نظر می رسد یک تفاوت کوچک در این مثال باشد، اگر تمام دستورالعمل های RUN را به چندین خط تقسیم کنید، تفاوت بسیار بزرگتر خواهد بود.

قانون شماره 3: فقط موارد مورد نیاز را نصب کنید

به طور پیش‌فرض، apt-get install بسته‌های پیشنهادی و همچنین بسته‌هایی را که از آن خواسته‌اید نصب کند، نصب می‌کند. گزینه --no-install-recommends به apt-get می گوید که فقط بسته هایی را که به صراحت مشخص شده اند و نه بسته های توصیه شده را نصب کند.


 ➜ time docker build -t without-no-install-recommends --no-cache -f without-no-install-recommends.dockerfile . 0.33s user 0.30s system 2% cpu 29.786 total ➜ docker images --filter "reference=*original*" --filter "reference=*recommends*" REPOSITORY TAG IMAGE ID CREATED SIZE without-no-install-recommends latest 41e6e37f1e2b 3 minutes ago 426MB minimize-layers latest dff22c85d84c 17 minutes ago 356MB


همانطور که می بینید، تصویر بدون --no-install-recommends 70 مگابایت بزرگتر از تصویر اصلی است. این افزایش 16 درصدی در اندازه است.


برای مشاهده فایل هایی که به تصویر اضافه شده اند از ابزار dive استفاده کنید - در پایان مقاله در مورد آن بیشتر بخوانید.

قانون شماره 4: بعد از نصب تمیز کنید

Dockerfile اصلی شامل دستور rm -rf /var/lib/apt/lists/* /var/cache/apt/archives بعد از دستور apt-get install است. این دستور لیست های بسته و آرشیوهایی را که پس از نصب دیگر مورد نیاز نیستند حذف می کند. بیایید ببینیم که چگونه بر اندازه تصویر تأثیر می گذارد، برای رسیدن به آن، یک Dockerfile جدید بدون دستور پاکسازی ایجاد می کنم.


 RUN apt-get update -qq && \ apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev


ساختن تصاویر تقریباً به همان زمان اولیه نیاز دارد که منطقی است.


 ➜ time docker build -t without-cleaning --no-cache -f without-cleaning.dockerfile . 0.28s user 0.30s system 2% cpu 21.658 total


بیایید اندازه تصاویر را بررسی کنیم.


 ➜ docker images --filter "reference=*original*" --filter "reference=*cleaning*" REPOSITORY TAG IMAGE ID CREATED SIZE without-cleaning latest 52884fe50773 2 minutes ago 375MB original latest f1363df79c8a 16 minutes ago 356MB


تصویر بدون تمیز کردن 19 مگابایت بزرگتر از تصویر با تمیز کردن است، این افزایش 5 درصدی در اندازه است.

بدترین سناریو

اگر هر چهار بهینه سازی ذکر شده در بالا اعمال نشود چه؟ بیایید یک Dockerfile جدید بدون هیچ بهینه سازی ایجاد کنیم و تصویر را بسازیم.


 # syntax=docker/dockerfile:1 # check=error=true ARG RUBY_VERSION=3.4.1 FROM docker.io/library/ruby:$RUBY_VERSION AS base RUN apt-get update -qq RUN apt-get install -y curl RUN apt-get install -y libjemalloc2 RUN apt-get install -y libvips RUN apt-get install -y libpq-dev CMD ["echo", "Whalecome!"]


 ➜ time docker build -t without-optimizations --no-cache -f without-optimizations.dockerfile . 0.46s user 0.45s system 1% cpu 1:02.21 total


وای، بیش از یک دقیقه طول کشید تا تصویر ساخته شود.


 ➜ docker images --filter "reference=*original*" --filter "reference=*without-optimizations*" REPOSITORY TAG IMAGE ID CREATED SIZE without-optimizations latest 45671929c8e4 2 minutes ago 1.07GB original latest f1363df79c8a 27 hours ago 356MB


تصویر بدون بهینه سازی 714 مگابایت بزرگتر از تصویر اصلی است، این افزایش 200 درصدی در اندازه است. این به وضوح نشان می‌دهد که بهینه‌سازی Dockerfile چقدر مهم است، تصاویر بزرگ‌تر زمان بیشتری را برای ساختن و مصرف فضای دیسک بیشتر می‌برند.

همیشه از .dockerignore استفاده کنید

فایل .dockerignore شبیه فایل .gitignore است که توسط Git استفاده می شود. برای حذف فایل ها و دایرکتوری ها از متن ساخت استفاده می شود. Context مجموعه ای از فایل ها و دایرکتوری ها است که هنگام ساخت یک تصویر به Daemon Docker ارسال می شود. متن به صورت تاربال به داکر دیمون ارسال می شود، بنابراین مهم است که آن را تا حد امکان کوچک نگه دارید.


اگر به هر دلیلی فایل .dockerignore را در پروژه خود ندارید، می توانید آن را به صورت دستی ایجاد کنید. پیشنهاد می کنم از الگوی رسمی فایل Rails .dockerignore به عنوان نقطه شروع استفاده کنید. در زیر نمونه ای از آنچه ممکن است به نظر برسد آورده شده است.


 # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. # Ignore git directory. /.git/ /.gitignore # Ignore bundler config. /.bundle # Ignore all environment files. /.env* # Ignore all default key files. /config/master.key /config/credentials/*.key # Ignore all logfiles and tempfiles. /log/* /tmp/* !/log/.keep !/tmp/.keep # Ignore pidfiles, but keep the directory. /tmp/pids/* !/tmp/pids/.keep # Ignore storage (uploaded files in development and any SQLite databases). /storage/* !/storage/.keep /tmp/storage/* !/tmp/storage/.keep # Ignore assets. /node_modules/ /app/assets/builds/* !/app/assets/builds/.keep /public/assets # Ignore CI service files. /.github # Ignore development files /.devcontainer # Ignore Docker-related files /.dockerignore /Dockerfile*


وجود یک فایل .dockerfile در پروژه نه تنها امکان حذف فایل‌ها و دایرکتوری‌های غیرضروری (مثلاً گردش‌های کاری GitHub از پوشه .github یا وابستگی‌های جاوا اسکریپت از node_modules ) را از زمینه فراهم می‌کند. همچنین به جلوگیری از افزودن تصادفی اطلاعات حساس به تصویر کمک می کند. به عنوان مثال، فایل .env که حاوی متغیرهای محیطی است یا فایل master.key که برای رمزگشایی اعتبارنامه ها استفاده می شود.

از Dive استفاده کنید

همه بهینه‌سازی‌های ذکر شده در بالا ممکن است هنگام توضیح واضح به نظر برسند. اگر از قبل تصویری عظیم دارید و نمی دانید از کجا شروع کنید، چه کاری باید انجام دهید؟


ابزار مورد علاقه و مفید من Dive است. Dive یک ابزار TUI برای کاوش تصویر Docker، محتویات لایه و کشف راه‌هایی برای کوچک کردن اندازه تصویر است. Dive را می توان با مدیریت بسته سیستم خود نصب کرد، یا می توانید از تصویر رسمی Docker آن برای اجرای آن استفاده کنید. بیایید از تصویر بدترین سناریوی خود استفاده کنیم.


 docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest without-optimizations 


ابزار بازرسی لایه های داکر Dive

در تصویر بالا، می توانید بررسی غیربهینه ترین تصویر ما را مشاهده کنید. Dive اندازه هر لایه، اندازه کلی تصویر و فایل هایی که در هر لایه تغییر کرده اند (اضافه شده، اصلاح یا حذف شده اند) را نشان می دهد. برای من، این مفیدترین ویژگی Dive است. با فهرست کردن فایل‌ها در پنل سمت راست، می‌توانید به راحتی فایل‌هایی را که مورد نیاز نیستند شناسایی کنید و دستوراتی را که آنها را به تصویر اضافه می‌کنند حذف کنید.


یکی از چیزهایی که من واقعاً در مورد Dive دوست دارم این است که علاوه بر داشتن رابط کاربری ترمینال، می‌تواند خروجی سازگار با CI را نیز ارائه دهد که می‌تواند در توسعه محلی نیز مؤثر باشد. برای استفاده از آن، Dive را با متغیر محیطی CI روی true اجرا کنید، خروجی دستور در تصویر زیر است.


 docker run -e CI=true --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest without-optimizations 


خروجی مناسب CI

ترجیح شخصی من این است که از Dive به صورت برنامه ریزی شده استفاده کنم، به عنوان مثال، یک بار در هفته، تا مطمئن شوم که تصاویر شما هنوز در شکل خوبی هستند. در مقاله‌های آینده، گردش‌های کاری خودکاری را که برای بررسی Dockerfile خود استفاده می‌کنم، شامل Dive و Hadolint پوشش خواهم داد.

لایه ها را له نکنید

یکی از روش‌هایی که برای به حداقل رساندن اندازه تصویر دیده‌ام، تلاش برای له کردن لایه‌ها است. ایده این بود که چندین لایه را در یک لایه ترکیب کنیم تا اندازه تصویر کاهش یابد. Docker یک گزینه آزمایشی داشت --squash ، علاوه بر این، ابزارهای شخص ثالث مانند docker-squash وجود داشت.


در حالی که این رویکرد در گذشته کار می کرد، در حال حاضر منسوخ شده است و استفاده از آن توصیه نمی شود. له کردن لایه ها ویژگی اساسی Docker در کش کردن لایه ها را از بین برد. جدای از آن، هنگام استفاده از --squash می‌توانید ناخواسته فایل‌های حساس یا موقتی از لایه‌های قبلی را در تصویر نهایی قرار دهید. این یک رویکرد همه یا هیچ است که فاقد کنترل دقیق است.


به جای له کردن لایه ها، توصیه می شود از ساخت های چند مرحله ای استفاده کنید. Rails Dockerfile در حال حاضر از ساخت های چند مرحله ای استفاده می کند، در مقاله بعدی نحوه عملکرد آن را توضیح خواهم داد.

نتیجه گیری

بهینه سازی تصاویر Docker، درست مانند هر بهینه سازی دیگری، یک بار انجام نمی شود و فراموش می شود . این یک فرآیند مداوم است که نیاز به بررسی و بهبود منظم دارد. من سعی کردم اصول اولیه را پوشش دهم، اما دانستن و درک آنها حیاتی است. در مقاله‌های بعدی، تکنیک‌ها و ابزارهای پیشرفته‌تری را پوشش خواهم داد که می‌توانند به ساخت سریع‌تر و کارآمدتر Docker شما کمک کنند.

L O A D I N G
. . . comments & more!

About Author

Igor Alexandrov HackerNoon profile picture
Igor Alexandrov@aleksandrov
Ruby/Crystal developer, JetRockets and OneTribe CTO and co-founder

برچسب ها را آویزان کنید

این مقاله در ارائه شده است...