Elixir 애플리케이션의 컨테이너를 가능한 한 다이어트 한 이야기

7900 단어 Elixir도커

개요



Elixir로 쓴 chatops용 어플리케이션anago을 GKE로 움직이려고 docker build하면 상당히 무거운 Rails 수준의 용량이 되어 버렸기 때문에 어디까지 쏟아낼 수 있는지 검증한 이야기입니다.
FROM elixir:latest

WORKDIR /app
ENV MIX_ENV=prod

RUN mix local.hex --force && \
  mix local.rebar --force

COPY mix.exs mix.exs
COPY mix.lock mix.lock
COPY config config
RUN mix deps.get --only prod && \
  mix deps.compile

COPY . .
CMD ["mix", "run", "--no-halt"]

처음에 Dockerfile은 이런 느낌입니다.
이 Dockerfile로 빌드 한 응용 프로그램의 크기는 다음과 같습니다 ...
docker images
##
REPOSITORY                                TAG             IMAGE ID       CREATED          SIZE
anago                                     latest          aa7e0779d912   2 seconds ago    1.27GB

이미지도 JSON도 DB도 없는 간단한 어플리케이션으로의 사이즈가 1.27GB로 나오면 과연 다이어트를 결의하겠지요...

기본 이미지 확인



Elixir의 베이스 이미지 사이즈는 아래와 같다.
docker pull elixir
## docker images
REPOSITORY                                TAG             IMAGE ID       CREATED         SIZE
elixir                                    latest          83478b936eba   2 days ago      1.24GB

비교에 Go 언어의 컨테이너를 가져 가면 ...
docker pull golang
### docker images
REPOSITORY                                TAG             IMAGE ID       CREATED          SIZE
golang                                    latest          5f9d35ce5cfe   3 weeks ago      839MB

역시 파일 사이즈는 빌드한 라이브러리의 코드 포함해도 30MB 정도.
하지만 기본 이미지가 원래 1.24GB도 있습니다 ...
비교에 취한 Go의 이미지와 비교해도 300MB 근처 Elixir 쪽이 무겁다

alpine으로 시도



이미지 사이즈의 다이어트의 입구는 베이스 이미지를 alpine로 하는 것이라고 생각하기 때문에 베이스 이미지를 바꾸어 본다.
docker pull elixir:alpine
## docker images
REPOSITORY                                TAG             IMAGE ID       CREATED         SIZE
elixir                                    alpine          dd10458addd0   2 days ago       84.9MB

압도적 모양! 96% 감소!
이것에 응용 프로그램의 30MB를 추가해도 114MB에!
REPOSITORY                                TAG             IMAGE ID       CREATED              SIZE
anago                                     alpine          c8b8c08b7aef   About a minute ago   114MB

원래 사이즈와 비교하면 10% 미만으로 다이어트 성공! !
이제 이것으로 좋지 않아?

escript, 움직입니다



Erlang에는 응용 프로그램을 하나의 실행 파일로 굳히는 escript라는 구조가 있습니다.
실행 파일은 Erlang 런타임이있는 환경에서 실행할 수 있습니다.
라는 것은 Erlang : alpine의 이미지로 움직이는 것이 아닙니까?
바로 Erlang : alpine의 기본 이미지를 얻으십시오.
docker pull erlang:alpine
## docker images

REPOSITORY                                TAG             IMAGE ID       CREATED          SIZE
erlang                                    alpine          daa6bbdd7458   2 weeks ago      69.4MB

Elixir는 Erlang에서 움직이기 때문에 Erlang의 기본 이미지가 더 가볍습니다.
15MB 정도이지만 경량이군요.
이제 가자! !

그래서 Dockerfile에 mix escript build를 추가했습니다.
그런 다음 소스 코드도 필요하지 않으므로 멀티 스테이지 빌드도합시다.
FROM elixir:alpine as build

WORKDIR /app
ENV MIX_ENV=prod

RUN mix local.hex --force && \
  mix local.rebar --force

COPY mix.exs mix.exs
COPY mix.lock mix.lock
COPY config config
RUN mix deps.get --only prod && \
  mix deps.compile

COPY . .

RUN mix escript.build

FROM erlang:alpine

WORKDIR /app
COPY --from=build /app/anago /app/anago

이것으로 요시!
다시 docker build하고 크기를 보면
REPOSITORY                                TAG             IMAGE ID       CREATED          SIZE
anago                                     erlang_alpine   a01f810d11dc   2 seconds ago    71.4MB

71.4MB까지 경량화에 성공! ! !
마침내 100MB의 벽을 돌파했습니다! !

한화휴제



이 응용 프로그램은 원래 mix run --no-halt에서 실행할 예정이었지만 escript로 설정하면 즉시 종료됩니다.
그런 때는 timer.sleep(:infinity) 라고 쓰면 계속 움직이기도 합니다.
defmodule Anago.CLI do
  def main(_args) do
    :timer.sleep(:infinity)
  end
end

어디까지 줄일 수 있니?



erlang : alpine도 최소한 뭔가 함께 들어있을 것이라고 생각하기 때문에 alpine에 apk add erlang하고 어디까지 줄어들지 궁금해졌습니다.
바닐라 alpine의 크기는 약간 5MB입니다.
시도에 alpine에 erlang만 설치하는 Dockerfile을 만들어 보겠습니다.
FROM alpine:latest
RUN apk add --no-cache erlang

이 Dockerfile을 빌드하면 결과는 63.6MB까지 경량화됩니다! (Erlang이 58MB 정도의 용량이므로 더 이상의 다이어트는 무리)
여기까지 줄어 버리면 제대로 움직이는지 불안해집니다만 여기까지 오면 목표도 어디까지 사이즈를 깎아내릴 수 있을까에 시프트하고 있으므로 어플리케이션을 포함해 빌드해 보겠습니다.
REPOSITORY                                TAG             IMAGE ID       CREATED             SIZE
anago                                     custom_alpine   fb1de28697a1   9 minutes ago       65.6MB

65.6MB까지 왔습니다

후기



덧붙여서이 이미지도 제대로 실행할 수있었습니다 (대단한 ...)
Erlang의 크기 한계로 아마 더 이상의 경량화는 할 수 없다고 생각해 경량화의 한계는 63.6MB + escript가 되는 것 같습니다.

좋은 웹페이지 즐겨찾기