<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:yandex="http://news.yandex.ru" xmlns:media="http://search.yahoo.com/mrss/" xmlns:turbo="http://turbo.yandex.ru">
  <channel>
    <title>BestPractices on OldTyT</title>
    <link>https://oldtyt.xyz/ru/categories/bestpractices/</link>
    <description>Recent content in BestPractices on OldTyT</description>
    <image>
      <title>OldTyT</title>
      <url>https://oldtyt.xyz/papermod-cover.png</url>
      <link>https://oldtyt.xyz/papermod-cover.png</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <atom:link href="https://oldtyt.xyz/ru/categories/bestpractices/index.xml" rel="self" type="application/rss+xml" />
    <item turbo="true">
      <title>Docker best practices</title>
      <turbo:topic>Docker best practices</turbo:topic>
      <link>https://oldtyt.xyz/ru/posts/docker_best_practices/</link>
      <turbo:source>https://oldtyt.xyz/ru/posts/docker_best_practices/</turbo:source>
      <pubDate>Mon, 29 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://oldtyt.xyz/ru/posts/docker_best_practices/</guid>
      <description>Docker best practices</description>
      <turbo:content><![CDATA[<p>В рамках данной статьи будут рассмотрены наиболее частые антипаттерны при проектировании docker образов, а так же будет представлено оптимальное решение для каждого</p>
<h2 id="использование-избыточного-базового-образа">Использование избыточного базового образа</h2>
<p>Один из распространенных антипаттернов при использовании Docker - это использование избыточного базового образа.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span></code></pre></div><p>Оптимальное решение - использовать наиболее легковесный базовый образ, который содержит только необходимые компоненты, в роли которого может выступать alpine.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span></code></pre></div><p>Сравнение размера двух образов:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@gusev:~# docker image ls
</span></span><span class="line"><span class="cl">REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
</span></span><span class="line"><span class="cl">alpine       latest    8ca4688f4f35   <span class="m">9</span> days ago    7.34MB
</span></span><span class="line"><span class="cl">ubuntu       latest    3565a89d9e81   <span class="m">13</span> days ago   77.8MB
</span></span></code></pre></div><h2 id="множество-инструкций">Множество инструкций</h2>
<p>Из-за особенностей работы docker, каждая выполненная инструкция - выполняет &ldquo;снэпшот&rdquo; состояния файловой системы контейнера на текущий момент, так что следует уменьшать количество этих самых инструкций.
Пример плохой реализации Dockerfil&rsquo;a:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt install -y nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt install -y curl<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> touch /my_file<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> chmod +x /my_file<span class="err">
</span></span></span></code></pre></div><p>Оптимальным вариантом будет следующий:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y nginx <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y curl <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    touch /my_file <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    chmod +x /my_file<span class="err">
</span></span></span></code></pre></div><h2 id="не-оптимальная-установка-пакетов">Не оптимальная установка пакетов</h2>
<p>Часто можно наблюдать в Dockerfile такую конструкцию:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk update <span class="o">&amp;&amp;</span> <span class="se">\ </span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span>    apk add curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>Данная конструкция не является оптимальной, т.к. выполняется обновление локальных кэшей, а это занимает драгоценное место, оптимальным решением будет следующее:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>В случае, если используется пакетный менеджер apt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y curl wget nginx <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    rm -rf /var/lib/apt/lists/*<span class="err">
</span></span></span></code></pre></div><h2 id="использование-последних-версий">Использование последних версий</h2>
<p>Зачастую в Dockerfile можно часто встретить конструкции по типу:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>Эта конструкция является плохой, т.к. через время, может появиться необходимость пересобрать контейнер, но вероятно возникнет ошибка из-за того, что были обновлены артефакты которые используются при сборке. Оптимальный вариант:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache <span class="nv">curl</span><span class="o">==</span>8.3.0-r0 <span class="nv">wget</span><span class="o">==</span>1.21.4-r0 <span class="nv">nginx</span><span class="o">==</span>1.24.0-r6<span class="err">
</span></span></span></code></pre></div><h2 id="multi-stage-сборки">Multi-stage сборки</h2>
<p>В Docker есть возможность реализовать multi-stage сборки, если кратко, то суть сводится к тому, что в Dockerfile описывается множество этапов, причем из каждого артефакты передаются в следующие. Отказ от использования такой возможности, может сильно увеличить размер конечного образа.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app_tmp</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><p>Оптимальным же решением будет следующее:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4 as builder</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app_out --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> --from<span class="o">=</span>builder /app_out /app<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><h2 id="healthcheck">Healthcheck</h2>
<p>Healthcheck - это инструкция, которую Docker может использовать для проверки работоспособности запущенного контейнера.
По большей части healthcheck проверяют доступность страницы/порта приложения. Один из вариантов реализации:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="k">FROM</span><span class="s"> alpine:3.18.4 as builder</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app_out --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> --from<span class="o">=</span>builder /app_out /app<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">HEALTHCHECK --interval=5s --timeout=10s --retries=3 </span><span class="k">CMD</span> curl -IL 127.0.0.1 <span class="p">|</span> grep <span class="m">200</span> <span class="o">||</span> <span class="nb">exit</span> <span class="m">1</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div>]]>
      </turbo:content>
      <yandex:full-text><![CDATA[<p>В рамках данной статьи будут рассмотрены наиболее частые антипаттерны при проектировании docker образов, а так же будет представлено оптимальное решение для каждого</p>
<h2 id="использование-избыточного-базового-образа">Использование избыточного базового образа</h2>
<p>Один из распространенных антипаттернов при использовании Docker - это использование избыточного базового образа.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span></code></pre></div><p>Оптимальное решение - использовать наиболее легковесный базовый образ, который содержит только необходимые компоненты, в роли которого может выступать alpine.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span></code></pre></div><p>Сравнение размера двух образов:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">root@gusev:~# docker image ls
</span></span><span class="line"><span class="cl">REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
</span></span><span class="line"><span class="cl">alpine       latest    8ca4688f4f35   <span class="m">9</span> days ago    7.34MB
</span></span><span class="line"><span class="cl">ubuntu       latest    3565a89d9e81   <span class="m">13</span> days ago   77.8MB
</span></span></code></pre></div><h2 id="множество-инструкций">Множество инструкций</h2>
<p>Из-за особенностей работы docker, каждая выполненная инструкция - выполняет &ldquo;снэпшот&rdquo; состояния файловой системы контейнера на текущий момент, так что следует уменьшать количество этих самых инструкций.
Пример плохой реализации Dockerfil&rsquo;a:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt install -y nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt install -y curl<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> touch /my_file<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> chmod +x /my_file<span class="err">
</span></span></span></code></pre></div><p>Оптимальным вариантом будет следующий:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y nginx <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y curl <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    touch /my_file <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    chmod +x /my_file<span class="err">
</span></span></span></code></pre></div><h2 id="не-оптимальная-установка-пакетов">Не оптимальная установка пакетов</h2>
<p>Часто можно наблюдать в Dockerfile такую конструкцию:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk update <span class="o">&amp;&amp;</span> <span class="se">\ </span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span>    apk add curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>Данная конструкция не является оптимальной, т.к. выполняется обновление локальных кэшей, а это занимает драгоценное место, оптимальным решением будет следующее:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>В случае, если используется пакетный менеджер apt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> ubuntu</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apt update <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    apt install -y curl wget nginx <span class="o">&amp;&amp;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>    rm -rf /var/lib/apt/lists/*<span class="err">
</span></span></span></code></pre></div><h2 id="использование-последних-версий">Использование последних версий</h2>
<p>Зачастую в Dockerfile можно часто встретить конструкции по типу:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>Эта конструкция является плохой, т.к. через время, может появиться необходимость пересобрать контейнер, но вероятно возникнет ошибка из-за того, что были обновлены артефакты которые используются при сборке. Оптимальный вариант:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache <span class="nv">curl</span><span class="o">==</span>8.3.0-r0 <span class="nv">wget</span><span class="o">==</span>1.21.4-r0 <span class="nv">nginx</span><span class="o">==</span>1.24.0-r6<span class="err">
</span></span></span></code></pre></div><h2 id="multi-stage-сборки">Multi-stage сборки</h2>
<p>В Docker есть возможность реализовать multi-stage сборки, если кратко, то суть сводится к тому, что в Dockerfile описывается множество этапов, причем из каждого артефакты передаются в следующие. Отказ от использования такой возможности, может сильно увеличить размер конечного образа.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Плохо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app_tmp</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><p>Оптимальным же решением будет следующее:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="c"># Хорошо</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4 as builder</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app_out --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> --from<span class="o">=</span>builder /app_out /app<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><h2 id="healthcheck">Healthcheck</h2>
<p>Healthcheck - это инструкция, которую Docker может использовать для проверки работоспособности запущенного контейнера.
По большей части healthcheck проверяют доступность страницы/порта приложения. Один из вариантов реализации:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-Dockerfile" data-lang="Dockerfile"><span class="line"><span class="cl"><span class="k">FROM</span><span class="s"> alpine:3.18.4 as builder</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> . .<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache hugo <span class="o">&amp;&amp;</span> hugo  --destination<span class="o">=</span>/app_out --baseURL<span class="o">=</span>https://oldtyt.xyz<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">FROM</span><span class="s"> alpine:3.18.4</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> --from<span class="o">=</span>builder /app_out /app<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">COPY</span> nginx.conf /etc/nginx/nginx.conf<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">WORKDIR</span><span class="s"> /app</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">RUN</span> apk add --no-cache curl nginx<span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err">HEALTHCHECK --interval=5s --timeout=10s --retries=3 </span><span class="k">CMD</span> curl -IL 127.0.0.1 <span class="p">|</span> grep <span class="m">200</span> <span class="o">||</span> <span class="nb">exit</span> <span class="m">1</span><span class="err">
</span></span></span><span class="line"><span class="cl"><span class="err"></span><span class="k">ENTRYPOINT</span> <span class="p">[</span><span class="s2">&#34;nginx&#34;</span><span class="p">,</span> <span class="s2">&#34;-g&#34;</span><span class="p">,</span> <span class="s2">&#34;daemon off;&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div>]]>
      </yandex:full-text>
    </item>
  </channel>
</rss>
