πŸ³πŸ”¨ Π‘Ρ‚Ρ€ΠΎΠΉΠ½Ρ‹Π΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹: ΠΊΠ°ΠΊ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Docker-ΠΎΠ±Ρ€Π°Π· с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ многоэтапной сборки

Docker-ΠΎΠ±Ρ€Π°Π·Ρ‹ часто ΡΡ‚Ρ€Π°Π΄Π°ΡŽΡ‚ ΠΎΡ‚ лишнСго вСса. Π­Ρ‚ΠΎ Π½Π΅ просто ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π·Π°Π½ΠΈΠΌΠ°Π΅ΠΌΠΎΠ³ΠΎ мСста – это вопрос бСзопасности ΠΈ эффСктивности. Но Π΅ΡΡ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅: многоэтапная сборка.

Π­Ρ‚ΠΎΡ‚ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» взят ΠΈΠ· нашСй СТСнСдСльной email-рассылки, посвящСнной бэкСнду. ΠŸΠΎΠ΄ΠΏΠΈΡˆΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π² числС ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, ΠΊΡ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ дайдТСст.

МногиС Dockerfile Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ Π² сСбя ΠΊΠ°ΠΊ зависимости для сборки прилоТСния, Ρ‚Π°ΠΊ ΠΈ зависимости для Π΅Π³ΠΎ выполнСния Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π² Ρ„ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ Docker-ΠΎΠ±Ρ€Π°Π·Ρ‹ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ ΠΊΡƒΠ΄Π° большС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‡Π΅ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ для запуска прилоТСния. А вСдь большиС ΠΎΠ±Ρ€Π°Π·Ρ‹ с Π½Π΅Π½ΡƒΠΆΠ½Ρ‹ΠΌΠΈ зависимостями Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ лишнСС мСсто, Π½ΠΎ ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ°ΡŽΡ‚ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ появлСния уязвимостСй.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ ΠΎΠ±Ρ€Π°Π·Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΈΠΌΠΈ большими

Π£ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π΅ΡΡ‚ΡŒ зависимости Π΄Π²ΡƒΡ… Ρ‚ΠΈΠΏΠΎΠ²:

  • Зависимости для сборки (build-time) – Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈ инструмСнты, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для компиляции ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ ΠΊ запуску.
  • Зависимости для выполнСния (run-time) – Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅.

Когда ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π· для сборки ΠΈ запуска, Ρ‚ΠΎ Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ½ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ лишниС инструмСнты – ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Ρ‹, компиляторы, Π»ΠΈΠ½Ρ‚Π΅Ρ€Ρ‹ ΠΈ Ρ‚.Π΄. Π˜Π·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этого ΠΌΠΎΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ раздСлСния этапов сборки ΠΈ выполнСния.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹Ρ… Dockerfile

Рассмотрим Dockerfile для Go ΠΈ Node.js ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, Π³Π΄Π΅ Π΄ΠΎΠΏΡƒΡ‰Π΅Π½Ρ‹ ошибки, приводящиС ΠΊ Π½Π΅Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ€Π°Π·Π΄ΡƒΠ²Π°Π½ΠΈΡŽ ΠΎΠ±Ρ€Π°Π·ΠΎΠ².

ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Dockerfile для Go-прилоТСния

Π—Π΄Π΅ΡΡŒ использован ΠΎΠ±Ρ€Π°Π· golang:1.23, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ скомпилированноС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½ΠΎ ΠΈ вСсь инструмСнтарий Go вмСстС с зависимостями – большС 800 Мб, мноТСство ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… становятся уязвимостями Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅:

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° этого Ρ€Π°Π·Π΄ΡƒΡ‚ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° выглядит Ρ‚Π°ΠΊ:

Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ этого увСсистого ΠΎΠ±Ρ€Π°Π·Π° Π½Π΅ Π½ΡƒΠΆΠ½Π° для запуска прилоТСния ΠΈ опасна Π² ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π΅

ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Dockerfile для Node.js-прилоТСния

Π—Π΄Π΅ΡΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ npm ci ΠΈ npm run build. ΠŸΠ΅Ρ€Π²Π°Ρ ΠΊΠΎΠΌΠ°Π½Π΄Π° устанавливаСт зависимости ΠΈ для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, ΠΈ для ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ΅Π½Π°. Но ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΡƒΠ±Ρ€Π°Ρ‚ΡŒ дСвСлопСрскиС зависимости ΠΊΠΎΠΌΠ°Π½Π΄Π° npm run build Π½Π΅ смоТСт Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒΡΡ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ для сборки Π½ΡƒΠΆΠ½Ρ‹ ΠΎΠ±Π° Ρ‚ΠΈΠΏΠ° зависимостСй:

Π’Π°ΠΊΠΎΠΉ Π΄ΠΎΠΊΠ΅Ρ€Ρ„Π°ΠΉΠ» создаСт ΠΎΠ±Ρ€Π°Π· с 500 Мб Π»ΠΈΡˆΠ½ΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²:

На долю самого прилоТСния Π² этом ΠΎΠ±Ρ€Π°Π·Π΅ приходится всСго 50 Мб

Как Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ многоэтапная сборка

ΠšΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡ многоэтапной сборки основана Π½Π° ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π΅ проСктирования Β«Π‘Ρ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΒ». Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ этот ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Docker, сначала Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ с двумя ΠΌΠΎΡ‰Π½Ρ‹ΠΌΠΈ возмоТностями Dockerfile – ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±Ρ€Π°Π·ΠΎΠ² Π² ΠΎΠ΄Π½ΠΎΠΌ Π΄ΠΎΠΊΠ΅Ρ€Ρ„Π°ΠΉΠ»Π΅.

ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π°

Одна ΠΈΠ· самых распространСнных инструкций Π² Dockerfile – это COPY. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для копирования Ρ„Π°ΠΉΠ»ΠΎΠ² с хоста Π² ΠΎΠ±Ρ€Π°Π·:

COPY host/path/to/file image/path/to/file

Однако Ρ„Π°ΠΉΠ»Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… Docker-ΠΎΠ±Ρ€Π°Π·ΠΎΠ². НапримСр, ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ nginx.conf ΠΈΠ· ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° nginx:latest прямо Π² свой Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±Ρ€Π°Π·:

COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf

ИмСнно Ρ„ΠΈΡ‡Π° COPY --from= ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Β«Π‘Ρ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΒ» – Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ создании ΠΎΠ±Ρ€Π°Π·Π° для Node.js:

# Основной ΠΎΠ±Ρ€Π°Π· для выполнСния прилоТСния
FROM node:lts-slim
# Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‡ΡƒΡŽ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ
WORKDIR /app
# ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ собранныС Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚Ρ‹ ΠΈΠ· Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° "build:v1"
COPY --from=build:v1 /app/.output .
# Настройки окруТСния
ENV NODE_ENV=production
EXPOSE 3000
# Команда запуска
CMD ["node", "/app/.output/index.mjs"]

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΎΠ±Ρ€Π°Π·ΠΎΠ² Π² ΠΎΠ΄Π½ΠΎΠΌ Dockerfile

Π‘ 2018 Π³ΠΎΠ΄Π° Docker ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎΡ†Π΅Π»Π΅Π²Ρ‹Π΅ Dockerfile: Π² ΠΎΠ΄Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ нСсколько инструкций FROM, каТдая ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… создаСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΎΠ±Ρ€Π°Π·. Π—Π΄Π΅ΡΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Ρ‚Ρ€ΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΎΠ±Ρ€Π°Π·Π° с ΠΈΡ… собствСнными настройками:

Π­Ρ‚Π° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ позволяСт Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ Ρ†Π΅Π»ΡŒ сборки с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° --target Π² ΠΊΠΎΠΌΠ°Π½Π΄Π΅ docker build, давая Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠΌΡƒ Dockerfile ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π·Ρ‹ Π² зависимости ΠΎΡ‚ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΉ Ρ†Π΅Π»ΠΈ:

Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π· Π½Π° основС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ FROM:

Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π· Π½Π° основС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ FROM:

Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π· Π½Π° основС Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅Π³ΠΎ FROM:

♾️ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° devops’a
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° devops’aΒ»
β™ΎοΈπŸŽ“ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° DevOps для собСса
ΠŸΠΎΠ΄Ρ‚ΡΠ½ΡƒΡ‚ΡŒ свои знания ΠΏΠΎ DevOps Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° DevOps для собСса»
β™ΎοΈπŸ§© Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ DevOps
Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ DevOps для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ DevOpsΒ»

Как ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ эти Π΄Π²Π΅ возмоТности для многоэтапной сборки

Dockerfile для сборки ΠΈ Dockerfile для выполнСния ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Π² ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» с нСсколькими инструкциями FROM. Π—Π΄Π΅ΡΡŒ Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΌ этапС происходит сборка прилоТСния с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ npm run build, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ этап ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ сборки ΠΈ запускаСт ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅:

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ:

  • ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ этапов ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. НСльзя Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ COPY --from ΠΈΠ· этапа, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ послС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ. Π­Ρ‚Π°ΠΏΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ описаны Π² логичСской ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.
  • Алиасы этапов. ИспользованиС AS (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, AS build) позволяСт Π΄Π°Ρ‚ΡŒ этапу понятноС имя, Π½ΠΎ ΠΈΡ… ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ: Ссли имя Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ΠΎ, Π½Π° этапы ΠΌΠΎΠΆΠ½ΠΎ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ ΠΏΠΎ ΠΈΡ… порядковому Π½ΠΎΠΌΠ΅Ρ€Ρƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, COPY --from=0).
  • По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ собираСтся послСдний этап. Если Π½Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ„Π»Π°Π³ --target, ΠΊΠΎΠΌΠ°Π½Π΄Π° docker build собСрСт послСдний этап ΠΈ всС этапы, ΠΎΡ‚ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ зависит.

НСсколько ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² многоэтапной сборки

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Go

Go-прилоТСния всСгда ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π° этапС сборки. Π˜Ρ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π΄Π²ΡƒΡ… Ρ‚ΠΈΠΏΠΎΠ²:

  1. БтатичСски связанный (собран с CGO_ENABLED=0) – всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ зависимости Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΡŒ самого Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ°. Π’Π°ΠΊΠΎΠΉ Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Π΄Π°ΠΆΠ΅ Π½Π° минималистичных Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΎΠ±Ρ€Π°Π·Π°Ρ…, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, gcr.io/distroless/static ΠΈΠ»ΠΈ scratch. ПослСдний – это Π²ΠΎΠΎΠ±Ρ‰Π΅ пустой ΠΎΠ±Ρ€Π°Π·, поэтому Π½ΡƒΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ остороТным ΠΏΡ€ΠΈ Π΅Π³ΠΎ использовании.
  2. ДинамичСски связанный (собран с CGO_ENABLED=1) – ΠΎΠ½ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Π½Π΅ΡˆΠ½ΠΈΡ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ стандартныС C-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. Для Π½Π΅Π³ΠΎ Π½ΡƒΠΆΠ΅Π½ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ эти Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ. НапримСр, это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ gcr.io/distroless/cc, alpine ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ debian.

Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв Π²Ρ‹Π±ΠΎΡ€ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° для этапа выполнСния Π½Π΅ мСняСт структуру многоэтапного Dockerfile – Π²Ρ‹ просто Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚Π΅ подходящий ΠΎΠ±Ρ€Π°Π· Π² зависимости ΠΎΡ‚ Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° Π±ΠΈΠ½Π°Ρ€Π½ΠΈΠΊΠ°:

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Rust

Rust-прилоТСния ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈΠ· исходного ΠΊΠΎΠ΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρ‹ cargo. ΠžΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Docker-ΠΎΠ±Ρ€Π°Π· для Rust Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ cargo, rustc (компилятор) ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ инструмСнты для Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ сборки. Из-Π·Π° этого Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΎΠ±Ρ€Π°Π·Π° получаСтся довольно большим – ΠΏΠΎΡ‡Ρ‚ΠΈ 2 Π“Π±. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ для Rust-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΌΠ½ΠΎΠ³ΠΎΡΡ‚Π°ΠΏΠ½ΡƒΡŽ сборку, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡ‚ΠΎΠ³ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π· для выполнСния прилоТСния Π±Ρ‹Π» ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½Ρ‹ΠΌ ΠΈ Π½Π΅ содСрТал Π»ΠΈΡˆΠ½ΠΈΡ… инструмСнтов. Π€ΠΈΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π·Π° для этапа выполнСния Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π½ΡƒΠΆΠ½Ρ‹ Π²Π°ΡˆΠ΅ΠΌΡƒ Rust-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡŽ:

ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Java

Java-прилоТСния ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΈΠ· исходного ΠΊΠΎΠ΄Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Maven ΠΈΠ»ΠΈ Gradle, ΠΈ для ΠΈΡ… выполнСния Π½ΡƒΠΆΠ½Π° Java Runtime Environment (JRE). Когда Java-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ запускаСтся Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Ρ€Π°Π·Π½Ρ‹Π΅ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ ΠΎΠ±Ρ€Π°Π·Ρ‹ для этапов сборки ΠΈ выполнСния. На этапС сборки Π½ΡƒΠΆΠ΅Π½ Java Development Kit (JDK), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ инструмСнты для компиляции ΠΈ ΡƒΠΏΠ°ΠΊΠΎΠ²ΠΊΠΈ ΠΊΠΎΠ΄Π°. А Π²ΠΎΡ‚ для этапа выполнСния достаточно Π±ΠΎΠ»Π΅Π΅ Π»Π΅Π³ΠΊΠΎΠΉ Java Runtime Environment (JRE), Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° содСрТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для запуска прилоТСния. Dockerfile выглядит Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ слоТнСС, Ρ‡Π΅ΠΌ сцСнарии для ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Go ΠΈ Rust, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ„Π°ΠΉΠ» для Java Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ этап тСстирования, Π΄Π° ΠΈ сам процСсс сборки Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ большС дСйствий:

***

А ΠΊΠ°ΠΊΠΈΠ΅ хитрости ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ Docker-ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Π²Ρ‹? ΠŸΠΎΠ΄Π΅Π»ΠΈΡ‚Π΅ΡΡŒ своим ΠΎΠΏΡ‹Ρ‚ΠΎΠΌ Π² коммСнтариях!

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

matyushkin
12 мая 2020

Как Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π²Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° Nginx Π² Docker πŸ³πŸ‘¨πŸ½β€πŸ’»

Π˜Π½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡ ΠΏΠΎ настройкС совмСстной Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π²Π΅Π±-прилоТСния ΠΈ сСрвСра Nginx Π² ...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
02 сСнтября 2017

10 популярных вопросов ΠΈ ΠΎΡ‚Π²Π΅Ρ‚ΠΎΠ² Π½Π° DevOps собСсСдовании

DevOps Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΊΠ°ΠΊ мост ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ, тСстированиСм ΠΈ эксплуатациСй Π²...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
12 июля 2017

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Docker, ΠΈ ΠΊΠ°ΠΊ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ? ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассказываСм

Π Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΏΠΎ косточкам, вСдь Docker – это ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт, ΠΈ ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ ΠΊΠΎΠ»ΠΈ...