У меня есть следующий 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"]