<?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>docker on OldTyT</title>
    <link>https://oldtyt.xyz/categories/docker/</link>
    <description>Recent content in docker 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/categories/docker/index.xml" rel="self" type="application/rss+xml" />
    <item turbo="true">
      <title>Docker best practices practices</title>
      <turbo:topic>Docker best practices practices</turbo:topic>
      <link>https://oldtyt.xyz/posts/docker_best_practices/</link>
      <turbo:source>https://oldtyt.xyz/posts/docker_best_practices/</turbo:source>
      <pubDate>Sun, 08 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://oldtyt.xyz/posts/docker_best_practices/</guid>
      <description>Docker best practices</description>
      <turbo:content><![CDATA[<p>Within the framework of this article, the most frequent antipatterns in the design of docker images will be considered, and the optimal solution for each will be presented.</p>
<h2 id="using-a-redundant-base-image">Using a redundant base image</h2>
<p>One of the common antipatterns when using Docker is the use of a redundant base image.</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"># Bad</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>The optimal solution is to use the most lightweight base image, which contains only the necessary components, which can act as 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"># Good</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>Comparing the size of two images:</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="lots-of-instructions">Lots of instructions</h2>
<p>Due to the peculiarities of docker&rsquo;s work, each executed instruction performs a &ldquo;snapshot&rdquo; of the state of the container&rsquo;s file system at the moment, so you should reduce the number of these very instructions, an example of a bad implementation of 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"># Bad</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>The best option would be the following:</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"># Good</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="not-optimal-package-installation">Not optimal package installation</h2>
<p>It is often possible to observe such a construction in 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"># Bad</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></span><span class="line"><span class="cl"><span class="se"></span>    apk add curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>This design is not optimal, because local caches are being updated, and this takes up precious space, the best solution would be the following:</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"># Good</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>In case the apt package manager is used:</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"># Good</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="using-the-latest-versions">Using the latest versions</h2>
<p>Often in Dockerfile you can often find constructions of the type:</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"># Bad</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>This design is bad, because after a while, it may be necessary to rebuild the container, but an error will probably occur due to the fact that the artifacts that are used during assembly have been updated. The best option:</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"># Good</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-builds">Multi-stage builds</h2>
<p>In Docker, it is possible to implement multi-stage builds, in short, the essence boils down to the fact that Dockerfile describes many stages, and artifacts are transferred from each to the next. Failure to use this feature can greatly increase the size of the final image.</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"># Bad</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>The optimal solution would be the following:</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"># Good</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>Health check is an instruction that Docker can use to check the health of a running container.
For the most part, healthcheck checks the availability of the page/port of the application. One of the implementation options:</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>Within the framework of this article, the most frequent antipatterns in the design of docker images will be considered, and the optimal solution for each will be presented.</p>
<h2 id="using-a-redundant-base-image">Using a redundant base image</h2>
<p>One of the common antipatterns when using Docker is the use of a redundant base image.</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"># Bad</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>The optimal solution is to use the most lightweight base image, which contains only the necessary components, which can act as 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"># Good</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>Comparing the size of two images:</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="lots-of-instructions">Lots of instructions</h2>
<p>Due to the peculiarities of docker&rsquo;s work, each executed instruction performs a &ldquo;snapshot&rdquo; of the state of the container&rsquo;s file system at the moment, so you should reduce the number of these very instructions, an example of a bad implementation of 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"># Bad</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>The best option would be the following:</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"># Good</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="not-optimal-package-installation">Not optimal package installation</h2>
<p>It is often possible to observe such a construction in 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"># Bad</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></span><span class="line"><span class="cl"><span class="se"></span>    apk add curl wget nginx<span class="err">
</span></span></span></code></pre></div><p>This design is not optimal, because local caches are being updated, and this takes up precious space, the best solution would be the following:</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"># Good</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>In case the apt package manager is used:</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"># Good</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="using-the-latest-versions">Using the latest versions</h2>
<p>Often in Dockerfile you can often find constructions of the type:</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"># Bad</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>This design is bad, because after a while, it may be necessary to rebuild the container, but an error will probably occur due to the fact that the artifacts that are used during assembly have been updated. The best option:</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"># Good</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-builds">Multi-stage builds</h2>
<p>In Docker, it is possible to implement multi-stage builds, in short, the essence boils down to the fact that Dockerfile describes many stages, and artifacts are transferred from each to the next. Failure to use this feature can greatly increase the size of the final image.</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"># Bad</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>The optimal solution would be the following:</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"># Good</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>Health check is an instruction that Docker can use to check the health of a running container.
For the most part, healthcheck checks the availability of the page/port of the application. One of the implementation options:</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>
    <item turbo="true">
      <title>Docker for the youngest</title>
      <turbo:topic>Docker for the youngest</turbo:topic>
      <link>https://oldtyt.xyz/posts/docker_for_the_youngest/</link>
      <turbo:source>https://oldtyt.xyz/posts/docker_for_the_youngest/</turbo:source>
      <pubDate>Sun, 08 Oct 2023 00:00:00 +0000</pubDate>
      <guid>https://oldtyt.xyz/posts/docker_for_the_youngest/</guid>
      <description>Docker for the youngest</description>
      <turbo:content><![CDATA[<p>To consolidate the material, it is recommended to execute the commands specified in the article</p>
<h2 id="introduction">Introduction</h2>
<p>Docker is a platform for developing, delivering, and running applications in containers. Containers are lightweight and isolated environments that allow you to run applications on any operating system without the need for additional dependencies. In this article, we will explore the basics of Docker and demonstrate how to use it for application development.</p>
<h2 id="installing-docker">Installing Docker</h2>
<p>Before you can start using Docker, you need to install it on your system. Follow the instructions on the official Docker website <a href="https://docs.docker.com/engine/install/">Docker</a> for detailed instructions for various operating systems.</p>
<h2 id="creating-a-container">Creating a Container</h2>
<p>After installing Docker, you are ready to create your containers. To do this, you will need a Dockerfile that describes the steps to create the container. Here is an example of a simple 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="k">FROM</span><span class="s"> alpine:latest</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;echo&#34;</span><span class="p">,</span> <span class="s2">&#34;Hello world!&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><p>In this example, we use the base image <a href="https://hub.docker.com/_/alpine">Alpine</a> and set the <a href="https://docs.docker.com/engine/reference/builder/#entrypoint">entrypoint command</a> to <code>echo &quot;Hello world!&quot;</code>.</p>
<h2 id="building-the-container">Building the Container</h2>
<p>To build the container image, execute the following command in the terminal:</p>
<pre tabindex="0"><code>docker build -t first_container:local .
</code></pre><p>This command will build a container image named <code>first_container</code> with the tag <code>local</code> based on the Dockerfile in the current directory.</p>
<h2 id="running-the-container">Running the Container</h2>
<p>After building the container, you can run it using the following command:</p>
<pre tabindex="0"><code>docker run --rm --name my_first_container first_container:local
</code></pre><p>This command will run the <code>first_container:local</code> container and execute the command specified in the Dockerfile&rsquo;s entrypoint.</p>
<h2 id="working-with-the-container">Working with the Container</h2>
<p>After running the container, you can interact with it by opening a terminal inside the container or executing commands within it. To do this, use the command:</p>
<pre tabindex="0"><code>docker exec -it my_first_container ash
</code></pre><p>This command will open an interactive terminal inside the <code>my_first_container</code> container.</p>
<p>But in this case, it will not be possible to execute, as the container dies after executing the echo command. To launch an interactive shell in the container, the following command needs to be executed:</p>
<pre tabindex="0"><code>docker run --rm --entrypoint ash -ti first_container:local
</code></pre>]]>
      </turbo:content>
      <yandex:full-text><![CDATA[<p>To consolidate the material, it is recommended to execute the commands specified in the article</p>
<h2 id="introduction">Introduction</h2>
<p>Docker is a platform for developing, delivering, and running applications in containers. Containers are lightweight and isolated environments that allow you to run applications on any operating system without the need for additional dependencies. In this article, we will explore the basics of Docker and demonstrate how to use it for application development.</p>
<h2 id="installing-docker">Installing Docker</h2>
<p>Before you can start using Docker, you need to install it on your system. Follow the instructions on the official Docker website <a href="https://docs.docker.com/engine/install/">Docker</a> for detailed instructions for various operating systems.</p>
<h2 id="creating-a-container">Creating a Container</h2>
<p>After installing Docker, you are ready to create your containers. To do this, you will need a Dockerfile that describes the steps to create the container. Here is an example of a simple 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="k">FROM</span><span class="s"> alpine:latest</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;echo&#34;</span><span class="p">,</span> <span class="s2">&#34;Hello world!&#34;</span><span class="p">]</span><span class="err">
</span></span></span></code></pre></div><p>In this example, we use the base image <a href="https://hub.docker.com/_/alpine">Alpine</a> and set the <a href="https://docs.docker.com/engine/reference/builder/#entrypoint">entrypoint command</a> to <code>echo &quot;Hello world!&quot;</code>.</p>
<h2 id="building-the-container">Building the Container</h2>
<p>To build the container image, execute the following command in the terminal:</p>
<pre tabindex="0"><code>docker build -t first_container:local .
</code></pre><p>This command will build a container image named <code>first_container</code> with the tag <code>local</code> based on the Dockerfile in the current directory.</p>
<h2 id="running-the-container">Running the Container</h2>
<p>After building the container, you can run it using the following command:</p>
<pre tabindex="0"><code>docker run --rm --name my_first_container first_container:local
</code></pre><p>This command will run the <code>first_container:local</code> container and execute the command specified in the Dockerfile&rsquo;s entrypoint.</p>
<h2 id="working-with-the-container">Working with the Container</h2>
<p>After running the container, you can interact with it by opening a terminal inside the container or executing commands within it. To do this, use the command:</p>
<pre tabindex="0"><code>docker exec -it my_first_container ash
</code></pre><p>This command will open an interactive terminal inside the <code>my_first_container</code> container.</p>
<p>But in this case, it will not be possible to execute, as the container dies after executing the echo command. To launch an interactive shell in the container, the following command needs to be executed:</p>
<pre tabindex="0"><code>docker run --rm --entrypoint ash -ti first_container:local
</code></pre>]]>
      </yandex:full-text>
    </item>
  </channel>
</rss>
