Назад | Перейти на главную страницу

Проблемы с определением контекста выполнения с помощью Docker и Docker Compose

У меня есть следующий docker-compose.yml:

version: '3'
services:
  frontend:
    build: 
      context: ./
      dockerfile: docker/Dockerfile
    image: tsl.web.frontend.image
    container_name: tsl.web.frontend.container
    ports:
      - "8080:80"

Обратите внимание на context: ./

И это моя команда docker-compose:

docker-compose build --force-rm --build-arg ENVIRONMENT=development frontend

Вот структура моего кода src:

Обратите внимание, я выделил красным два важных аспекта этой структуры.

Теперь вот часть моего Dockerfile, я включу весь Dockerfile ниже:

# https://stackoverflow.com/a/35774741/1258525
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY ./package.json /tmp/package.json
RUN npm --prefix /tmp install /tmp
RUN cp -rn /tmp/node_modules ./
#RUN npm --prefix ./ run build-development ./
RUN npm run build-development #failing here

COPY dist /usr/share/nginx/html

Так что RUN npm run build-development команда не работает, потому что не может найти package.json:

Вот где меня смущает контекст выполнения RUN заявление. Мне удалось скопировать файл package.json в / tmp в предыдущей команде Dockerfile COPY ./package.json /tmp/package.json. Я думаю, что мой контекст все еще там, где живет мой файл docker-compose.yml, но, очевидно, это не так ...

Полный Dockerfile:

FROM centos:7
MAINTAINER Brian Ogden

# Not currently being used but may come in handy
ARG ENVIRONMENT
ENV NODE_VERSION 6.11.1

RUN yum -y update; yum clean all
RUN yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm; yum -y makecache
RUN yum -y install nginx-1.12.0

# Cleanup some default NGINX configuration files we don’t need
RUN rm /etc/nginx/conf.d/default.conf

COPY ./docker/conf/frontend.conf /etc/nginx/conf.d/frontend.conf
COPY ./docker/conf/nginx.conf /etc/nginx/nginx.conf

#############################################
# NodeJs Install
#############################################
RUN yum install -y \
        wget

#Download NodeJs package
RUN wget https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz

#extract the binary package into our system's local package hierarchy with the tar command. 
#The archive is packaged within a versioned directory, which we can get rid of by passing the --strip-components 1 option. 
#We will specify the target directory of our command with the -C command:
#This will install all of the components within the /usr/local branch
RUN tar --strip-components 1 -xzvf node-v* -C /usr/local
#############################################

# https://stackoverflow.com/a/35774741/1258525
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY ./package.json /tmp/package.json
RUN npm --prefix /tmp install /tmp
RUN cp -rn /tmp/node_modules ./
#RUN npm --prefix ./ run build-development ./
RUN npm run build-development

COPY dist /usr/share/nginx/html

EXPOSE 8080

CMD ["nginx"]

Вы можете запустить промежуточный контейнер с идентификатором 4e14504665eb и исследовать файловую систему.

$ docker run -it --rm 4e14504665eb  bash

или вы можете напрямую запустить

$ docker run -it --rm 4e14504665eb  ls -la /tmp

Но эти команды выглядят немного странно

RUN npm --prefix /tmp install /tmp
RUN cp -rn /tmp/node_modules ./
RUN npm run build-development

Вероятно, вам следует запустить команду сборки из каталога / tmp

P.S. Ваш Dockerfile выглядит неоптимально. Я бы посоветовал использовать больше оптимизированная версия

Я считаю, что причиной моего недоразумения на самом деле был контекст выполнения Docker. COPY команда против RUN команда.

Я думал, что RUN команда выполнялась в том же контексте выполнения, что и COPY это будет Dockerfile или контекст, указанный в моем docker-compose.yml, потому что COPY был в этом контексте.

Но в основном это не так. COPY знает ./ в Dockerfile. RUN однако не знает ничего, кроме создаваемого образа Docker.

Я пытался RUN команда для файлов, которые я не скопировал в создаваемый мной образ Docker. Этот раздел моего Dockerfile был секретом успеха:

WORKDIR /app
COPY . /app

RUN npm run build-$ENVIRONMENT

И вот мой полный рабочий Dockerfile, спасибо ALex_hha за некоторые оптимизации синтаксиса:

FROM centos:7
MAINTAINER Brian Ogden

# Not currently being used but may come in handy
ARG ENVIRONMENT
ENV NODE_VERSION 6.11.1

RUN yum -y update && \
    yum clean all && \
    yum -y install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm \
    yum -y makecache && \
    yum -y install nginx-1.12.0 wget

# Cleanup some default NGINX configuration files we don’t need
RUN rm /etc/nginx/conf.d/default.conf

#############################################
# NodeJs Install
#############################################

#Download NodeJs package
RUN wget -q -O - https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz \
    | tar --strip-components=1 -xzf - -C /usr/local
#pipe tar is extracting the binary package into our system's local package hierarchy with the tar command. 
#The archive is packaged within a versioned directory, which we can get rid of by passing the --strip-components 1 option. 
#We will specify the target directory of our command with the -C command:
#This will install all of the components within the /usr/local branch

# https://stackoverflow.com/a/35774741/1258525
# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY ./package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir /app && cp -a /tmp/node_modules /app/

WORKDIR /app
COPY . /app

RUN npm run build-$ENVIRONMENT

RUN cd /app && cp -a dist/* /usr/share/nginx/html
COPY ./docker/conf/frontend.conf /etc/nginx/conf.d/frontend.conf
COPY ./docker/conf/nginx.conf /etc/nginx/nginx.conf


EXPOSE 80

CMD ["nginx"]