# Shop **v0.20.0** — интернет-магазин на **Node.js** и **PostgreSQL 17**. Два способа установки: [Docker Compose](#docker-compose-рекомендуется-для-теста) | [без Docker (Ubuntu)](#postgresql-17-без-docker) Подробности релиза: [CHANGELOG.md](CHANGELOG.md) · [docs/RELEASE-0.20.md](docs/RELEASE-0.20.md) **Сервер (установка, обновление, ошибки):** [wiki/Server-Operations.md](wiki/Server-Operations.md) · [wiki/Troubleshooting.md](wiki/Troubleshooting.md) ## Возможности - Каталог товаров с категориями и поиском - Корзина и оформление заказа - Регистрация, вход (пароль или passkey), сброс пароля по email - Личный кабинет: профиль, бронирования - Роли клиент / администратор, админ-панель - Согласие на 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 (создаётся автоматически). --- ## Быстрый развёртывание на 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 bash "$SHOP_ROOT/scripts/server-update.sh" ``` Не копируйте в shell шаблоны вроде `` — это подсказки в тексте, не команды. Подробно: **[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) | --- ## Запуск как служба (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)**. ```bash export SHOP_ROOT=/opt/shop cd "$SHOP_ROOT" bash scripts/git-sync.sh # если detached HEAD bash 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-postgresql-ubuntu.sh quick-deploy-ubuntu.sh fix-db-connection.sh diagnose-502.sh server-update.sh src/ ``` ## Релиз 0.20.0 ```bash git clone /opt/shop cd /opt/shop git checkout v0.20.0 ``` | Способ | Команда | |--------|---------| | Docker | `docker compose up -d --build` | | Без Docker | `bash scripts/setup-postgres-ubuntu.sh` → `systemctl start shop` | ## Репозиторий ```bash git clone /opt/shop cd /opt/shop ```