4248b649ed
Co-authored-by: Cursor <cursoragent@cursor.com>
402 lines
10 KiB
Markdown
402 lines
10 KiB
Markdown
# Shop
|
||
|
||
**v0.10.0** — интернет-магазин на **Node.js** и **PostgreSQL 17**.
|
||
|
||
Два способа установки: [Docker Compose](#docker-compose-рекомендуется-для-теста) | [без Docker (Ubuntu)](#postgresql-17-без-docker)
|
||
|
||
Подробности релиза: [CHANGELOG.md](CHANGELOG.md) · [docs/RELEASE-0.10.md](docs/RELEASE-0.10.md)
|
||
|
||
## Возможности
|
||
|
||
- Каталог товаров с категориями и поиском
|
||
- Корзина и оформление заказа
|
||
- Регистрация и вход пользователей
|
||
- История заказов в личном кабинете
|
||
|
||
## Требования
|
||
|
||
- Node.js 18+ и PostgreSQL 17 — **или** Docker / Docker Compose
|
||
|
||
---
|
||
|
||
## Docker Compose (рекомендуется для теста)
|
||
|
||
Полный стек: **PostgreSQL 17** + **приложение Node.js**.
|
||
|
||
```bash
|
||
cp .env.docker.example .env
|
||
# Отредактируйте SESSION_SECRET в .env
|
||
|
||
docker compose up -d --build
|
||
docker compose ps
|
||
curl -s http://127.0.0.1:3000/health
|
||
```
|
||
|
||
Сайт: **http://localhost:3000**
|
||
|
||
| Команда | Описание |
|
||
|---------|----------|
|
||
| `docker compose up -d --build` | Сборка и запуск |
|
||
| `docker compose logs -f app` | Логи приложения |
|
||
| `docker compose down` | Остановка |
|
||
| `docker compose down -v` | Остановка + удаление БД |
|
||
|
||
### Caddy в Docker (HTTPS, опционально)
|
||
|
||
```bash
|
||
# В .env: TRUST_PROXY=1
|
||
# Отредактируйте caddy/Caddyfile.docker.example (домен)
|
||
docker compose --profile proxy up -d --build
|
||
```
|
||
|
||
Порты: **80**, **443** (Caddy) → `app:3000`.
|
||
|
||
### Только PostgreSQL (разработка на хосте)
|
||
|
||
```bash
|
||
docker compose -f docker-compose.dev.yml up -d
|
||
cp .env.example .env
|
||
# DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop
|
||
npm install && npm run dev
|
||
```
|
||
|
||
### Файлы
|
||
|
||
| Файл | Назначение |
|
||
|------|------------|
|
||
| `Dockerfile` | Образ приложения |
|
||
| `docker-compose.yml` | app + postgres (+ caddy с профилем `proxy`) |
|
||
| `docker-compose.dev.yml` | только postgres для `npm run dev` |
|
||
| `.env.docker.example` | переменные для compose |
|
||
|
||
---
|
||
|
||
## PostgreSQL 17 (без Docker)
|
||
|
||
### Ubuntu (сервер)
|
||
|
||
```bash
|
||
apt update
|
||
apt install -y postgresql-17 postgresql-client-17
|
||
systemctl enable postgresql
|
||
systemctl start postgresql
|
||
```
|
||
|
||
Если пакета `postgresql-17` нет в репозитории Ubuntu, подключите [PGDG](https://www.postgresql.org/download/linux/ubuntu/):
|
||
|
||
```bash
|
||
apt install -y curl ca-certificates
|
||
install -d /usr/share/postgresql-common/pgdg
|
||
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
|
||
sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(. /etc/os-release && echo ${VERSION_CODENAME}-pgdg) main" > /etc/apt/sources.list.d/pgdg.list'
|
||
apt update
|
||
apt install -y postgresql-17 postgresql-client-17
|
||
```
|
||
|
||
Пользователь и база `shop`:
|
||
|
||
```bash
|
||
cd /opt/shop
|
||
bash scripts/setup-postgres-ubuntu.sh
|
||
```
|
||
|
||
Схема: `postgres/init/01_schema.sql` (применяется при старте приложения).
|
||
|
||
Сессии — таблица `session` в PostgreSQL (создаётся автоматически).
|
||
|
||
---
|
||
|
||
## Быстрый развёртывание на Ubuntu
|
||
|
||
```bash
|
||
# 1. Система + Node.js 20
|
||
apt update
|
||
apt install -y git curl
|
||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||
apt install -y nodejs
|
||
|
||
# 2. PostgreSQL 17
|
||
apt install -y postgresql-17 postgresql-client-17
|
||
|
||
# 3. Код
|
||
cd /opt
|
||
git clone <URL_РЕПОЗИТОРИЯ> shop
|
||
cd shop
|
||
|
||
# 4. БД
|
||
bash scripts/setup-postgres-ubuntu.sh
|
||
|
||
# 5. Окружение
|
||
cp .env.example .env
|
||
sed -i "s/change-me-to-a-long-random-string/$(openssl rand -hex 32)/" .env
|
||
# Проверьте DATABASE_URL в .env
|
||
|
||
# 6. Приложение
|
||
npm install --omit=dev
|
||
npm start
|
||
```
|
||
|
||
Проверка:
|
||
|
||
```bash
|
||
curl -s http://127.0.0.1:3000/health
|
||
# {"ok":true,"service":"shop","database":"postgresql"}
|
||
```
|
||
|
||
### Переменные `.env`
|
||
|
||
```env
|
||
PORT=3000
|
||
HOST=127.0.0.1
|
||
NODE_ENV=production
|
||
TRUST_PROXY=1
|
||
SESSION_SECRET=длинный-секрет
|
||
DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop
|
||
```
|
||
|
||
| Переменная | Описание |
|
||
|------------|----------|
|
||
| `DATABASE_URL` | Строка подключения PostgreSQL |
|
||
| `PGHOST`, `PGPORT`, `PGUSER`, `PGPASSWORD`, `PGDATABASE` | Альтернатива `DATABASE_URL` |
|
||
| `HOST` | `127.0.0.1` в production (доступ через Caddy) |
|
||
|
||
---
|
||
|
||
## Запуск как служба (systemd)
|
||
|
||
```bash
|
||
cp /opt/shop/deploy/shop.service /etc/systemd/system/shop.service
|
||
|
||
cd /opt/shop
|
||
cp .env.example .env # при первой установке
|
||
# Заполните SESSION_SECRET и DATABASE_URL
|
||
|
||
npm install --omit=dev
|
||
|
||
# Не делайте chown -R www-data на весь /opt/shop (ломает git pull)
|
||
systemctl daemon-reload
|
||
systemctl enable shop
|
||
systemctl start shop
|
||
journalctl -u shop -f
|
||
```
|
||
|
||
`EnvironmentFile=/opt/shop/.env` должен содержать `DATABASE_URL`.
|
||
|
||
---
|
||
|
||
## Проверка после установки
|
||
|
||
```bash
|
||
systemctl restart shop
|
||
sleep 1
|
||
curl -s http://127.0.0.1:3000/health
|
||
ss -tlnp | grep 3000
|
||
journalctl -u shop -n 5 --no-pager
|
||
# Магазин: http://127.0.0.1:3000 (PostgreSQL)
|
||
```
|
||
|
||
---
|
||
|
||
## Обновление на сервере (git pull)
|
||
|
||
```bash
|
||
cd /opt/shop
|
||
git config --global --add safe.directory /opt/shop
|
||
bash scripts/server-update.sh
|
||
```
|
||
|
||
Скрипт: `git pull` → `npm install` → проверка PostgreSQL → `restart shop` → `curl /health` → `reload caddy`.
|
||
|
||
Вручную:
|
||
|
||
```bash
|
||
cd /opt/shop
|
||
git pull
|
||
npm install --omit=dev
|
||
systemctl restart shop
|
||
curl -s http://127.0.0.1:3000/health
|
||
systemctl reload caddy
|
||
```
|
||
|
||
---
|
||
|
||
## Переход с SQLite на PostgreSQL 17
|
||
|
||
Если сервер уже работал на старой версии (файлы `data/*.db`):
|
||
|
||
```bash
|
||
# 1. PostgreSQL
|
||
apt install -y postgresql-17 postgresql-client-17
|
||
systemctl start postgresql
|
||
|
||
# 2. Код
|
||
cd /opt/shop
|
||
git config --global --add safe.directory /opt/shop
|
||
git pull
|
||
|
||
# 3. База shop
|
||
bash scripts/setup-postgres-ubuntu.sh
|
||
|
||
# 4. .env — обязательно DATABASE_URL
|
||
cp -n .env.example .env
|
||
nano .env
|
||
# DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop
|
||
# HOST=127.0.0.1
|
||
# NODE_ENV=production
|
||
# TRUST_PROXY=1
|
||
|
||
# 5. Зависимости и перезапуск
|
||
npm install --omit=dev
|
||
systemctl restart shop
|
||
|
||
# 6. Проверка
|
||
curl -s http://127.0.0.1:3000/health
|
||
systemctl reload caddy
|
||
```
|
||
|
||
Каталог `data/` больше не используется. Демо-товары появятся при пустой таблице `products`. Аккаунты и заказы из SQLite не переносятся — нужна повторная регистрация или ручной импорт.
|
||
|
||
Проверка PostgreSQL:
|
||
|
||
```bash
|
||
psql "postgresql://shop:shop@127.0.0.1:5432/shop" -c '\dt'
|
||
```
|
||
|
||
---
|
||
|
||
## Caddy — SSL и reverse proxy
|
||
|
||
**Перед Caddy:** `curl http://127.0.0.1:3000/health` → OK.
|
||
|
||
```bash
|
||
apt install -y debian-keyring debian-archive-keyring apt-transport-https
|
||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
|
||
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
|
||
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
|
||
| tee /etc/apt/sources.list.d/caddy-stable.list
|
||
apt update && apt install -y caddy
|
||
|
||
cp /opt/shop/caddy/Caddyfile.example /etc/caddy/Caddyfile
|
||
nano /etc/caddy/Caddyfile # ваш домен и email
|
||
|
||
caddy validate --config /etc/caddy/Caddyfile
|
||
systemctl enable caddy
|
||
systemctl reload caddy
|
||
```
|
||
|
||
Пример `Caddyfile`:
|
||
|
||
```caddyfile
|
||
{
|
||
email admin@example.com
|
||
}
|
||
|
||
shop.example.com {
|
||
encode gzip zstd
|
||
reverse_proxy 127.0.0.1:3000
|
||
}
|
||
```
|
||
|
||
Порты **80/443** открыть; **5432** и **3000** наружу не публиковать.
|
||
|
||
### Ошибка `ECONNREFUSED 127.0.0.1:5432`
|
||
|
||
Приложение обновилось на PostgreSQL, а сервер БД не запущен.
|
||
|
||
**Быстрое исправление (одной командой):**
|
||
|
||
```bash
|
||
cd /opt/shop
|
||
git pull
|
||
bash scripts/fix-db-connection.sh
|
||
```
|
||
|
||
**Вручную:**
|
||
|
||
```bash
|
||
apt install -y postgresql-17 postgresql-client-17
|
||
systemctl enable --now postgresql
|
||
pg_isready -h 127.0.0.1 -p 5432
|
||
|
||
cd /opt/shop
|
||
bash scripts/setup-postgres-ubuntu.sh
|
||
nano .env # DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop
|
||
|
||
cp deploy/shop.service /etc/systemd/system/shop.service
|
||
systemctl daemon-reload
|
||
systemctl restart shop
|
||
curl -s http://127.0.0.1:3000/health
|
||
```
|
||
|
||
### HTTP 502
|
||
|
||
```bash
|
||
bash /opt/shop/scripts/diagnose-502.sh
|
||
journalctl -u shop -n 50 --no-pager
|
||
```
|
||
|
||
| Причина | Решение |
|
||
|--------|---------|
|
||
| `ECONNREFUSED 127.0.0.1:5432` | PostgreSQL не запущен или не установлен — см. ниже |
|
||
| PostgreSQL не запущен | `systemctl enable --now postgresql` |
|
||
| Неверный `DATABASE_URL` | проверить `.env`, `psql` |
|
||
| Node не слушает 3000 | `journalctl -u shop -f` |
|
||
| Caddy без backend | сначала `curl /health`, потом `reload caddy` |
|
||
|
||
---
|
||
|
||
## Локальная разработка
|
||
|
||
```bash
|
||
docker compose -f docker-compose.dev.yml up -d
|
||
cp .env.example .env
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
## Скрипты npm
|
||
|
||
| Команда | Описание |
|
||
|---------|----------|
|
||
| `npm start` | Запуск сервера |
|
||
| `npm run dev` | С автоперезагрузкой |
|
||
| `npm run seed` | Демо-товары (если каталог пуст) |
|
||
|
||
## Структура
|
||
|
||
```
|
||
Dockerfile
|
||
docker-compose.yml
|
||
docker-compose.dev.yml
|
||
postgres/init/01_schema.sql
|
||
caddy/Caddyfile.example
|
||
caddy/Caddyfile.docker.example
|
||
deploy/shop.service
|
||
scripts/
|
||
setup-postgres-ubuntu.sh
|
||
fix-db-connection.sh
|
||
diagnose-502.sh
|
||
server-update.sh
|
||
src/
|
||
```
|
||
|
||
## Релиз 0.10.0
|
||
|
||
```bash
|
||
git clone <URL_РЕПОЗИТОРИЯ> shop
|
||
cd shop
|
||
git checkout v0.10.0
|
||
```
|
||
|
||
| Способ | Команда |
|
||
|--------|---------|
|
||
| Docker | `docker compose up -d --build` |
|
||
| Без Docker | `bash scripts/setup-postgres-ubuntu.sh` → `systemctl start shop` |
|
||
|
||
## Репозиторий
|
||
|
||
```bash
|
||
git clone <URL_РЕПОЗИТОРИЯ> shop
|
||
cd shop
|
||
```
|