7060b0566a
pg + connect-pg-simple, async routes, docker-compose, скрипт setup-postgres. Co-authored-by: Cursor <cursoragent@cursor.com>
233 lines
5.7 KiB
Markdown
233 lines
5.7 KiB
Markdown
# Shop
|
|
|
|
Интернет-магазин на **Node.js** и **PostgreSQL 17**.
|
|
|
|
## Возможности
|
|
|
|
- Каталог товаров с категориями и поиском
|
|
- Корзина и оформление заказа
|
|
- Регистрация и вход пользователей
|
|
- История заказов в личном кабинете
|
|
|
|
## Требования
|
|
|
|
- Node.js 18+
|
|
- PostgreSQL 17
|
|
- npm
|
|
|
|
---
|
|
|
|
## PostgreSQL 17
|
|
|
|
### Docker (разработка / тест)
|
|
|
|
```bash
|
|
docker compose up -d
|
|
# БД: postgresql://shop:shop@127.0.0.1:5432/shop
|
|
```
|
|
|
|
### Ubuntu (сервер)
|
|
|
|
```bash
|
|
apt update
|
|
apt install -y postgresql-17 postgresql-client-17
|
|
|
|
# Пользователь и база shop
|
|
cd /opt/shop
|
|
sudo bash scripts/setup-postgres-ubuntu.sh
|
|
```
|
|
|
|
Схема таблиц: `postgres/init/01_schema.sql` (применяется при старте приложения и при первом запуске Docker).
|
|
|
|
Сессии хранятся в PostgreSQL (таблица `session`, создаётся автоматически).
|
|
|
|
---
|
|
|
|
## Быстрый развёртывание на 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
|
|
git config --global --add safe.directory /opt/shop
|
|
npm install --omit=dev
|
|
|
|
# Код — root, служба — www-data (только чтение кода достаточно)
|
|
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)
|
|
```
|
|
|
|
Обновление:
|
|
|
|
```bash
|
|
bash /opt/shop/scripts/server-update.sh
|
|
```
|
|
|
|
---
|
|
|
|
## 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** наружу не публиковать.
|
|
|
|
### HTTP 502
|
|
|
|
```bash
|
|
bash /opt/shop/scripts/diagnose-502.sh
|
|
journalctl -u shop -n 50 --no-pager
|
|
```
|
|
|
|
| Причина | Решение |
|
|
|--------|---------|
|
|
| PostgreSQL не запущен | `systemctl start postgresql` |
|
|
| Неверный `DATABASE_URL` | проверить `.env`, `psql` |
|
|
| Node не слушает 3000 | `journalctl -u shop -f` |
|
|
| Caddy без backend | сначала `curl /health`, потом `reload caddy` |
|
|
|
|
---
|
|
|
|
## Локальная разработка
|
|
|
|
```bash
|
|
docker compose up -d
|
|
cp .env.example .env
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
## Скрипты npm
|
|
|
|
| Команда | Описание |
|
|
|---------|----------|
|
|
| `npm start` | Запуск сервера |
|
|
| `npm run dev` | С автоперезагрузкой |
|
|
| `npm run seed` | Демо-товары (если каталог пуст) |
|
|
|
|
## Структура
|
|
|
|
```
|
|
postgres/init/01_schema.sql
|
|
docker-compose.yml — PostgreSQL 17 локально
|
|
caddy/Caddyfile.example
|
|
deploy/shop.service
|
|
scripts/
|
|
setup-postgres-ubuntu.sh
|
|
diagnose-502.sh
|
|
server-update.sh
|
|
src/
|
|
```
|
|
|
|
## Миграция с SQLite
|
|
|
|
Старая версия хранила данные в `data/*.db`. После перехода на PostgreSQL выполните `git pull`, настройте `DATABASE_URL`, `npm install` — при первом запуске создастся схема и демо-каталог (если таблица `products` пуста). Пользователей и заказы из SQLite нужно переносить вручную или заново зарегистрироваться.
|
|
|
|
## Репозиторий
|
|
|
|
```bash
|
|
git clone <URL_РЕПОЗИТОРИЯ> shop
|
|
cd shop
|
|
```
|