gmile

gmile

After docker released native support for multi-stage builds, I decided to make my own small docker container with app.

Below container is based on the one from @bitwalker. It is the smallest one I could come up with in one sitting, given quite limited knowledge of docker & distillery releases:

# Dockerfile
FROM bitwalker/alpine-elixir:1.4.4 as builder

ADD . /app

WORKDIR /app

ENV MIX_ENV=prod

RUN mix do deps.get, deps.compile, release

FROM alpine:3.6

RUN apk add --no-cache \
      ca-certificates \
      openssl-dev \
      ncurses-dev \
      unixodbc-dev \
      zlib-dev

WORKDIR /app

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

ENV PORT=4000

RUN tar -xzf ritm.tar.gz; rm ritm.tar.gz

CMD ["bin/ritm", "foreground"]

It’s around 64Mb when pushed to docker hub. That’s a lot, although I don’t expect this to grow significantly (more app code & deps shouldn’t contribute that much).

I am aware guys from @Nerves-Core-Team build super-small linux images with the app installed, but I am not sure what could be derived from their work in order to build my own small container with docker.

How can I reduce the size of container even further?

Showing Posts 1 to 10

wmnnd

wmnnd

@gmile You don’t need the -dev libs on the release image.

This should suffice:

 add --no-cache \
      ncurses-libs \
      zlib \
      openssl \
      ca-certificates
gmile

gmile OP

@wmnnd this dropped the size to 56 MB, thanks!

cmkarlsson

cmkarlsson

How big is the actual release tar file you copy onto the image? The
reason I am asking is that I built alpine from scratch with our erlang
release and it was 18MB where 2/3 (if I remember correctly) was our release.

You should be able to shrink this significantly.

wmnnd

wmnnd

How do you suggest shrinking the release size?

cmkarlsson

cmkarlsson

Normally you don’t. You can exclude debug information which will make it
much smaller (half the size?). Without debug information you cannot
do things like tracing and other useful introspection in production. But
if you need the smallest available this is an option.

Generally the release size is the size your image will be + 5MB or so
for alpine.

bitwalker

bitwalker

Leader

If you depend on additional system libs that can add quite a bit of weight, depending on what they are. You can also double check to see which Erlang applications are being included, it should only be the subset your application depends on, not all of them.

A medium-sized application would probably depend on enough Erlang libs to hit that limit before any code from their own application was counted. A simple test project of mine hits 23mb with just libs, and here are the ones included in the release:


asn1-5.0/
certifi-1.1.0/
combine-0.9.6/
compiler-7.1/
crypto-4.0/
elixir-1.4.5/
gettext-0.13.1/
hackney-1.8.0/
idna-4.0.0/
iex-1.4.5/
kernel-5.3/
logger-1.4.5/
metrics-1.0.1/
mimerl-1.0.2/
poison-3.1.0/
public_key-1.4.1/
sasl-3.0.4/
ssl-8.2/
ssl_verify_fun-1.1.1/
stdlib-3.4/
test-0.1.0/
timex-3.1.13/
tzdata-0.5.12/

So either your app was extremely small or didn’t depend on much - in any case, I suspect most real-world applications will be much larger than 18mb. ERTS itself is only like 6mb, and anything in priv of your application or your dependencies will also be included.

I strongly recommend not stripping debug info - those cases you mentioned are some of the most powerful capabilities of the runtime, and are one of the reasons why OTP is such a powerful tool operationally. You are trading a small amount of space for a significant amount of functionality, to me it’s not even close to worth it to sacrifice that.

cmkarlsson

cmkarlsson

So either your app was extremely small or didn’t depend on much - in any case,
I suspect most real-world applications will be much larger than 18mb. ERTS
itself is only like 6mb, and anything in priv of your application or your
dependencies will also be included.

Yes, it didn’t have many dependencies. My point was that the
release is what should take up the most space. You cannot get the docker image
smaller than the release and that the alpine linux image should have
very little overhead in terms of space.

I strongly recommend not stripping debug info - those cases you mentioned are
some of the most powerful capabilities of the runtime, and are one of the
reasons why OTP is such a powerful tool operationally. You are trading a small
amount of space for a significant amount of functionality, to me it’s not even
close to worth it to sacrifice that.

Agreed. I don’t think the trade-off is worth it either but if you want
the smallest image possible you should know about the option.

We generally encrypt the debug info (we ship our software to clients).
In this case you need the key to be able to do any debugging but it
makes it a little bit harder to reconstruct the source code.

gmile

gmile OP

I’ve measured the space taken inside the container, and here’s what I’ve got.

  • here’s the root:

    docker run -it gmile/ritm:0.0.9 du / -h -d 1
    0       /dev
    4.0K    /home
    0       /proc
    4.0K    /root
    8.9M    /usr
    4.0K    /tmp
    812.0K  /bin
    80.0K   /var
    0       /sys
    1.3M    /etc
    4.0K    /run
    4.0K    /srv
    4.0K    /mnt
    220.0K  /sbin
    5.3M    /lib
    16.0K   /media
    55.7M   /app
    72.3M   /
    
  • here’s the /app folder, containing unpacked tar release:

    docker run -it gmile/ritm:0.0.9 du /app -h -d 1
    52.0K   /app/bin
    380.0K  /app/releases
    33.7M   /app/erts-8.3
    21.6M   /app/lib
    55.7M   /app
    

ERTS itself is only like 6mb

@bitwalker from what I am seeing, erts is 33.7 Mb way bigger than 6 Mb. Any ideas why so?

gmile

gmile OP

Upgrading the base image to bitwalker/alpine-elixir:1.4.5 (with erlang 20.0.1 underneath) shaved off another 12 Mb down to 48 Mb. After looking at the size stats, the shrink is due to erts loosing some weight:

docker run -it gmile/ritm:0.0.10 du /app -h -d 1
21.1M   /app/erts-9.0.1
52.0K   /app/bin
380.0K  /app/releases
22.2M   /app/lib
43.7M   /app

The size of erts is still way more than 6 Mb.

bitwalker

bitwalker

Leader

You’d have to show what is taking up that space in the ERTS folder - on my laptop, a release packed with ERTS included only shows 5.4mb in the erts-9.0 folder via du -hs <path>. Either there is more in the ERTS folder on Alpine which can be stripped (and I can tweak that in the Alpine images I produce if so) or it’s just bigger on Linux for some reason, but I can’t imagine why that would be.

Where Next? Top

Trending in Questions Top

water
I’m aware of 2 such projects, are there others? git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New
leoschweizer
Hi, we run different LLM models across a cluster, with each node loading a configurable subset. Model-specific queues let nodes consume ...
New

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews