Files

386 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Shop
**v1.2.0** — интернет-магазин на **Node.js** и **PostgreSQL 17**.
Два способа установки: [Docker Compose](#docker-compose-рекомендуется-для-теста) | [без Docker (Ubuntu)](#postgresql-17-без-docker)
Подробности релиза: [CHANGELOG.md](CHANGELOG.md) · [docs/RELEASE-1.0.1.md](docs/RELEASE-1.0.1.md) · [1.0.0](docs/RELEASE-1.0.md)
**Сервер (установка, обновление, ошибки):** [wiki/Server-Operations.md](wiki/Server-Operations.md) · [wiki/Troubleshooting.md](wiki/Troubleshooting.md)
## Возможности
- Каталог товаров с категориями и поиском
- Корзина и оформление заказа
- Регистрация, вход (пароль или passkey), сброс пароля по email
- Личный кабинет: профиль, бронирования
- Роли: клиент (`customer`) и **один** администратор (`admin`) — аккаунт из `ADMIN_EMAIL` в `.env`
- Согласие на cookies
- Подписка «сообщить о поступлении», если товара нет в наличии
- Лояльность (баллы), промокоды со скидкой и таймером до конца акции
## Требования
- 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 "$SHOP_ROOT"
bash scripts/setup-postgres-ubuntu.sh
```
Схема: `postgres/init/01_schema.sql` (применяется при старте приложения).
Сессии — таблица `session` в PostgreSQL (создаётся автоматически).
---
## Интерактивный установщик
Задаёт вопросы: **Docker или Ubuntu**, данные **администратора**, **PostgreSQL**, URL сайта, опционально SMTP.
```bash
cd /path/to/shop
bash scripts/install.sh
```
Нативная установка на сервере — от root: `sudo bash scripts/install.sh`.
---
## Быстрый развёртывание на Ubuntu
Подставьте **URL своего репозитория** и каталог клона `SHOP_ROOT` (часто `/opt/shop`):
```bash
export SHOP_ROOT=/opt/shop
export SHOP_GIT_URL='https://ваш-forge/пользователь/shop.git'
apt update && apt install -y git curl
git clone "$SHOP_GIT_URL" "$SHOP_ROOT"
cd "$SHOP_ROOT"
sudo SHOP_INSTALL_DIR="$SHOP_ROOT" SHOP_GIT_URL="$SHOP_GIT_URL" bash scripts/quick-deploy-ubuntu.sh
```
**Обновление** (сайт уже работает) — **лучше так** (из любого каталога):
```bash
export SHOP_ROOT=/opt/shop/shop10
bash "$SHOP_ROOT/scripts/server-update.sh"
```
`SHOP_ROOT` — путь к клону с `package.json` (у вас может быть `/opt/shop` вместо `/opt/shop/shop10`).
Не копируйте в shell шаблоны вроде `<URL_РЕПОЗИТОРИЯ>` — это подсказки в тексте, не команды.
Подробно: **[wiki/Server-Operations.md](wiki/Server-Operations.md)** (PostgreSQL PGDG, git, systemd, порт 3000).
Проверка:
```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) |
| `ADMIN_EMAIL` | Email **единственного** администратора (создаётся/обновляется при старте) |
| `ADMIN_PASSWORD` | Пароль администратора (только при первом создании аккаунта) |
| `ADMIN_NAME` | Имя администратора |
### Роли и администратор
- Через **регистрацию** на сайте все пользователи получают роль **клиент** (`customer`).
- **Один** зарегистрированный пользователь — **администратор**: аккаунт с email из `ADMIN_EMAIL` (по умолчанию `admin@site.com`). При старте приложения он создаётся, если ещё нет, или ему назначается роль `admin`.
- Админ-панель: `/admin` (кнопка в шапке и в личном кабинете — только у администратора).
- Сменить администратора: укажите другой email в `ADMIN_EMAIL` и перезапустите shop (прежние admin-аккаунты станут клиентами).
---
## Запуск как служба (systemd)
```bash
cd "$SHOP_ROOT"
cp .env.example .env # при первой установке — SESSION_SECRET, DATABASE_URL
sudo bash scripts/install-shop-service.sh
journalctl -u shop -f
```
Не делайте `chown -R www-data` на весь каталог репозитория (ломает `git pull`).
`EnvironmentFile` в unit должен указывать на `$SHOP_ROOT/.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)
См. **[wiki/Server-Operations.md](wiki/Server-Operations.md)**.
**Рекомендуемый способ** (надёжнее, чем вручную `cd` и `git pull`):
```bash
export SHOP_ROOT=/opt/shop/shop10
bash "$SHOP_ROOT/scripts/server-update.sh"
```
`WorkingDirectory` в `deploy/shop.service` должен совпадать с `$SHOP_ROOT`.
Скрипт: `git pull``npm install` → проверка PostgreSQL → `restart shop``curl /health``reload caddy`.
Вручную:
```bash
cd "$SHOP_ROOT"
git pull
npm install --omit=dev
systemctl restart shop
curl -s http://127.0.0.1:3000/health
systemctl reload caddy
```
---
## 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
bash "$SHOP_ROOT/scripts/fix-db-connection.sh"
```
**Вручную:**
```bash
cd "$SHOP_ROOT"
sudo bash scripts/install-postgresql-ubuntu.sh
systemctl enable --now postgresql
pg_isready -h 127.0.0.1 -p 5432
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 "$SHOP_ROOT/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
install.sh
install-postgresql-ubuntu.sh
quick-deploy-ubuntu.sh
fix-db-connection.sh
diagnose-502.sh
server-update.sh
src/
```
## Релиз 1.0.1
```bash
git clone <URL-вашего-репозитория> /opt/shop
cd /opt/shop
git checkout v1.0.1
```
| Способ | Команда |
|--------|---------|
| Интерактивно | `bash scripts/install.sh` |
| Docker | `docker compose up -d --build` |
| Без Docker | `bash scripts/setup-postgres-ubuntu.sh``systemctl start shop` |
Обновление с **0.20**: `bash "$SHOP_ROOT/scripts/server-update.sh"` или **Админ → Обновление**.
## Репозиторий
```bash
git clone <URL-вашего-репозитория> /opt/shop
cd /opt/shop
```