Alpine์€ Python์šฉ Docker ๋นŒ๋“œ๋ฅผ 50๋ฐฐ ๋Š๋ฆฌ๊ฒŒ ์ปดํŒŒ์ผํ•˜๊ณ  ์ด๋ฏธ์ง€๋Š” 2๋ฐฐ ๋” ๋ฌด๊ฒ์Šต๋‹ˆ๋‹ค.

Alpine์€ Python์šฉ Docker ๋นŒ๋“œ๋ฅผ 50๋ฐฐ ๋Š๋ฆฌ๊ฒŒ ์ปดํŒŒ์ผํ•˜๊ณ  ์ด๋ฏธ์ง€๋Š” 2๋ฐฐ ๋” ๋ฌด๊ฒ์Šต๋‹ˆ๋‹ค.

Alpine Linux๋Š” Docker์˜ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋กœ ๊ถŒ์žฅ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. Alpine์„ ์‚ฌ์šฉํ•˜๋ฉด ๋นŒ๋“œ๊ฐ€ ๋” ์ž‘์•„์ง€๊ณ  ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋” ๋นจ๋ผ์ง„๋‹ค๋Š” ๋ง์„ ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— Alpine Linux๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋นŒ๋“œ ์†๋„๊ฐ€ ํ›จ์”ฌ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.
  • ์ด๋ฏธ์ง€๋ฅผ ๋” ํฌ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  • ์‹œ๊ฐ„๋‚ญ๋น„
  • ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ๊ตญ ๋Ÿฐํƒ€์ž„์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Alpine์ด ๊ถŒ์žฅ๋˜๋Š” ์ด์œ ์™€ Python์—์„œ Alpine์„ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋˜๋Š” ์ด์œ ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‚ฌ๋žŒ๋“ค์ด ์•ŒํŒŒ์ธ์„ ์ถ”์ฒœํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?

์ด๋ฏธ์ง€์˜ ์ผ๋ถ€๋กœ gcc๊ฐ€ ํ•„์š”ํ•˜๊ณ  ๋นŒ๋“œ ์†๋„์™€ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ธก๋ฉด์—์„œ Alpine Linux์™€ Ubuntu 18.04๋ฅผ ๋น„๊ตํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ๋‘ ๊ฐœ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํฌ๊ธฐ๋ฅผ ๋น„๊ตํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

$ docker pull --quiet ubuntu:18.04
docker.io/library/ubuntu:18.04
$ docker pull --quiet alpine
docker.io/library/alpine:latest
$ docker image ls ubuntu:18.04
REPOSITORY          TAG        IMAGE ID         SIZE
ubuntu              18.04      ccc6e87d482b     64.2MB
$ docker image ls alpine
REPOSITORY          TAG        IMAGE ID         SIZE
alpine              latest     e7d92cdc71fe     5.59MB

๋ณด์‹œ๋‹ค์‹œํ”ผ Alpine์˜ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋Š” ํ›จ์”ฌ ์ž‘์Šต๋‹ˆ๋‹ค. ์ด์ œ gcc๋ฅผ ์„ค์น˜ํ•˜๊ณ  Ubuntu๋ฅผ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

FROM ubuntu:18.04
RUN apt-get update && 
    apt-get install --no-install-recommends -y gcc && 
    apt-get clean && rm -rf /var/lib/apt/lists/*

์™„๋ฒฝํ•œ Dockerfile์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ด ๊ธฐ์‚ฌ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

์กฐ๋ฆฝ ์†๋„๋ฅผ ์ธก์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

$ time docker build -t ubuntu-gcc -f Dockerfile.ubuntu --quiet .
sha256:b6a3ee33acb83148cd273b0098f4c7eed01a82f47eeb8f5bec775c26d4fe4aae

real    0m29.251s
user    0m0.032s
sys     0m0.026s
$ docker image ls ubuntu-gcc
REPOSITORY   TAG      IMAGE ID      CREATED         SIZE
ubuntu-gcc   latest   b6a3ee33acb8  9 seconds ago   150MB

Alpine(Dockerfile)์— ๋Œ€ํ•ด์„œ๋„ ๋™์ผํ•œ ์ž‘์—…์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค.

FROM alpine
RUN apk add --update gcc

์šฐ๋ฆฌ๋Š” ์กฐ๋ฆฝํ•˜๊ณ  ์กฐ๋ฆฝ ์‹œ๊ฐ„๊ณผ ํฌ๊ธฐ๋ฅผ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

$ time docker build -t alpine-gcc -f Dockerfile.alpine --quiet .
sha256:efd626923c1478ccde67db28911ef90799710e5b8125cf4ebb2b2ca200ae1ac3

real    0m15.461s
user    0m0.026s
sys     0m0.024s
$ docker image ls alpine-gcc
REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
alpine-gcc   latest   efd626923c14   7 seconds ago   105MB

์•ฝ์†ํ•œ ๋Œ€๋กœ Alpine ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋Š” ๋” ๋น ๋ฅด๊ณ  ๋” ์ž‘์Šต๋‹ˆ๋‹ค. ์ฆ‰, 15์ดˆ๊ฐ€ ์•„๋‹Œ 30์ดˆ๊ฐ€ ์†Œ์š”๋˜๋ฉฐ ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 105MB์—์„œ 150MB์ž…๋‹ˆ๋‹ค. ๊ฝค ์ข‹์Šต๋‹ˆ๋‹ค!

๊ทธ๋Ÿฌ๋‚˜ Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์ถ•์œผ๋กœ ์ „ํ™˜ํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ๊ทธ๋ ‡๊ฒŒ ์žฅ๋ฐ‹๋น›์ด ์•„๋‹™๋‹ˆ๋‹ค.

ํŒŒ์ด์ฌ ์ด๋ฏธ์ง€

Python ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ข…์ข… pandas์™€ matplotlib๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•œ ๊ฐ€์ง€ ์˜ต์…˜์€ ์ด Dockerfile์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ณต์‹ Debian ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

FROM python:3.8-slim
RUN pip install --no-cache-dir matplotlib pandas

๊ทธ๊ฒƒ์„ ์ˆ˜์ง‘ํ•˜์ž:

$ docker build -f Dockerfile.slim -t python-matpan.
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM python:3.8-slim
 ---> 036ea1506a85
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas
 ---> Running in 13739b2a0917
Collecting matplotlib
  Downloading matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64.whl (13.1 MB)
Collecting pandas
  Downloading pandas-0.25.3-cp38-cp38-manylinux1_x86_64.whl (10.4 MB)
...
Successfully built b98b5dc06690
Successfully tagged python-matpan:latest

real    0m30.297s
user    0m0.043s
sys     0m0.020s

363MB ํฌ๊ธฐ์˜ ์ด๋ฏธ์ง€๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.
์•ŒํŒŒ์ธ๊ณผ ๋” ์ž˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ํ•ด๋ณด์ž:

FROM python:3.8-alpine
RUN pip install --no-cache-dir matplotlib pandas

$ docker build -t python-matpan-alpine -f Dockerfile.alpine .                                 
Sending build context to Docker daemon  3.072kB                                               
Step 1/2 : FROM python:3.8-alpine                                                             
 ---> a0ee0c90a0db                                                                            
Step 2/2 : RUN pip install --no-cache-dir matplotlib pandas                                                  
 ---> Running in 6740adad3729                                                                 
Collecting matplotlib                                                                         
  Downloading matplotlib-3.1.2.tar.gz (40.9 MB)                                               
    ERROR: Command errored out with exit status 1:                                            
     command: /usr/local/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/
tmp/pip-install-a3olrixa/matplotlib/setup.py'"'"'; __file__='"'"'/tmp/pip-install-a3olrixa/matplotlib/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'rn'"'"', '"'"'n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-a3olrixa/matplotlib/pip-egg-info                              

...
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
The command '/bin/sh -c pip install matplotlib pandas' returned a non-zero code: 1

๋ฌด์Šจ ์ผ์ด์•ผ?

์•ŒํŒŒ์ธ์€ ๋ฐ”ํ€ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค

Debian ๊ธฐ๋ฐ˜ ๋นŒ๋“œ๋ฅผ ๋ณด๋ฉด matplotlib-3.1.2-cp38-cp38-manylinux1_x86_64๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.ํ—.

์ด๊ฒƒ์€ ํœ ์šฉ ๋ฐ”์ด๋„ˆ๋ฆฌ์ž…๋‹ˆ๋‹ค. Alpine์€ `matplotlib-3.1.2.tar' ์†Œ์Šค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.gz` ํ‘œ์ค€์„ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”ํ€ด.

์™œ? ๋Œ€๋ถ€๋ถ„์˜ Linux ๋ฐฐํฌํŒ์€ ์‹ค์ œ๋กœ Python์„ ํฌํ•จํ•˜์—ฌ C๋กœ ์ž‘์„ฑ๋œ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋žจ์— ํ•„์š”ํ•œ C ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ GNU ๋ฒ„์ „(glibc)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Alpine์€ 'musl'์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋Š” 'glibc'์šฉ์œผ๋กœ ์„ค๊ณ„๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹จ์ˆœํžˆ ์˜ต์…˜์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ Alpine์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฐ Python ํŒจํ‚ค์ง€์—์„œ C๋กœ ์ž‘์„ฑ๋œ ๋ชจ๋“  ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•„, ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์ปดํŒŒ์ผํ•ด์•ผ ํ•˜๋Š” ๋ชจ๋“  ์ข…์†์„ฑ ๋ชฉ๋ก์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๋‹ค.

FROM python:3.8-alpine
RUN apk --update add gcc build-base freetype-dev libpng-dev openblas-dev
RUN pip install --no-cache-dir matplotlib pandas

๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œ์‹œ๊ฐ„๋„ ๊ฑธ๋ฆฌ๊ณ ...

... 25๋ถ„ 57์ดˆ! ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋Š” 851MB์ž…๋‹ˆ๋‹ค.

Alpine ๊ธฐ๋ฐ˜ ์ด๋ฏธ์ง€๋Š” ๋นŒ๋“œํ•˜๋Š” ๋ฐ ํ›จ์”ฌ ๋” ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๊ณ  ํฌ๊ธฐ๊ฐ€ ๋” ํฌ๋ฉฐ ์—ฌ์ „ํžˆ ๋ชจ๋“  ์ข…์†์„ฑ์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์–ด์…ˆ๋ธ”๋ฆฌ ํฌ๊ธฐ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋‹จ๊ณ„ ๋นŒ๋“œ ํ•˜์ง€๋งŒ ์ด๋Š” ๋” ๋งŽ์€ ์ž‘์—…์ด ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ฒŒ ๋‹ค๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค!

Alpine์€ ๋Ÿฐํƒ€์ž„์— ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฒ„๊ทธ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์‹คํžˆ ์ด๋Ÿฌํ•œ ์˜ค๋ฅ˜๋Š” ์ด๋ฏธ ์ˆ˜์ •๋˜์—ˆ์ง€๋งŒ ์•ž์œผ๋กœ ์–ผ๋งˆ๋‚˜ ๋” ๋งŽ์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ• ์ง€ ๋ˆ„๊ฐ€ ์•Œ๊ฒ ์Šต๋‹ˆ๊นŒ?

Python์— Alpine ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”.

ํฌ๊ณ  ๊ธด ๋นŒ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ข…์†์„ฑ๊ณผ ์ž ์žฌ์ ์ธ ์˜ค๋ฅ˜๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด Alpine Linux๋ฅผ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์„ธ์š”. ์ข‹์€ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€ ์„ ํƒ.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€