<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="42307" data-post-id="42307">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bitwalker" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/120/998_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bitwalker
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Leader</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="gmile" data-post="21" data-topic="6975">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/48/33982_2.png" class="avatar"> gmile:</div>
<blockquote>
<p>Even if I strip 11 Mb, that’d make it 48 - 11 = 37, which is still 2x times than what people here are reporting, e.g. 20 Mb.</p>
</blockquote>
</aside>
<p>Your ERTS is only 19mb though, of which 11mb is apparently debug info, the rest is presumably system libs and your application code. 20mb is the absolute smallest application people are reporting, not the average. My applications on average are ~50-75mb, so you are well within normal size in my opinion.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="42307" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-42307" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="42307"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="42313" data-post-id="42313">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="asaaki" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/asaaki/120/4802_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  asaaki
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bitwalker" data-post="22" data-topic="6975">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bitwalker/48/998_2.png" class="avatar"> bitwalker:</div>
<blockquote>
<p>20mb is the absolute smallest application people are reporting, not the average.</p>
</blockquote>
</aside>
<p><img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20">  Not quite true …</p>
<pre data-code-wrap="sh"><code class="lang-sh"># in a bare minimum Phoenix project with one C ext package
mix edib --hex --edib edib/edib-tool:latest --strip
# ...
docker images

REPOSITORY          ...  SIZE
local/edib_app_test ...  14.7MB
</code></pre>
<p>A simple hello world Elixir app without any real code and deps would be around 10ish MB with stripping.</p>
<p>Though I also wouldn’t recommend using stripping and/or zipping if not really necessary, of course.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="42313" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-42313" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="42313"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="52946" data-post-id="52946">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gmile" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/120/33982_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gmile
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>In case anyone is interested, this is the container I’m building right now. It uses:</p>
<ul>
<li><code>alpine:3.6</code> as a builder/runner image,</li>
<li><code>Erlang 20.1.1</code></li>
<li><code>Elixir 1.5.2</code></li>
</ul>
<p>I like to build my own image instead of a pre-backed image in this case. I like to <em>install</em> elixir/erlang, as well as other packages, instead of compiling them. By looking at base image, I know that there’s no magic going on here.</p>
<p>It’s size, including my apps compiled code and dependencies is <strong>55.5 Mb</strong>.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">FROM alpine:3.6 as builder

RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community/" &gt;&gt; /etc/apk/repositories

RUN apk add --update \
      git \
      erlang=20.1.1-r0 \
      elixir=1.5.2-r0 \
      erlang-crypto \
      erlang-parsetools \
      erlang-syntax-tools \
      erlang-runtime-tools

ADD . /app

WORKDIR /app

ENV MIX_ENV=prod

RUN mix do local.hex --force, \
           local.rebar --force, \
           deps.get, \
           deps.compile, \
           release

FROM alpine:3.6

RUN apk add --no-cache \
      ncurses-libs \
      zlib \
      ca-certificates \
      openssl \
      bash

WORKDIR /app

COPY --from=builder /app/_build/prod/rel/my_app/releases/0.0.1/my_app.tar.gz /app

RUN tar -xzf my_app.tar.gz; rm my_app.tar.gz
</code></pre>
<p>I’m relying on <a href="https://github.com/bitwalker/distillery" rel="noopener nofollow ugc">distillery</a> for building releases. After the container is built, the app must be started by running <code>bin/my_app foreground</code> in the container:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">docker run my_app_image bin/my_app foreground
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="52946" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-52946" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="52946"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="59724" data-post-id="59724">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gmile" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/120/33982_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gmile
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>So, the Dockerfile I’m using has changed significantly. I’m now using two of them:</p>
<ul>
<li>a base one, which is updated much less frequently,</li>
<li>and the apps one, which is ran every time I need to pack the app into a container.</li>
</ul>
<p>This is how they look like:</p>
<p>Base:</p>
<pre data-code-wrap="Dockerfile"><code class="lang-Dockerfile"># edenlabllc/elixir:1.5.2

FROM alpine:edge

ENV REFRESHED_AT=2017-11-23

RUN apk add --update \
  erlang=20.1.7-r0 \
  elixir=1.5.2-r0 \
  erlang-crypto \
  erlang-parsetools \
  erlang-syntax-tools \
  erlang-runtime-tools \
  git \
  make
</code></pre>
<p>Everyday use:</p>
<pre data-code-wrap="Dockerfile"><code class="lang-Dockerfile">FROM edenlabllc/elixir:1.5.2 as builder

ARG APP_NAME
ARG APP_VERSION

ADD . /app

WORKDIR /app

ENV MIX_ENV=prod

RUN mix do \
      local.hex --force, \
      local.rebar --force, \
      deps.get, \
      deps.compile, \
      release

FROM alpine:edge

ARG APP_NAME
ARG APP_VERSION

RUN apk add --no-cache \
      ncurses-libs \
      zlib \
      ca-certificates \
      openssl \
      bash

WORKDIR /app

COPY --from=builder /app/_build/prod/rel/${APP_NAME}/releases/${APP_VERSION}/${APP_NAME}.tar.gz /app

RUN tar -xzf ${APP_NAME}.tar.gz; rm ${APP_NAME}.tar.gz

ENV REPLACE_OS_VARS=true \
    APP=${APP_NAME}

CMD ./bin/${APP} foreground
</code></pre>
<p>In order to build this, I run:</p>
<pre data-code-wrap="bash"><code class="lang-bash">docker build --tag "my_account/my_app:1.2.3" \
             --file Dockerfile \
             --build-arg APP_VERSION=1.2.3. \
             --build-arg APP_NAME=my_app .
</code></pre>
<p>I could merge both Dockerfiles, but it just didn’t make sense to re-install the compile-time dependencies every time I needed to build the app. After all, elixir and erlang release versions much less frequently.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59724" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-59724" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59724"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="59767" data-post-id="59767">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="melpon" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  melpon
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think <code>openssl</code> package is not needed if Erlang is built with <code>./configure --disable-dynamic-ssl-lib ...</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="59767" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-59767" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="59767"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="61332" data-post-id="61332">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gmile" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/120/33982_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gmile
                      <span class="op-star" title="Thread Starter">
                        <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                      </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/melpon" rel="nofollow">@melpon</a> unfortunately by default erlang for alpine is built using <code>--enable-ssl=dynamic-ssl-lib</code> –<br>
<a href="https://github.com/alpinelinux/aports/blob/master/community/erlang/APKBUILD#L90" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/alpinelinux/aports/blob/master/community/erlang/APKBUILD#L90</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="61332" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/smallest-docker-container-with-elixir-app/6975/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-61332" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="61332"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>