Многоступенчатой сборке Docker не удается найти файл на втором этапе

#docker #docker-compose #docker-multi-stage-build

#docker #docker-compose #docker-многоступенчатая сборка

Вопрос:

Моя среда: Ubuntu 18.04, Docker 19.03.11

Я работаю над приложением Flask и управляю службами с помощью Docker. Вот мой файл для создания:

 version: '3.6'

x-build-args: amp;build_args
  INSTALL_PYTHON_VERSION: 3.8
  INSTALL_NODE_VERSION: 12

x-default-volumes: amp;default_volumes
  volumes:
    - ./:/app
    - node-modules:/app/node_modules
    - ./dev.db:/tmp/dev.db

services:
  flask-dev:
    build:
      context: .
      target: development
      args:
        <<: *build_args
        user: abc
    image: "testapp-development"
    ports:
      - "5000:5000"
      - "2992:2992"
    <<: *default_volumes

  flask-prod:
    build:
      context: .
      target: production
      args:
        <<: *build_args
    image: "testapp-production"
    ports:
      - "5000:5000"
    environment:
      FLASK_ENV: production
      FLASK_DEBUG: 0
      LOG_LEVEL: info
      GUNICORN_WORKERS: 4
    <<: *default_volumes

  manage:
    build:
      context: .
      target: manage
    environment:
      FLASK_ENV: production
      FLASK_DEBUG: 0
    image: "testapp-manage"
    stdin_open: true
    tty: true
    <<: *default_volumes

volumes:
  node-modules:
  static-build:
  dev-db:

  

Мой Dockerfile:

 # ==================================== BASE ====================================
ARG INSTALL_PYTHON_VERSION=${INSTALL_PYTHON_VERSION:-3.7}
FROM python:${INSTALL_PYTHON_VERSION}-slim-buster AS base

RUN apt-get update
RUN apt-get install -y 
    curl 
    gcc

ARG INSTALL_NODE_VERSION=${INSTALL_NODE_VERSION:-12}
RUN curl -sL https://deb.nodesource.com/setup_${INSTALL_NODE_VERSION}.x | bash -
RUN apt-get install -y 
    nodejs 
    amp;amp; apt-get -y autoclean

ARG user=sid
# Add the user and their group
RUN groupadd -r ${user} amp;amp; useradd -m -r -l -g ${user} ${user}
# the /app directory contains things that npm needs
# user won't have permissions to this, so copy it
# into their home dir
WORKDIR /app
COPY --chown=${user}:${user} . /home/${user}/
USER ${user}
WORKDIR /home/${user}/app
ENV PATH="/home/${user}/.local/bin:${PATH}"
RUN npm install

# ================================= DEVELOPMENT ================================
FROM base AS development
RUN pip install --user -r requirements/dev.txt
EXPOSE 2992
EXPOSE 5000
CMD [ "npm", "start" ]

# ================================= PRODUCTION =================================
FROM base AS production
RUN pip install --user -r requirements/prod.txt
COPY supervisord.conf /etc/supervisor/supervisord.conf
COPY supervisord_programs /etc/supervisor/conf.d
EXPOSE 5000
ENTRYPOINT ["/bin/bash", "shell_scripts/supervisord_entrypoint.sh"]
CMD ["-c", "/etc/supervisor/supervisord.conf"]

# =================================== MANAGE ===================================
FROM base AS manage
RUN pip install --user -r requirements/dev.txt
ENTRYPOINT [ "flask" ]
  

Сбой как в процессе разработки, так и в процессе производства

Вот результат, который я получаю от запуска docker-compose build flask-dev :

 Building flask-dev
Step 1/20 : ARG INSTALL_PYTHON_VERSION=${INSTALL_PYTHON_VERSION:-3.7}
Step 2/20 : FROM python:${INSTALL_PYTHON_VERSION}-slim-buster AS base
 ---> 38cd21c9e1a8
Step 3/20 : RUN apt-get update
 ---> Using cache
 ---> 5d431961b77a
Step 4/20 : RUN apt-get install -y     curl     gcc
 ---> Using cache
 ---> caeafb0035dc
Step 5/20 : ARG INSTALL_NODE_VERSION=${INSTALL_NODE_VERSION:-12}
 ---> Using cache
 ---> 6e8a1eb59d3c
Step 6/20 : RUN curl -sL https://deb.nodesource.com/setup_${INSTALL_NODE_VERSION}.x | bash -
 ---> Using cache
 ---> 06fe96eb13e7
Step 7/20 : RUN apt-get install -y     nodejs     amp;amp; apt-get -y autoclean
 ---> Using cache
 ---> 1e085132d325
Step 8/20 : ARG user=sid
 ---> Using cache
 ---> 3b3faf180389
Step 9/20 : RUN groupadd -r ${user} amp;amp; useradd -m -r -l -g ${user} ${user}
 ---> Running in 9672d6f8b64d
Removing intermediate container 9672d6f8b64d
 ---> 02a5c2602513
Step 10/20 : WORKDIR /app
 ---> Running in bd48ac652908
Removing intermediate container bd48ac652908
 ---> 92c16bf347d4
Step 11/20 : COPY --chown=${user}:${user} . /home/${user}/
 ---> 2af997c5a255
Step 12/20 : USER ${user}
 ---> Running in 6409cf8784ee
Removing intermediate container 6409cf8784ee
 ---> 012d9cf92f31
Step 13/20 : WORKDIR /home/${user}/app
 ---> Running in a12b164c39dd
Removing intermediate container a12b164c39dd
 ---> db6fba37f948
Step 14/20 : ENV PATH="/home/${user}/.local/bin:${PATH}"
 ---> Running in eb13f4786b17
Removing intermediate container eb13f4786b17
 ---> a32249e3169b
Step 15/20 : RUN npm install
 ---> Running in 8aefdd56e8f2
npm WARN deprecated fsevents@1.2.13: fsevents 1 will break on node v14  and could be using insecure binaries. Upgrade to fsevents 2.
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@~2.1.2 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.2.7 (node_modules/watchpack-chokidar2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.13: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

audited 712 packages in 2.873s

43 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Removing intermediate container 8aefdd56e8f2
 ---> 737faa9b974e

Step 16/20 : FROM base AS development
 ---> 737faa9b974e
Step 17/20 : RUN pip install --user -r requirements/dev.txt
 ---> Running in af5508643877
ERROR: Could not open requirements file: [Errno 2] No such file or directory: 'requirements/dev.txt'
ERROR: Service 'flask-dev' failed to build: The command '/bin/sh -c pip install --user -r requirements/dev.txt' returned a non-zero code: 1
  

Я думаю, что мой подход к этому неправильный. Мне нужно, чтобы приложение Flask работало вне тома приложения, который я использую в файле compose.

Я думаю, что неправильно понимаю многоступенчатые сборки. Нужно ли мне выполнять дополнительные шаги на этапах разработки, производства и управления, чтобы иметь возможность доступа к каталогу /home / $ {user} / app? Насколько я понимаю, аргументы, определенные на предыдущих этапах, недоступны на последующих, но вся ли обработка, выполняемая на этапе, также недоступна на последующих этапах?

Я также пытался использовать COPY —from=base на втором этапе с полным путем к каталогу приложения, который находится на этапе базовой сборки, но это тоже неверно.

Соответствующие части каталога проекта являются:

 testapp/
    docker-compose.yml
    Dockerfile
    testapp/
       <web app code>
    requirements/
        dev.txt
        prod.txt
  

Комментарии:

1. Это dev.txt или dev.text ? Вы перечисляете одну вещь в каталоге и копируете другую в Dockerfile.

2. Можете ли вы использовать абсолютные пути в команде pip? RUN pip install --user -r /app/requirements/dev.txt или `ЗАПУСТИТЕ pip install —user -r /home/user/app/requirements/dev.txt `. Это зависит от того, где вы requirements.txt есть.

3. @BMitch извините за опечатку, это dev.txt. Отредактировал оригинал

4. @M.Iduoad Этот путь также не работает.

Ответ №1:

Вы скопировали свои файлы в другой каталог:

 WORKDIR /app
COPY --chown=${user}:${user} . /home/${user}/
USER ${user}
WORKDIR /home/${user}/app
  

Каталог требований будет находиться в /home/${user}/ , в то время как ваша относительная команда run будет использовать workdir для поиска в /home/${user}/app . Вероятно, вы хотите скопировать в подкаталог app:

 COPY --chown=${user}:${user} . /home/${user}/app