Многоступенчатый Dockerfile приводит к нехватке места - PullRequest
0 голосов
/ 11 ноября 2018

Поскольку мой код (nodeJS-приложение) меняется чаще, чем зависимости (npm), я попытался создать нечто вроде кеша в моем CI.

Я использую многоэтапный Dockerfile. В этом я запускаю npm install для всех и только для prod-зависимостей. Позже они копируются в окончательное изображение, чтобы оно стало намного меньше. Отлично.

Кроме того, сборка становится супер быстрой, если зависимость не была изменена.

Однако со временем hd заполняется, поэтому мне нужно запустить docker prune ..., чтобы вернуть место. Но когда я это делаю, кеш исчезает.

Поэтому, если я запускаю prune после каждого конвейера в моем CI, я не получаю «функциональность кэша» многоступенчатого Dockerfile.

### 1. Build
FROM node:10.13 AS build
WORKDIR /home/node/app

COPY ./package*.json ./
COPY ./.babelrc ./

RUN npm set progress=false \
    && npm config set depth 0 \
    && npm install --only=production --silent \
    && cp -R node_modules prod_node_modules
RUN npm install --silent

COPY ./src ./src
RUN ./node_modules/.bin/babel ./src/ -d ./dist/ --copy-files

### 2. Run
FROM node:10.13-alpine
RUN apk --no-cache add --virtual \
      builds-deps \
      build-base \
      python
WORKDIR /home/node/app

COPY --from=build /home/node/app/prod_node_modules ./node_modules
COPY --from=build /home/node/app/dist .

EXPOSE 3000
ENV NODE_ENV production
CMD ["node", "app.js"]

1 Ответ

0 голосов
/ 11 ноября 2018

Если ваша система CI позволяет вам выполнить несколько шагов docker build, вы можете разделить это на два файла Docker.

# Dockerfile.dependencies
# docker build -f Dockerfile.dependencies -t me/dependencies .
FROM node:10.13
...
RUN npm install
# Dockerfile
# docker build -t me/application .
FROM me/dependencies:latest AS build
COPY ./src ./src
RUN ./node_modules/.bin/babel ./src/ -d ./dist/ --copy-files

FROM node:10.13-alpine
...
CMD ["node", "app.js"]

Если вы сделаете это, то вы можете удалить неиспользуемые изображения после каждой сборки:

docker image prune

Самая последняя сборка изображения зависимостей будет иметь метку, поэтому она не будет "зависать" и не будет отображаться в списке изображений. При каждой сборке ее метка будет «взята из» предыдущей сборки (если она изменилась), поэтому эта последовательность будет очищать предыдущие сборки. Это также удалит образы «сборки», хотя, как вы заметили, если что-нибудь изменилось, чтобы вызвать сборку, оно, вероятно, будет находиться в дереве src, и поэтому принудительное перестроение там разумно.

В этом конкретном случае уместно просто использовать тег latest. Если у окончательно созданных изображений есть еще несколько уникальных тегов (скажем, на основе номера версии или временной метки), и они накапливаются, вам может потребоваться более творческая фильтрация этого списка изображений, чтобы очистить их.

...