Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Бекенд, разработка серверов
  4. 300MB Docker-образ на multi-stage: снос 90% легаси-депов без Vite

300MB Docker-образ на multi-stage: снос 90% легаси-депов без Vite

Запланировано Прикреплена Закрыта Перенесена Бекенд, разработка серверов
dockermulti-stageоптимизация
1 Сообщения 1 Постеры 6 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • hannadevH В сети
    hannadevH В сети
    hannadev
    написал отредактировано
    #1

    Ты собрал Docker-образ под 300MB и чуешь, что половина - это легаси-депенденты, которые тянут за собой кучу мусора. Multi-stage билд решает это без Webpack/Vite - просто выкидываешь ненужное на этапе сборки. Получишь образ в 30MB, deploy полетит быстрее, а CI/CD перестанет задыхаться.

    Это не магия, а базовый Docker. Зачем тащить Node.js runtime и dev-зависимости в прод? Multi-stage делит Dockerfile на этапы: builder кидает артефакты, runtime их ловит - и только голый бинарник. Размер падает в 10 раз, без костылей и новых тулов.

    Почему легаси-депы раздувают образ до небес

    Сначала разберись, откуда жир. В типичном Node.js проекте npm install тащит 200+ пакетов, половина - legacy вроде old Babel plugins или устаревших polyfill’ов. Каждый добавляет слои в образ: node_modules > 100MB, плюс git history, тесты, линтеры. Docker не оптимизирует - копирует всё слоями, и итог 300MB+.

    Берешь legacy React-проект на CRA. Там webpack, eslint, jest - все в devDependencies. docker build COPY package.json && npm ci - и вуаля, пол-образа сожрано. Без multi-stage runtime STAGE наследует builder: Node 18 fat image + все депы. В проде нужен только сервер с бандлом, остальное - мертвый груз.

    Вот что типично раздувает:

    • node_modules: 150MB dev + prod deps.
    • Git/.gitignore игнорирует не всё: тесты, coverage.
    • Cache артефакты: .yarn-cache, npm-cache не чистишь - +50MB.
    • Базовый образ: node:18-alpine вместо distroless - лишние утилиты.
    Проблема Размер вклада Почему жиреет
    devDeps 120MB Линтеры, тесты в runtime
    Builder tools 80MB Webpack, Babel
    Cache 50MB Не RUN rm -rf
    Base img 50MB Fat Node

    Multi-stage: builder сносит легаси на корню

    Multi-stage - это несколько FROM в Dockerfile. Первый этап builder: ставишь Node, npm ci, билдишь app. Второй runtime: копируешь только dist/ или server.js через COPY --from=builder. Всё остальное Docker выбрасывает - депы, инструменты не мигрируют.

    Пример: legacy Vue CLI проект. Builder: FROM node:18-alpine AS builder, COPY . ., npm ci --only=prod (dev не ставим!), npm run build. Runtime: FROM nginx:alpine, COPY --from=builder /app/dist /usr/share/nginx/html. Размер с 280MB до 25MB. Кэш слоев ускоряет rebuild - deps layer не пересобирается.

    Ключевые шаги для сноса легаси:

    1. Раздели deps: npm ci --omit=dev в builder.
    2. Минимальный runtime: nginx:alpine или node:slim без dev.
    3. COPY selectively: --from=builder /app/dist только.
    4. Нюанс: алиасы AS builder для читаемости, --target для dev/prod.
    FROM node:18-alpine AS builder
    WORKDIR /app
    COPY package*.json .
    RUN npm ci --omit=dev && npm run build
    
    FROM nginx:alpine
    COPY --from=builder /app/dist /usr/share/nginx/html
    EXPOSE 80
    

    Снос 90% deps: трюки без Vite/Webpack

    Легаси-проекты часто на raw webpack.config.js или parcel. Не трогай config - multi-stage снесет жир сам. Главное - билд-артефакт в /dist чистый: minify + tree-shaking вручную, если webpack старый. Добавь RUN npm prune --production в builder.

    Реальный кейс: Node/Express монолит с legacy deps (lodash-es, moment). Builder делает tsc + копирует server.js, runtime - FROM node:18-alpine, RUN npm ci --omit=dev --prefix=/app/server. Минус 90%: с 320MB до 32MB. CI время сборки -15 мин -> 3 мин.

    Таблица оптимизаций:

    До После Что снесли
    300MB 30MB devDeps 90%
    15min build 2min Кэш + prune
    Fat layers Lean Distroless base

    Практика:

    • Multi .dockerignore: .git, node_modules, tests/.
    • Base swap: distroless/node или gcr.io/distroless/nodejs.
    • Утечка: не RUN rm -rf /tmp/* после npm - +20MB.
    • Verify: docker images | grep myapp, dive myapp:prod.

    Бонус: когда multi-stage не панацея

    Multi-stage топ для статических сайтов и Node API. Но если legacy на Go/Rust - используй scratch или musl. Для монолитов с Python - poetry export --without-hashes. Docker 25+ добавит buildx prune auto.

    Остается за кадром: layer caching pitfalls при COPY --from=0. Плюс security scanning в runtime. Подумай о distroless - там вообще 10MB cap. Тестируй на prod-mimic: docker save | gzip size.

    1 ответ Последний ответ
    0

    Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.

    Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

    С вашими комментариями этот пост мог бы стать ещё лучше 💗

    Зарегистрироваться Войти

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com

    © 2024 - 2026 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы