<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Спасибо, волшебно. Я тоже в процессе накопал такую вот еще
      документацию -
      <a class="moz-txt-link-freetext" href="https://pythonspeed.com/articles/multi-stage-docker-python/">https://pythonspeed.com/articles/multi-stage-docker-python/</a></p>
    <p>А еще вопрос, но уже более специфический. Мой Dockerfile теперь
      выглядит следующим образом:</p>
    <p>FROM ubuntu AS compiler<br>
      RUN apt update<br>
      RUN apt -y install python3 python3-pip python3-venv<br>
      RUN python3 -m venv --system-site-packages /opt/venv<br>
      ENV PATH="/opt/venv/bin:$PATH"<br>
      COPY requirements.txt .<br>
      RUN pip3 install --ignore-installed --no-cache-dir -r
      requirements.txt<br>
      RUN rm requirements.txt<br>
      <br>
      FROM ubuntu AS builder<br>
      RUN apt update<br>
      RUN apt -y install python3<br>
      RUN mkdir /opt/contapp<br>
      WORKDIR  /opt/contapp<br>
      COPY --from=compiler /opt/venv /opt/venv<br>
      COPY core core<br>
      COPY base base<br>
      <br>
      ENV PATH="/opt/venv/bin:$PATH"<br>
      ENV PYTHONPATH="${PYTHONPATH}:/opt/contapp"<br>
      ENTRYPOINT ["python3", "/opt/contapp/core/daemon.py"]</p>
    <p>данное конкретное приложение работает с network queues под
      убунтой и потому я собираю библиотеки под убунтой же[1]:<br>
    </p>
    <p>- на первом шаге (as compiler) собирается система, компилится всё
      нужное, складывается в venv, чтобы перенести потом в новый слой
      (builder)<br>
      - новый слой (builder), соответственно, тоже делается на основе
      убунты, потому что собранные на первом шаге библиотеки требуют
      системных библиотек</p>
    <p>получившийся образ - около 200M. Не 400, конечно (как могло бы
      получиться без слоя builder), но и не хотя бы 100 :)</p>
    <p>Собственно, вопрос: а есть какой-то если не официальный, то
      проверенный образ(ы) для проворачивания "оптимизации" такого типа
      (названия придуманы :-) )<br>
    </p>
    <p>FROM ubuntu:glibc<br>
      FROM ubuntu:python-3.x as builder<br>
      [ ... ]<br>
      COPY --from=compiler /opt/venv /opt/venv<br>
      [ ... ]</p>
    <p>Спасибо.<br>
    </p>
    <p>[1] === Пробовал использовать alpine в виде:</p>
    <p>FROM alpine<br>
      FROM python:3.9-alpine AS compiler<br>
      [ ... compile stuff ... ]<br>
    </p>
    <p>FROM alpine<br>
      FROM python:3.9-alpine AS builder<br>
      COPY --from=compiler /opt/venv /opt/venv<br>
      [ ... rest stuff ... ]</p>
    <p>но при запуске под убунтой получаю такую ошибку:<br>
    </p>
    <p>ImportError: Error relocating
      /opt/venv/lib/python3.9/site-packages/fnfqueue/_fnfqueue.abi3.so:
      be64toh: symbol not found</p>
    <p>что, в общем-то, логично.<br>
    </p>
    <div class="moz-cite-prefix">On 26.01.2021 20:44, Serge Negodyuck
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CABKyZDE_SyTK_Eh_Nh=XKa5p_S3N+UKvRZh891FqQRTM6iKZmA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="ltr"><br>
        True way: <a
          href="https://docs.docker.com/develop/develop-images/multistage-build/"
          moz-do-not-send="true">https://docs.docker.com/develop/develop-images/multistage-build/</a><br>
        <br>
        Каждая команда RUN, COPY, ...  создает новый слой.<br>
        Но как quick & dirty  можно устанавливать и удалять
        build-depends в одном и том же шаге типа такого:<br>
        <pre style="white-space:pre-wrap;color:rgb(0,0,0)">FROM alpin
FROM python:3.9-alpine
RUN apk add build-base libffi-dev openssl-dev && \ 
mkdir /opt/contapp && \
cp requirements.txt /opt/contapp && \
cd /opt/contapp && \
pip install --no-cache-dir -r requirements.txt && \
rm requirements.txt &&  \
apk del --purge build-base libffi-dev openssl-dev

COPY core core
COPY base base</pre>
      </div>
      <br>
      <div class="gmail_quote">
        <div dir="ltr" class="gmail_attr">вт, 26 янв. 2021 г. в 20:17,
          Volodymyr Litovka <a class="moz-txt-link-rfc2396E" href="mailto:doka@xlit.one"><doka@xlit.one></a>:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
          0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
          <div>
            <p>Привет,</p>
            <p>в первый раз в жизни собираю контейнер (требование такое,
              Александр Васильевич, ёптить ;-) ) из питона и возникла
              незадача. В процессе pip install требуется gcc для сборки
              библиотек для нескольких требуемых питоновских пекеджей
              (описаны в requirements.txt)<br>
            </p>
            <p>Я делаю вот такой Dockerfile:</p>
            <pre>FROM alpine
FROM python:3.9-alpine
RUN apk add build-base libffi-dev openssl-dev
RUN mkdir /opt/contapp
WORKDIR  /opt/contapp

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN rm requirements.txt
# Cleanup
RUN apk del --purge build-base libffi-dev openssl-dev

COPY core core
COPY base base

ENV PYTHONPATH "${PYTHONPATH}:/opt/contapp"
ENTRYPOINT ["python3", "/opt/contapp/core/daemon.py"]
</pre>
            При сборке картина следующая - после инсталла alpine
            рипортит 224Mb в пекеджах (ожидаемо), после удаления -
            рипортит 15Mb в пекеджах (it's ok):
            <pre>Step 4/14 : RUN apk add build-base libffi libffi-dev openssl-dev
 ---> Running in bafd9776ce4d
fetch <a href="http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz" target="_blank" moz-do-not-send="true">http://dl-cdn.alpinelinux.org/alpine/v3.12/main/x86_64/APKINDEX.tar.gz</a>
fetch <a href="http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz" target="_blank" moz-do-not-send="true">http://dl-cdn.alpinelinux.org/alpine/v3.12/community/x86_64/APKINDEX.tar.gz</a>
(1/24) Installing libgcc (9.3.0-r2)
(2/24) Installing libstdc++ (9.3.0-r2)
(3/24) Installing binutils (2.34-r1)
(4/24) Installing libmagic (5.38-r0)
(5/24) Installing file (5.38-r0)
(6/24) Installing gmp (6.2.0-r0)
(7/24) Installing isl (0.18-r0)
(8/24) Installing libgomp (9.3.0-r2)
(9/24) Installing libatomic (9.3.0-r2)
(10/24) Installing libgphobos (9.3.0-r2)
(11/24) Installing mpfr4 (4.0.2-r4)
(12/24) Installing mpc1 (1.1.0-r1)
(13/24) Installing gcc (9.3.0-r2)
(14/24) Installing musl-dev (1.1.24-r10)
(15/24) Installing libc-dev (0.7.2-r3)
(16/24) Installing g++ (9.3.0-r2)
(17/24) Installing make (4.3-r0)
(18/24) Installing fortify-headers (1.1-r0)
(19/24) Installing patch (2.7.6-r6)
(20/24) Installing build-base (0.5-r2)
(21/24) Installing linux-headers (5.4.5-r1)
(22/24) Installing pkgconf (1.7.2-r0)
(23/24) Installing libffi-dev (3.3-r2)
(24/24) Installing openssl-dev (1.1.1i-r0)
Executing busybox-1.31.1-r19.trigger
<b>OK: 224 MiB in 60 packages</b>
[ ... ]
Step 10/14 : RUN apk del --purge build-base libffi-dev openssl-dev
 ---> Running in 709a88c5f43d
(1/24) Purging build-base (0.5-r2)
(2/24) Purging file (5.38-r0)
(3/24) Purging g++ (9.3.0-r2)
(4/24) Purging gcc (9.3.0-r2)
(5/24) Purging binutils (2.34-r1)
(6/24) Purging libatomic (9.3.0-r2)
(7/24) Purging libgomp (9.3.0-r2)
(8/24) Purging libgphobos (9.3.0-r2)
(9/24) Purging libstdc++ (9.3.0-r2)
(10/24) Purging make (4.3-r0)
(11/24) Purging libc-dev (0.7.2-r3)
(12/24) Purging musl-dev (1.1.24-r10)
(13/24) Purging fortify-headers (1.1-r0)
(14/24) Purging patch (2.7.6-r6)
(15/24) Purging libffi-dev (3.3-r2)
(16/24) Purging linux-headers (5.4.5-r1)
(17/24) Purging openssl-dev (1.1.1i-r0)
(18/24) Purging libgcc (9.3.0-r2)
(19/24) Purging libmagic (5.38-r0)
(20/24) Purging isl (0.18-r0)
(21/24) Purging mpc1 (1.1.0-r1)
(22/24) Purging mpfr4 (4.0.2-r4)
(23/24) Purging gmp (6.2.0-r0)
(24/24) Purging pkgconf (1.7.2-r0)
Executing busybox-1.31.1-r19.trigger
<b>OK: 15 MiB in 36 packages</b>
</pre>
            <p>но, по факту, это микро-факин-сервис получается размером
              300+Mb, по сравнению с 6+45Mb базовых образов:</p>
            <pre>root@gk:/opt/tlspx# docker image list
REPOSITORY   TAG          IMAGE ID       CREATED         SIZE
contapp      latest       af34adc59bfa   8 seconds ago   328MB
python       3.9-alpine   03c59395ddea   17 hours ago    44.9MB
alpine       latest       7731472c3f2a   11 days ago     5.61MB
</pre>
            <p>Вопросы:<br>
              - как вообще правильно выкрутиться в ситуации, когда devel
              set нужен только в процессе сборки?<br>
              - как  избавиться от всего лишнего, образовавшегося при
              сборке и не нужного в runtime (вроде и делаю apk del
              --purge, но размер образа остается такой, как будто и не
              удалял ничего)?</p>
            <p>Спасибо.</p>
            <pre cols="72">-- 
Volodymyr Litovka
  "Vision without Execution is Hallucination." -- Thomas Edison</pre>
          </div>
          _______________________________________________<br>
          uanog mailing list<br>
          <a href="mailto:uanog@uanog.kiev.ua" target="_blank"
            moz-do-not-send="true">uanog@uanog.kiev.ua</a><br>
          <a href="https://mailman.uanog.kiev.ua/mailman/listinfo/uanog"
            rel="noreferrer" target="_blank" moz-do-not-send="true">https://mailman.uanog.kiev.ua/mailman/listinfo/uanog</a></blockquote>
      </div>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
Volodymyr Litovka
  "Vision without Execution is Hallucination." -- Thomas Edison</pre>
  </body>
</html>