LINUX.ORG.RU
ФорумAdmin

Почему в Dockerfile для NodeJS используется 2 FROM?

 


0

1

Всем привет. Я лалка в девопсе, но объясните плиз Вот пример «дефолтного» Dockerfile для запуска NextJS:

FROM node:22.0 as builder

WORKDIR /app

COPY package.json .
COPY package-lock.json .

RUN npm ci

COPY . .

RUN npm run build

FROM node:22.0

COPY --from=builder /app ./

EXPOSE 3000

CMD ["npm", "run", "start"]

Вопрос: Зачем мы два раза пишем FROM node:22.0?

И зачем мы каждый раз делаем COPY?

Это для двух разных этапов сборки. Используется multistage сборка. Первый с альясом (as builder), вторйо без.

  1. Первый этап (builder):
  • Docker строит образ от базового образа node:22.0 и задает алиас builder для этого этапа.
  • Устанавливается рабочая директория в /app.
  • Копируются package.json и package-lock.json.
  • Запускается npm ci для установки зависимостей из package-lock.json.
  • Копируются все файлы и папки из текущего каталога в контейнер.
  • Запускается npm run build для сборки приложения.
  1. Второй этап:
  • Docker начинает новый этап с базового образа node:22.0 без алиаса.
  • Копируется содержимое из первого этапа, используя COPY –from=builder /app ./, чтобы скопировать все файлы из директории /app.
  • Выставляется порт экспозиции 3000 для контейнера.
  • Устанавливается команда запуска приложения через CMD [«npm», «run», «start»].

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

PPP328 ★★★★★
()
Последнее исправление: PPP328 (всего исправлений: 1)
Ответ на: комментарий от PPP328

Понял) Только у меня тогда вопрос: Если сделать так:

FROM node:22.0 as builder

WORKDIR /app

COPY package.json .
COPY package-lock.json .

RUN npm ci

COPY . .

RUN npm run build

COPY . . # ДОБАВИЛ ЭТУ!!!!!!!!!

# FROM node:22.0 убрал эту строчку

# COPY --from=builder /app ./ и эту убрал

EXPOSE 3000

CMD ["npm", "run", "start"]

То тогда с этим конфигом я получаю ошибку directory .next not found .next - это директория в который лежит «собранный» nextjs Но я тогда не могу понять, почему после npm run build «CMD» не видит .next директорию? А вот если добавить «второй FROM» и в него скопировать «все файлы» из первого FROM, то тогда все работает

Почему он не видит .next директорию, когда у нас «один FROM»?

romanlinux ★★★
() автор топика
Ответ на: комментарий от romanlinux

Инструкция: COPY . . копирует заново содержимое сборочной директории, в контейнер. Видимо перезатирая в поддиректориях внутри контейнера.

Если тебе нужен контейнер с мусором от сборки сделай так:

FROM node:22.0

WORKDIR /app

COPY package.json .
COPY package-lock.json .

RUN npm ci

COPY . .

RUN npm run build

EXPOSE 3000

CMD ["npm", "run", "start"]
anonymous
()
Ответ на: комментарий от PPP328

Ничего он не копирует, там же точки, скопировал точку, вставил точку.

Что ты чушь пишешь, автору темы виднее же.

Её вообще можно удалить, зачем точки попировать.

anonymous
()
Ответ на: комментарий от firkax

Да не мне в принципе устраивает как docker и nodejs работает (и вместе и по отдельности) xDDD

Мне просто стало интересно, зачем делают два «FROM…» из «одного и тогоже» образа. Но теперь я понял спс)

romanlinux ★★★
() автор топика
Ответ на: комментарий от romanlinux

Сорян я чайник по докеру.

В изучение докера стоит инвестировать время, это важная технология.

А что именно в нем стоит изменить?

Из того, что в глаза бросилось:

  1. Использовать node lts и alpine образ

  2. Все операции делать от отдельного юзера, а не от рута.

  3. Вот тут неэффективно:

COPY package.json .
COPY package-lock.json .

Эти две команды создают два слоя. Их надо объединить в одну команду COPY package.json package-lock.json .

  1. COPY . . это полная дичь, которая копирует в образ кучу мусора. В сборочный образ копировать нужно ровно те файлы, которые нужны для сборки. Твой README.md для сборки не нужен.

  2. COPY --from=builder /app ./ это ещё одна дичь. В конечный образ копировать нужно ровно те файлы, которые нужны для работы. Скорей всего это что-то вроде /app/dist. С node_modules тоже нужно аккуратно разбираться. Модули, которые нужны для сборки, для работы не нужны и в конечном образе будут являться мусором. К примеру компилятор typescript-а. Ну и /app/src для работы, очевидно, тоже не нужен.

В общем это максимально ленивый и непродуманный Dockefile из разряда «и так сойдёт», которые и создают негативный образ технологии.

vbr ★★★★
()