feat: add Docker deployment (Dockerfile, docker-compose, .dockerignore) and update docs

- Multi-stage Dockerfile (node:22-slim, bun build, standalone output, non-root)
- docker-compose.yml with DB volume, healthcheck, memory limits
- .dockerignore to exclude dev artifacts from build context
- docs: full deployment guide with docker compose, manual docker, env vars,
  reverse proxy configs (Caddy/Nginx), update instructions, server requirements
- docs: comparison table old (Node.js bot) vs new (Next.js admin)
This commit is contained in:
Z User
2026-08-05 23:27:35 +00:00
parent abcc8a02f2
commit de6f82bd00
4 changed files with 270 additions and 8 deletions

27
.dockerignore Normal file
View File

@@ -0,0 +1,27 @@
node_modules
.next
.git
git
*.md
db/*.db
db/*.db-journal
tool-results/
agent-ctx/
.zscripts/
screenshot-*.png
keepalive.js
seed-standalone.ts
standalone-server.js
gitea-*.json
*.log
dev.log
server.log
.env
.dev
tests/
examples/
mini-services/
upload/
download/
Claude.md
.claude

59
Dockerfile Normal file
View File

@@ -0,0 +1,59 @@
# --- Stage 1: Build ---
FROM node:22-slim AS builder
WORKDIR /app
# Install bun for faster installs
RUN npm install -g bun
# Install dependencies
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
# Copy source
COPY prisma ./prisma/
COPY tsconfig.json next.config.ts postcss.config.mjs tailwind.config.ts components.json ./
COPY public ./public/
COPY src ./src/
# Generate Prisma client
RUN npx prisma generate
# Build Next.js (output: standalone)
RUN npx next build
# Copy static assets into standalone
RUN cp -r .next/static .next/standalone/.next/ && \
cp -r public .next/standalone/
# --- Stage 2: Production ---
FROM node:22-slim AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Create non-root user
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Copy standalone output
COPY --from=builder /app/.next/standalone ./
# Copy static files
COPY --from=builder /app/.next/standalone/.next ./.next
# Copy Prisma schema for potential migrations
COPY --from=builder /app/prisma ./prisma/
# Create db directory
RUN mkdir -p /app/db && chown nextjs:nodejs /app/db
# Switch to non-root
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

32
docker-compose.yml Normal file
View File

@@ -0,0 +1,32 @@
services:
admin:
build:
context: .
dockerfile: ./Dockerfile
container_name: tg_shop_admin
restart: always
ports:
- "3000:3000"
environment:
# === Обязательные ===
- DATABASE_URL=file:/app/db/custom.db
- ADMIN_SECRET=${ADMIN_SECRET:-changeme}
- SUPER_ADMIN_SECRET=${SUPER_ADMIN_SECRET:-changeme_super}
# === ИИ-чатбот (опционально) ===
- CHATBOT_API_KEY=${CHATBOT_API_KEY:-}
- CHATBOT_API_ENDPOINT=${CHATBOT_API_ENDPOINT:-https://api.openai.com/v1}
volumes:
# Персистентная база данных
- ./db:/app/db
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
healthcheck:
test: ["CMD", "node", "-e", "const http = require('http'); http.get('http://localhost:3000/api/auth/session', r => { process.exit(r.statusCode === 401 ? 0 : 1) }).on('error', () => process.exit(1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s

View File

@@ -243,18 +243,162 @@ model Lead {
- Оператор видит всю историю переписки
- При отключении — бот снова отвечает
## Docker (ARM)
## Развертывание (Docker)
### Сравнение со старой версией
| | Старая (Node.js бот) | Новая (Next.js админка) |
|---|---|---|
| Dockerfile | `FROM node:22`, `npm install`, `CMD node src/index.js` | Multi-stage build, standalone output, non-root user |
| docker-compose | 1 сервис, BOT_TOKEN + ADMIN_IDS | 1 сервис, ADMIN_SECRET + CHATBOT_API_KEY |
| БД | `./db/shop.db` (sqlite3 напрямую) | `./db/custom.db` (через Prisma ORM) |
| Порт | Нет (только TG webhook) | 3000 (веб-интерфейс + API) |
| RAM | ~64 MB | ~256512 MB |
### Быстрый старт (docker compose)
```bash
docker build -t tg-admin .
docker run -p 3000:3000 -v ./db:/app/db \
-e ADMIN_SECRET=your_secret \
-e SUPER_ADMIN_SECRET=super_secret \
-e CHATBOT_API_KEY=sk-xxx \
tg-admin
# 1. Клонировать ветку
GIT_LFS_SKIP_SMUDGE=1 git clone -b feat/nextjs-admin https://git.softuniq.eu/Telegram-Market/telegram-shop.git
CD telegram-shop
# 2. Создать .env файл
cat > .env << 'EOF'
ADMIN_SECRET=your_admin_password
SUPER_ADMIN_SECRET=your_super_admin_password
CHATBOT_API_KEY=sk-your-openai-key # опционально, для ИИ-бота
CHATBOT_API_ENDPOINT=https://api.openai.com/v1 # или другой провайдер
EOF
# 3. Создать папку для БД
mkdir -p db
# 4. Собрать и запустить
COMPOSE_DOCKER_CLI_BUILD=1 DOCKER_BUILDKIT=1 docker compose up -d --build
# 5. Дождаться запуска (15-30 сек)
docker compose logs -f
```
Требования: минимум 512 МБ RAM, ARM64/ARMv7/x86_64.
После запуска админка доступна на `http://<IP>:3000`.
### Ручной Docker (без compose)
```bash
# Сборка
docker build -t tg-shop-admin .
# Запуск
docker run -d \
--name tg_shop_admin \
--restart always \
-p 3000:3000 \
-v $(pwd)/db:/app/db \
-e ADMIN_SECRET=your_admin_password \
-e SUPER_ADMIN_SECRET=your_super_admin_password \
-e CHATBOT_API_KEY=sk-xxx \
-m 512m \
tg-shop-admin
```
### Переменные окружения
| Переменная | Обязательна | По умолчанию | Описание |
|---|---|---|---|
| `DATABASE_URL` | Нет | `file:/app/db/custom.db` | Путь к SQLite БД внутри контейнера |
| `ADMIN_SECRET` | **Да** | `changeme` | Пароль для роли admin |
| `SUPER_ADMIN_SECRET` | Нет | — | Пароль для роли super_admin |
| `CHATBOT_API_KEY` | Нет | — | API-ключ для ИИ-бота (OpenAI/DeepSeek/etc) |
| `CHATBOT_API_ENDPOINT` | Нет | `https://api.openai.com/v1` | Endpoint LLM-провайдера |
### Запуск без Docker (разработка)
```bash
# Установить зависимости
bun install
# Инициализация БД
bun run db:push
# Создать .env
echo 'DATABASE_URL=file:./db/custom.db' > .env
echo 'ADMIN_SECRET=admin123' >> .env
echo 'SUPER_ADMIN_SECRET=superadmin456' >> .env
# Генерация тестовых данных (опционально)
curl -X POST http://localhost:3000/api/seed/demo \
-H 'Cookie: admin_token=<your_token>'
# Dev-сервер
bun run dev # http://localhost:3000
# Production
bun run build # сборка standalone
bun run start # запуск production
```
### Первоначальная настройка после деплоя
1. Открыть `http://<IP>:3000`
2. Войти с паролем из `ADMIN_SECRET`
3. Перейти в **Settings** (`#/settings`) — настроить параметры магазина
4. Перейти в **AI Chatbot** (`#/chatbot`) — настроить ИИ-бота:
- Ввести API-ключ и выбрать провайдера
- Настроить системный промпт
- Добавить базу знаний (словарный лексикон)
5. Перейти в **Danger Zone****Seed Demo Data** для заполнения тестовыми данными
6. Очистить тестовые данные через **Clear Database** перед продакшеном
### Обновление
```bash
# docker compose
git pull
docker compose up -d --build
# ручной
git pull
docker build -t tg-shop-admin .
docker stop tg_shop_admin && docker rm tg_shop_admin
# повторить docker run ...
```
**Важно:** БД хранится в volume `./db`, она сохраняется при пересборке.
### Требования к серверу
| Ресурс | Минимум | Рекомендуется |
|---|---|---|
| CPU | 1 ядро | 2 ядра |
| RAM | 256 MB | 512 MB |
| Диск | 500 MB (образ) + БД | 1 GB |
| Архитектура | x86_64, ARM64 | — |
### Reverse Proxy (Caddy / Nginx)
**Caddy** (авто HTTPS):
```
admin.yourdomain.com {
reverse_proxy localhost:3000
}
```
**Nginx**:
```nginx
server {
listen 443 ssl;
server_name admin.yourdomain.com;
# ... ssl certs ...
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
## Seed-данные