Установка и настройка Vendure (NestJS/TypeScript)
Vendure устанавливается через @vendure/create или вручную. Ручная установка предпочтительна если проект нестандартный: нужна конкретная версия, монорепозиторий, или интеграция в существующий NestJS-проект.
Системные требования
- Node.js 18+ (рекомендуется 20 LTS)
- PostgreSQL 12+ или MySQL 8+ (SQLite только для разработки)
- Redis 6+ (для воркеров и сессий в продакшне)
Установка через CLI
npx @vendure/create my-shop
Интерактивный мастер предложит выбрать:
- БД (PostgreSQL / MySQL / SQLite)
- Заполнить тестовыми данными
- Использовать TypeScript или JavaScript
Результат — рабочий проект с dev-скриптами.
Ручная установка (production-ready)
mkdir vendure-shop && cd vendure-shop
npm init -y
npm install @vendure/core @vendure/email-plugin @vendure/asset-server-plugin \
@vendure/admin-ui-plugin @nestjs/core @nestjs/common \
typeorm pg reflect-metadata ts-node typescript
npm install -D @types/node ts-node-dev
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2020",
"lib": ["ES2020"],
"strict": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"outDir": "dist",
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Переменные окружения
# .env
APP_ENV=development
SUPERADMIN_USERNAME=admin
SUPERADMIN_PASSWORD=changeme_in_production
DB_HOST=localhost
DB_PORT=5432
DB_NAME=vendure
DB_USER=vendure
DB_PASSWORD=vendure_secret
COOKIE_SECRET=your-32-char-secret-here
SMTP_HOST=smtp.mailgun.org
[email protected]
SMTP_PASS=smtp-password
ASSET_UPLOAD_DIR=/var/www/vendure/assets
SHOP_URL=https://shop.yourdomain.com
ADMIN_UI_URL=https://admin.yourdomain.com
Инициализация БД и миграции
# Сгенерировать первую миграцию
npm run build
npx ts-node src/migration.ts generate src/migrations/InitialSchema
# Применить миграции
npx ts-node src/migration.ts run
// src/migration.ts
import { DataSource } from "typeorm";
import { createConnection } from "@vendure/core";
import { config } from "./vendure-config";
const connection = createConnection(config.dbConnectionOptions);
const args = process.argv.slice(2);
const command = args[0];
const name = args[1];
(async () => {
const dataSource = new DataSource(config.dbConnectionOptions as any);
await dataSource.initialize();
if (command === "generate") {
await dataSource.driver.createSchemaBuilder().build();
} else if (command === "run") {
await dataSource.runMigrations();
}
await dataSource.destroy();
})();
Заполнение начальными данными
// src/populate.ts
import { bootstrap, VendureConfig } from "@vendure/core";
import { populate } from "@vendure/core/cli";
import { getSampleData } from "@vendure/create/assets/sample-data";
populate(
() => bootstrap(config),
getSampleData(),
{ logging: true }
).then(() => {
process.exit(0);
});
npx ts-node src/populate.ts
Запуск в development
// package.json scripts
{
"scripts": {
"dev:server": "ts-node-dev --respawn --transpile-only src/index.ts",
"dev:worker": "ts-node-dev --respawn --transpile-only src/worker.ts",
"dev": "concurrently \"npm run dev:server\" \"npm run dev:worker\"",
"build": "tsc",
"start": "node dist/index.js",
"start:worker": "node dist/worker.js",
"migration:generate": "ts-node src/migration.ts generate",
"migration:run": "ts-node src/migration.ts run"
}
}
Production деплой (Docker Compose)
# docker-compose.yml
version: "3.9"
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: vendure
POSTGRES_USER: vendure
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redisdata:/data
vendure-server:
build: .
command: node dist/index.js
env_file: .env.production
ports:
- "3000:3000"
depends_on:
- postgres
- redis
volumes:
- assets:/app/static/assets
vendure-worker:
build: .
command: node dist/worker.js
env_file: .env.production
depends_on:
- postgres
- redis
volumes:
- assets:/app/static/assets
volumes:
pgdata:
redisdata:
assets:
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
Nginx reverse proxy
server {
listen 443 ssl;
server_name shop.yourdomain.com;
location /shop-api/ {
proxy_pass http://vendure-server:3000/shop-api/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /assets/ {
proxy_pass http://vendure-server:3000/assets/;
expires 30d;
add_header Cache-Control "public, immutable";
}
location /admin/ {
proxy_pass http://vendure-server:3000/admin/;
}
}
Checklist после установки
- БД создана, миграции применены
- Суперадмин создан (
SUPERADMIN_USERNAME/PASSWORDв env) - Admin UI доступен по адресу
/admin - Shop API отвечает на
/shop-api? - Assets директория имеет права записи
- SMTP настроен (тест: создать заказ, проверить письмо)
- Worker запущен отдельным процессом
- Redis подключён (проверить логи воркера)
Установка занимает 4–8 часов при наличии готовой инфраструктуры (БД, Redis, CI/CD).







