Skip to content

Docker

Vite+ публикует официальный Docker-образ с предустановленным CLI vp:

bash
ghcr.io/voidzero-dev/vite-plus

Используйте его для сборки, CI и devcontainer-окружений. Он не предназначен для использования в качестве runtime-образа на продакшене.

vp определяет версию Node.js из вашего проекта (.node-version, devEngines.runtime или engines.node) и загружает именно эту версию во время установки/сборки. Поэтому образ не требует тегов под конкретные версии Node.js.

Для продакшена используйте многоэтапную сборку: собирайте приложение с помощью образа Vite+, затем копируйте только загруженный бинарник Node.js, результат сборки и продакшен-зависимости в более лёгкий runtime-образ.

Теги образа

Теги соответствуют версиям vp:

ТегЗначение
ghcr.io/voidzero-dev/vite-plus:latestПоследний релиз
ghcr.io/voidzero-dev/vite-plus:<major>Последняя мажорная
ghcr.io/voidzero-dev/vite-plus:<major>.<minor>Последняя минорная
ghcr.io/voidzero-dev/vite-plus:<major>.<minor>.<patch>Точная версия

В примерах используется :latest для отслеживания самого свежего релиза; при необходимости воспроизводимых сборок фиксируйте конкретный тег или digest. Образ публикуется для платформ linux/amd64 и linux/arm64 и по умолчанию запускается от непривилегированного пользователя. Этот пользователь может выполнять sudo без ввода пароля, поэтому этапы сборки или CI, требующие прав root (например, установка дополнительных пакетов через apt или выполнение playwright install --with-deps), работают без смены пользователя образа.

Все опубликованные версии и digest-значения доступны на странице GitHub Packages.

Продакшен: серверное приложение SSR / Node.js

Для приложений, которые запускаются в Node.js в продакшене (SvelteKit, Nuxt, собственный Vite SSR-сервер и т. д.), выполняйте сборку с помощью образа цепочки инструментов, а затем копируйте полученный Node.js и собранное приложение в облегчённый runtime-этап:

Dockerfile
dockerfile
# syntax=docker/dockerfile:1

# --- build stage: the official Vite+ toolchain image ---
FROM ghcr.io/voidzero-dev/vite-plus:latest AS build
WORKDIR /app

# Install dependencies first so this layer is cached across source changes.
COPY --chown=vp:vp package.json pnpm-lock.yaml pnpm-workspace.yaml .node-version* ./
RUN vp install --frozen-lockfile

# Build. vp reads .node-version and provisions that exact Node.js automatically.
COPY --chown=vp:vp . .
RUN vp build

# Export the exact resolved Node.js binary for the runtime stage.
RUN cp "$(vp env which node | head -1)" /tmp/node

# --- deps stage: production-only dependencies ---
# A separate, fresh `--prod` install so devDependencies (including the vite-plus
# toolchain) are excluded. Running `--prod` over the full install above would not
# prune the already-installed devDependencies.
FROM ghcr.io/voidzero-dev/vite-plus:latest AS deps
WORKDIR /app
COPY --chown=vp:vp package.json pnpm-lock.yaml pnpm-workspace.yaml .node-version* ./
RUN vp install --frozen-lockfile --prod

# --- runtime stage: small, glibc, no vp ---
FROM debian:bookworm-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production

# The exact Node.js from .node-version (official, signature-verified build).
COPY --from=build /tmp/node /usr/local/bin/node

COPY --from=build /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/package.json ./

USER nobody
EXPOSE 3000
CMD ["node", "dist/server.js"]

Собранный образ содержит только Node.js, ваше приложение и продакшен-зависимости и полностью соответствует .node-version. Он значительно меньше стандартного образа node:*; см. совет по distroless ниже для получения минимального размера.

Удаление продакшен-зависимостей в отдельном этапе

Устанавливайте продакшен-зависимости в отдельном этапе deps, как показано ниже. Запуск vp install --prod после полного vp install в том же этапе не удаляет уже установленные devDependencies, поэтому цепочка инструментов vite-plus будет скопирована в runtime-образ. Если серверный бандл полностью самодостаточный (без неупакованных зависимостей во время выполнения), можно не копировать node_modules вообще.

Ещё меньше размер

Для минимального runtime без shell и с минимальной поверхностью CVE замените базовый образ runtime на distroless (gcr.io/distroless/cc) и используйте ENTRYPOINT в векторной форме. Он основан на glibc, поэтому скопированный бинарник Node.js остаётся совместимым.

Продакшен: статический SPA / SSG

Статическому сайту Node.js во время выполнения не требуется; просто раздавайте собранный результат любым статическим сервером:

Dockerfile
dockerfile
FROM ghcr.io/voidzero-dev/vite-plus:latest AS build
WORKDIR /app
COPY --chown=vp:vp package.json pnpm-lock.yaml pnpm-workspace.yaml .node-version* ./
RUN vp install --frozen-lockfile
COPY --chown=vp:vp . .
RUN vp build

FROM nginx:alpine AS runtime
COPY --from=build /app/dist /usr/share/nginx/html

Непрерывная интеграция

Используйте образ напрямую в контейнерных CI-системах (GitLab CI, Buildkite, CircleCI, Jenkins и других):

.gitlab-ci.yml
yaml
build:
  image: ghcr.io/voidzero-dev/vite-plus:latest
  script:
    - vp install --frozen-lockfile
    - vp check
    - vp test
    - vp build

На GitHub Actions предпочтительно использовать setup-vp вместо образа.

Тесты в режиме браузера (Vitest / Playwright)

Запуск от имени непривилегированного пользователя vp — именно то, что нужно для браузеров: Chromium сохраняет свою песочницу (при запуске браузера от имени root она отключается). Установите браузер и его системные библиотеки в рамках задания. Команде playwright install --with-deps требуются права root для установки этих библиотек через apt-get install. Пользователь vp может выполнять sudo без ввода пароля, поэтому Playwright использует его для установки библиотек без смены пользователя образа:

.gitlab-ci.yml
yaml
test:
  image: ghcr.io/voidzero-dev/vite-plus:latest
  script:
    - vp install --frozen-lockfile
    - vp exec playwright install --with-deps chromium
    - vp test

vp exec запускает Playwright, установленный в самом проекте (согласно вашему lock-файлу), поэтому устанавливается именно та версия браузера, которую ожидают ваши тесты. Предпочитайте его вместо vpx playwright install, так как эта команда загрузит последнюю доступную версию Playwright, которая может установить другую версию браузера.

Чтобы встроить браузер и его системные библиотеки в производный образ вместо их установки при каждом запуске, сначала установите зависимости проекта, чтобы встроенная версия браузера соответствовала вашему lock-файлу, а затем выполните установку с помощью Playwright из проекта (права root доступны через sudo):

Dockerfile
dockerfile
FROM ghcr.io/voidzero-dev/vite-plus:latest
WORKDIR /app
COPY --chown=vp:vp package.json pnpm-lock.yaml pnpm-workspace.yaml .node-version* ./
RUN vp install --frozen-lockfile
RUN vp exec playwright install --with-deps chromium

Если Chromium аварийно завершается под высокой нагрузкой в CI, выделите контейнеру больше общей памяти с помощью --ipc=host; см. документацию Playwright по Docker.

Devcontainers

Используйте образ как готовый контейнер для разработки с предустановленной цепочкой инструментов:

.devcontainer/devcontainer.json
jsonc
{
  "image": "ghcr.io/voidzero-dev/vite-plus:latest",
}

Разовое использование

Запускайте любую команду vp для проекта без установки vp на локальную машину:

bash
docker run --rm -it -v "$PWD:/app" -w /app ghcr.io/voidzero-dev/vite-plus vp build

Примечания

  • Версия Node.js: определяется во время сборки из .node-version, engines.node или devEngines.runtime, поэтому отдельные теги образа под Node.js не нужны. Копирование зависимостей использует glob .node-version*, поэтому файл необязателен: проекты, которые фиксируют версию через engines.node или devEngines.runtime, могут не иметь .node-version, а при его наличии он доступен на всех этапах.
  • Непривилегированный пользователь: образ запускается от пользователя vp без root-прав, поэтому исходники нужно копировать с COPY --chown=vp:vp ..., как показано выше. Без этого файлы будут принадлежать root, и vp install не сможет их изменять (ошибка доступа). Пользователь vp имеет право выполнять sudo без ввода пароля для редких действий, требующих прав суперпользователя (например, установки дополнительных пакетов через apt или выполнения playwright install --with-deps), поэтому вам редко потребуется переключаться на другого пользователя в образе. Этап выполнения в продакшене использует отдельный базовый образ без пользователя vp, поэтому это удобство не распространяется на ваш развёрнутый образ.
  • Нативные модули: образ содержит инструменты C/C++ (build-essential, python3), поэтому нативные зависимости, такие как better-sqlite3, собираются во время vp install.
  • glibc: образ основан на glibc, поэтому используется официальный, подписанный Node.js.
  • Пользовательский базовый образ: чтобы добавить vp в собственный базовый образ, используйте установщик: curl -fsSL https://vite.plus | bash (зафиксируйте версию через VP_VERSION для воспроизводимости).