From 561fbd22e0e043acb07a7c68e2470b081729b93c Mon Sep 17 00:00:00 2001 From: shop Date: Sun, 17 May 2026 13:34:25 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20Server-Operations=20=E2=80=94=20=D1=83?= =?UTF-8?q?=D0=BD=D0=B8=D0=B2=D0=B5=D1=80=D1=81=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D0=B5=20=D1=80=D0=B0=D0=B7=D0=B2=D1=91=D1=80=D1=82=D1=8B?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B5=D0=B7=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=B2=D1=8F=D0=B7=D0=BA=D0=B8=20=D0=BA=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D0=BD=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- README.md | 68 +++++------ deploy/shop.service | 6 +- scripts/git-sync.sh | 2 +- scripts/install-shop-service.sh | 9 +- scripts/quick-deploy-ubuntu.sh | 16 ++- scripts/server-update.sh | 9 +- scripts/shop-root.sh | 13 +- wiki/Home.md | 32 ++--- wiki/Install-Native.md | 201 +++++++------------------------ wiki/Server-Operations.md | 179 ++++++++++++++++++++++++++++ wiki/Troubleshooting.md | 203 ++++++-------------------------- 11 files changed, 336 insertions(+), 402 deletions(-) create mode 100644 wiki/Server-Operations.md diff --git a/README.md b/README.md index c6ab528..0aed2fa 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Подробности релиза: [CHANGELOG.md](CHANGELOG.md) · [docs/RELEASE-0.20.md](docs/RELEASE-0.20.md) -**Wiki (установка):** https://git.evilfox.cc/test/shop10/wiki +**Сервер (установка, обновление, ошибки):** [wiki/Server-Operations.md](wiki/Server-Operations.md) · [wiki/Troubleshooting.md](wiki/Troubleshooting.md) ## Возможности @@ -100,7 +100,7 @@ apt install -y postgresql-17 postgresql-client-17 Пользователь и база `shop`: ```bash -cd /opt/shop/shop10 +cd "$SHOP_ROOT" bash scripts/setup-postgres-ubuntu.sh ``` @@ -112,34 +112,27 @@ bash scripts/setup-postgres-ubuntu.sh ## Быстрый развёртывание на Ubuntu -**Одной командой** (клон в `/opt/shop/shop10`, PostgreSQL через PGDG, systemd): +Подставьте **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 https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cd /opt/shop/shop10 -sudo bash scripts/quick-deploy-ubuntu.sh +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 /opt/shop/shop10/scripts/server-update.sh +bash "$SHOP_ROOT/scripts/server-update.sh" ``` -Не выполняйте `cd /opt/shop`, если репозиторий в `/opt/shop/shop10` — там нет `package.json`. +Не копируйте в shell шаблоны вроде `` — это подсказки в тексте, не команды. -Ручная установка: - -```bash -cd /opt/shop/shop10 -sudo bash scripts/install-postgresql-ubuntu.sh # PGDG, не apt install postgresql-17 напрямую -bash scripts/setup-postgres-ubuntu.sh -cp .env.example .env -# SESSION_SECRET, DATABASE_URL, SITE_URL -npm install --omit=dev -systemctl restart shop -``` +Подробно: **[wiki/Server-Operations.md](wiki/Server-Operations.md)** (PostgreSQL PGDG, git, systemd, порт 3000). Проверка: @@ -170,7 +163,7 @@ DATABASE_URL=postgresql://shop:shop@127.0.0.1:5432/shop ## Запуск как служба (systemd) ```bash -cd /opt/shop/shop10 +cd "$SHOP_ROOT" cp .env.example .env # при первой установке — SESSION_SECRET, DATABASE_URL sudo bash scripts/install-shop-service.sh journalctl -u shop -f @@ -178,7 +171,7 @@ journalctl -u shop -f Не делайте `chown -R www-data` на весь каталог репозитория (ломает `git pull`). -`EnvironmentFile=/opt/shop/shop10/.env` должен содержать `DATABASE_URL`. +`EnvironmentFile` в unit должен указывать на `$SHOP_ROOT/.env` с `DATABASE_URL`. --- @@ -197,28 +190,23 @@ journalctl -u shop -n 5 --no-pager ## Обновление на сервере (git pull) -Каталог клона — там, где лежат `package.json` и `scripts/` (часто `/opt/shop` или `/opt/shop/shop10`): +См. **[wiki/Server-Operations.md](wiki/Server-Operations.md)**. ```bash -cd /opt/shop/shop10 -bash scripts/git-sync.sh # если detached HEAD или ошибка git pull +export SHOP_ROOT=/opt/shop +cd "$SHOP_ROOT" +bash scripts/git-sync.sh # если detached HEAD bash scripts/server-update.sh ``` -Или одной командой (путь к скрипту в вашем клоне): - -```bash -bash /opt/shop/shop10/scripts/server-update.sh -``` - -Скрипт сам найдёт корень репозитория. В `deploy/shop.service` поле `WorkingDirectory` должно указывать на тот же каталог. +`WorkingDirectory` в `deploy/shop.service` = ваш `$SHOP_ROOT`. Скрипт: `git pull` → `npm install` → проверка PostgreSQL → `restart shop` → `curl /health` → `reload caddy`. Вручную: ```bash -cd /opt/shop/shop10 +cd "$SHOP_ROOT" git pull npm install --omit=dev systemctl restart shop @@ -270,13 +258,13 @@ shop.example.com { **Быстрое исправление (одной командой):** ```bash -bash /opt/shop/shop10/scripts/fix-db-connection.sh +bash "$SHOP_ROOT/scripts/fix-db-connection.sh" ``` **Вручную:** ```bash -cd /opt/shop/shop10 +cd "$SHOP_ROOT" sudo bash scripts/install-postgresql-ubuntu.sh systemctl enable --now postgresql pg_isready -h 127.0.0.1 -p 5432 @@ -293,7 +281,7 @@ curl -s http://127.0.0.1:3000/health ### HTTP 502 ```bash -bash /opt/shop/shop10/scripts/diagnose-502.sh +bash "$SHOP_ROOT/scripts/diagnose-502.sh" journalctl -u shop -n 50 --no-pager ``` @@ -347,8 +335,8 @@ src/ ## Релиз 0.20.0 ```bash -git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cd /opt/shop/shop10 +git clone /opt/shop +cd /opt/shop git checkout v0.20.0 ``` @@ -360,6 +348,6 @@ git checkout v0.20.0 ## Репозиторий ```bash -git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cd /opt/shop/shop10 +git clone /opt/shop +cd /opt/shop ``` diff --git a/deploy/shop.service b/deploy/shop.service index c4c562e..ec5a56e 100644 --- a/deploy/shop.service +++ b/deploy/shop.service @@ -7,9 +7,9 @@ Wants=network-online.target Type=simple User=www-data Group=www-data -WorkingDirectory=/opt/shop/shop10 -EnvironmentFile=/opt/shop/shop10/.env -ExecStartPre=+/opt/shop/shop10/scripts/wait-postgres.sh +WorkingDirectory=/opt/shop +EnvironmentFile=/opt/shop/.env +ExecStartPre=+/opt/shop/scripts/wait-postgres.sh ExecStart=/usr/bin/node src/server.js Restart=on-failure RestartSec=5 diff --git a/scripts/git-sync.sh b/scripts/git-sync.sh index 7c3b3f2..9a84f45 100644 --- a/scripts/git-sync.sh +++ b/scripts/git-sync.sh @@ -6,7 +6,7 @@ source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/shop-root.sh" if [ ! -d .git ]; then echo "Ошибка: в $SHOP_ROOT нет .git — нужен полный clone:" - echo " git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10" + echo " git clone /opt/shop" exit 1 fi diff --git a/scripts/install-shop-service.sh b/scripts/install-shop-service.sh index 0d949f5..63ed520 100644 --- a/scripts/install-shop-service.sh +++ b/scripts/install-shop-service.sh @@ -19,10 +19,11 @@ if [ ! -f "$SHOP_ROOT/package.json" ]; then exit 1 fi -# .env: shop10 или старый /opt/shop -if [ ! -f "$SHOP_ROOT/.env" ] && [ -f /opt/shop/.env ]; then - cp /opt/shop/.env "$SHOP_ROOT/.env" - echo "Скопирован .env из /opt/shop" +# .env в родительском каталоге (если переносили клон) +PARENT_ENV="$(dirname "$SHOP_ROOT")/.env" +if [ ! -f "$SHOP_ROOT/.env" ] && [ -f "$PARENT_ENV" ]; then + cp "$PARENT_ENV" "$SHOP_ROOT/.env" + echo "Скопирован .env из $(dirname "$SHOP_ROOT")" fi if [ ! -f "$SHOP_ROOT/.env" ]; then diff --git a/scripts/quick-deploy-ubuntu.sh b/scripts/quick-deploy-ubuntu.sh index ee3c59e..fe4e7e4 100644 --- a/scripts/quick-deploy-ubuntu.sh +++ b/scripts/quick-deploy-ubuntu.sh @@ -2,12 +2,12 @@ # Быстрое развёртывание / обновление на Ubuntu (без Docker) # sudo bash scripts/quick-deploy-ubuntu.sh # -# Каталог по умолчанию: /opt/shop/shop10 -# Переопределение: SHOP_INSTALL_DIR=/opt/shop/shop10 SHOP_GIT_URL=https://... +# Каталог: SHOP_INSTALL_DIR (по умолчанию /opt/shop) +# URL репозитория: SHOP_GIT_URL (обязателен при первом clone) set -euo pipefail -INSTALL_DIR="${SHOP_INSTALL_DIR:-/opt/shop/shop10}" -GIT_URL="${SHOP_GIT_URL:-https://git.evilfox.cc/test/shop10.git}" +INSTALL_DIR="${SHOP_INSTALL_DIR:-/opt/shop}" +GIT_URL="${SHOP_GIT_URL:-}" if [ "$(id -u)" -ne 0 ]; then echo "Запустите от root: sudo bash scripts/quick-deploy-ubuntu.sh" @@ -26,7 +26,13 @@ if ! command -v node >/dev/null; then fi if [ ! -f "$INSTALL_DIR/package.json" ]; then - echo "Клонирование репозитория..." + if [ -z "$GIT_URL" ]; then + echo "Задайте URL репозитория:" + echo " export SHOP_GIT_URL='https://ваш-forge/user/shop.git'" + echo " sudo SHOP_GIT_URL=\"\$SHOP_GIT_URL\" bash scripts/quick-deploy-ubuntu.sh" + exit 1 + fi + echo "Клонирование: $GIT_URL -> $INSTALL_DIR" mkdir -p "$(dirname "$INSTALL_DIR")" git clone "$GIT_URL" "$INSTALL_DIR" fi diff --git a/scripts/server-update.sh b/scripts/server-update.sh index 1853c2d..6a6dd99 100644 --- a/scripts/server-update.sh +++ b/scripts/server-update.sh @@ -1,6 +1,6 @@ #!/bin/bash # Обновление на сервере: git pull, npm, restart shop -# bash /opt/shop/shop10/scripts/server-update.sh +# bash "$SHOP_ROOT/scripts/server-update.sh" set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -11,9 +11,10 @@ echo "=== Shop update: $SHOP_ROOT ===" if [ ! -d .git ]; then echo "Ошибка: $SHOP_ROOT не git-репозиторий (нет .git)." - echo "Если код только в /opt/shop/shop10 без git — переустановите:" - echo " mv /opt/shop/shop10 /opt/shop/shop10.bak" - echo " git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10" + echo "Если нет .git — клонируйте заново:" + echo " export SHOP_GIT_URL=''" + echo " mv \"$SHOP_ROOT\" \"\${SHOP_ROOT}.bak\"" + echo " git clone \"\$SHOP_GIT_URL\" \"$SHOP_ROOT\"" exit 1 fi diff --git a/scripts/shop-root.sh b/scripts/shop-root.sh index 3c03840..c1eef42 100644 --- a/scripts/shop-root.sh +++ b/scripts/shop-root.sh @@ -6,16 +6,16 @@ _resolve_shop_root() { for d in \ "${SHOP_ROOT:-}" \ "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" \ - "/opt/shop/shop10" \ - "/opt/shop"; do + "/opt/shop" \ + "/opt/shop/app"; do [ -z "$d" ] && continue [ -f "${d}/package.json" ] && [ -d "${d}/.git" ] && SHOP_ROOT="$d" && return 0 done for d in \ "${SHOP_ROOT:-}" \ "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" \ - "/opt/shop/shop10" \ - "/opt/shop"; do + "/opt/shop" \ + "/opt/shop/app"; do [ -z "$d" ] && continue [ -f "${d}/package.json" ] && SHOP_ROOT="$d" && return 0 done @@ -24,8 +24,9 @@ _resolve_shop_root() { if ! _resolve_shop_root; then echo "Ошибка: не найден каталог Shop (нет package.json)." - echo " git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10" - echo " SHOP_ROOT=/opt/shop/shop10 bash scripts/server-update.sh" + echo " export SHOP_ROOT=/opt/shop # каталог с package.json" + echo " git clone \"\$SHOP_ROOT\"" + echo " SHOP_ROOT=\$SHOP_ROOT bash scripts/server-update.sh" exit 1 fi diff --git a/wiki/Home.md b/wiki/Home.md index 424caeb..5547bf0 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -1,4 +1,4 @@ -# Shop — документация v0.20.0 +# Shop — документация Интернет-магазин на **Node.js** и **PostgreSQL 17**. @@ -7,7 +7,8 @@ | Способ | Когда использовать | |--------|-------------------| | **[Установка через Docker](Install-Docker)** | Быстрый старт, тест, изолированное окружение | -| **[Установка без Docker](Install-Native)** | Production на Ubuntu, systemd, свой Caddy | +| **[Установка без Docker](Install-Native)** | Production на Ubuntu, systemd, Caddy | +| **[Сервер: установка и обновление](Server-Operations)** | Обновления, systemd, типичные ошибки | ## Требования @@ -17,31 +18,35 @@ ## Быстрый старт -### Docker (3 команды) +### Docker ```bash -git clone https://git.evilfox.cc/test/shop10.git && cd shop10 -git checkout v0.10.0 -cp .env.docker.example .env && docker compose up -d --build +git clone shop +cd shop +cp .env.docker.example .env +docker compose up -d --build ``` Сайт: http://localhost:3000 -### Без Docker +### Без Docker (сервер) ```bash -git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cd /opt/shop/shop10 +export SHOP_ROOT=/opt/shop +export GIT_REPO_URL='' + +git clone "$GIT_REPO_URL" "$SHOP_ROOT" +cd "$SHOP_ROOT" sudo bash scripts/quick-deploy-ubuntu.sh ``` -Обновление на работающем сервере: +Обновление: ```bash -bash /opt/shop/shop10/scripts/server-update.sh +bash "$SHOP_ROOT/scripts/server-update.sh" ``` -## Проверка работы +## Проверка ```bash curl -s http://127.0.0.1:3000/health @@ -51,6 +56,5 @@ curl -s http://127.0.0.1:3000/health ## Ссылки -- [Репозиторий](https://git.evilfox.cc/test/shop10) -- [Releases](https://git.evilfox.cc/test/shop10/releases) - [Решение проблем](Troubleshooting) +- [Сервер: установка и обновление](Server-Operations) diff --git a/wiki/Install-Native.md b/wiki/Install-Native.md index 542ff25..fc65c8d 100644 --- a/wiki/Install-Native.md +++ b/wiki/Install-Native.md @@ -1,225 +1,106 @@ # Установка без Docker (Ubuntu) -Production-развёртывание на **Ubuntu 22.04 / 24.04**: Node.js 20, PostgreSQL 17, systemd, опционально Caddy. +Production: Node.js 20, PostgreSQL 17, systemd, опционально Caddy. + +**Полное руководство по ошибкам и обновлениям:** [Server-Operations](Server-Operations). + +Задайте каталог клона: + +```bash +export SHOP_ROOT=/opt/shop +``` + +--- ## 1. Требования -- Сервер Ubuntu 22.04 или 24.04 (root или sudo) -- Минимум 1 GB RAM, 10 GB диск -- Открыты порты **22**, **80**, **443** (если используете Caddy) -- Порт **3000** наружу не открывать — только localhost +- Ubuntu 22.04 или 24.04 +- Порты 22, 80, 443 (для Caddy) +- Порт 3000 только localhost -## 2. Установка системных пакетов +## 2. Системные пакеты -```bash -apt update -apt install -y git curl ca-certificates -``` - -### Node.js 20 LTS +### Node.js 20 ```bash curl -fsSL https://deb.nodesource.com/setup_20.x | bash - -apt install -y nodejs -node -v # v20.x +apt install -y nodejs git curl ``` ### PostgreSQL 17 -Не используйте `apt install postgresql-17` без PGDG — пакет не найдётся. Скрипт подключает PGDG автоматически: +Не используйте `apt install postgresql-17` без PGDG: ```bash -sudo bash /opt/shop/shop10/scripts/install-postgresql-ubuntu.sh +sudo bash "$SHOP_ROOT/scripts/install-postgresql-ubuntu.sh" ``` -## 3. Клонирование проекта +## 3. Клонирование ```bash -git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cd /opt/shop/shop10/shop10 -git checkout v0.20.0 +export GIT_REPO_URL='' +git clone "$GIT_REPO_URL" "$SHOP_ROOT" +cd "$SHOP_ROOT" ``` -Или быстрая установка всего стека: `sudo bash scripts/quick-deploy-ubuntu.sh` +Или: `sudo SHOP_GIT_URL="$GIT_REPO_URL" bash scripts/quick-deploy-ubuntu.sh` -## 4. База данных PostgreSQL +## 4. База данных ```bash -cd /opt/shop/shop10/shop10 +cd "$SHOP_ROOT" bash scripts/setup-postgres-ubuntu.sh ``` -Скрипт: -- запускает PostgreSQL; -- создаёт пользователя и БД `shop` (по умолчанию пароль `shop` — **смените в production**); -- выводит строку `DATABASE_URL`. - -Проверка: - -```bash -psql "postgresql://shop:shop@127.0.0.1:5432/shop" -c "SELECT 1" -``` - -## 5. Файл окружения `.env` +## 5. `.env` ```bash cp .env.example .env nano .env ``` -Обязательные параметры: +`SESSION_SECRET`, `DATABASE_URL`, `SITE_URL` (ваш публичный URL без привязки к конкретному домену в коде). -```env -PORT=3000 -HOST=127.0.0.1 -NODE_ENV=production -TRUST_PROXY=1 -SESSION_SECRET=сгенерируйте_длинную_строку -DATABASE_URL=postgresql://shop:ВАШ_ПАРОЛЬ@127.0.0.1:5432/shop -``` - -Секрет сессии: +## 6. Зависимости ```bash -openssl rand -hex 32 -``` - -`HOST=127.0.0.1` — приложение доступно только локально; снаружи — через Caddy. - -## 6. Установка зависимостей Node.js - -```bash -cd /opt/shop/shop10 npm install --omit=dev ``` -При первом запуске приложение создаст таблицы и демо-товары (если каталог пуст). - -## 7. Служба systemd +## 7. systemd ```bash -cp /opt/shop/shop10/deploy/shop.service /etc/systemd/system/shop.service -systemctl daemon-reload -systemctl enable shop -systemctl start shop -systemctl status shop +sudo bash scripts/install-shop-service.sh ``` -Unit ждёт PostgreSQL (`ExecStartPre` + `pg_isready`) и запускает Node от пользователя `www-data`. +`WorkingDirectory` в unit = `$SHOP_ROOT`. Не делайте `chown -R www-data` на весь репозиторий. -**Важно:** не выполняйте `chown -R www-data /opt/shop` — это ломает `git pull`. Права на запись нужны только для каталога `data/` (если используется); с PostgreSQL каталог `data/` не обязателен. +## 8. Caddy -Логи: +После `curl http://127.0.0.1:3000/health` → OK: ```bash -journalctl -u shop -f -``` - -## 8. Проверка backend - -```bash -curl -s http://127.0.0.1:3000/health -ss -tlnp | grep 3000 -``` - -В логах должно быть: `Магазин: http://127.0.0.1:3000 (PostgreSQL)` - -## 9. Caddy — HTTPS и reverse proxy - -Установка Caddy: - -```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 -``` - -Конфигурация: - -```bash -cp /opt/shop/shop10/caddy/Caddyfile.example /etc/caddy/Caddyfile -nano /etc/caddy/Caddyfile -``` - -Пример (замените домен и email): - -```caddyfile -{ - email admin@example.com -} - -shop.example.com { - encode gzip zstd - reverse_proxy 127.0.0.1:3000 -} -``` - -```bash -caddy validate --config /etc/caddy/Caddyfile -systemctl enable caddy +cp "$SHOP_ROOT/caddy/Caddyfile.example" /etc/caddy/Caddyfile +# укажите ваш домен в Caddyfile systemctl reload caddy ``` -Файрвол: +## 9. Обновление ```bash -ufw allow 22/tcp -ufw allow 80/tcp -ufw allow 443/tcp -ufw enable +bash "$SHOP_ROOT/scripts/server-update.sh" ``` -Зависимость Caddy от shop (опционально): - -```bash -mkdir -p /etc/systemd/system/caddy.service.d -cp /opt/shop/deploy/caddy-after-shop.conf /etc/systemd/system/caddy.service.d/shop.conf -systemctl daemon-reload -``` - -## 10. Обновление - -```bash -cd /opt/shop/shop10/shop10 -git config --global --add safe.directory "$(pwd)" -bash scripts/server-update.sh -``` - -Если клон в `/opt/shop` без подкаталога — используйте `/opt/shop`. Скрипт ищет `package.json` автоматически; можно запустить так: - -```bash -bash /opt/shop/shop10/scripts/server-update.sh -``` - -Или вручную: - -```bash -git pull -npm install --omit=dev -systemctl restart shop -curl -s http://127.0.0.1:3000/health -systemctl reload caddy -``` - -## 11. Архитектура +## 10. Архитектура ``` -Интернет → Caddy :443 → 127.0.0.1:3000 (Node.js shop) +Интернет → Caddy :443 → 127.0.0.1:3000 (Node.js) ↓ PostgreSQL 127.0.0.1:5432 ``` -## 12. Резервное копирование БД +## 11. Резервное копирование ```bash sudo -u postgres pg_dump shop > shop_backup_$(date +%F).sql ``` - -Восстановление: - -```bash -sudo -u postgres psql shop < shop_backup_2026-05-17.sql -``` diff --git a/wiki/Server-Operations.md b/wiki/Server-Operations.md new file mode 100644 index 0000000..4939462 --- /dev/null +++ b/wiki/Server-Operations.md @@ -0,0 +1,179 @@ +# Сервер: установка и обновление + +Инструкция **без привязки к конкретному домену или хостингу**. Подставьте свои значения: + +| Переменная | Что это | Пример | +|------------|---------|--------| +| `SHOP_ROOT` | Каталог клона, где лежат `package.json` и `scripts/` | `/opt/shop` | +| `GIT_REPO_URL` | URL вашего git-репозитория | `https://forge.example.com/user/shop.git` | +| `SITE_URL` | Публичный URL магазина (для писем и passkey) | `https://shop.example.com` | + +Проверка каталога: + +```bash +export SHOP_ROOT=/opt/shop +test -f "$SHOP_ROOT/package.json" && echo OK || echo "Неверный SHOP_ROOT" +``` + +--- + +## Первая установка (Ubuntu, без Docker) + +```bash +export SHOP_ROOT=/opt/shop +export GIT_REPO_URL='https://ВАШ-FORGE/путь/к/shop.git' + +apt update && apt install -y git curl +git clone "$GIT_REPO_URL" "$SHOP_ROOT" +cd "$SHOP_ROOT" + +sudo SHOP_INSTALL_DIR="$SHOP_ROOT" SHOP_GIT_URL="$GIT_REPO_URL" \ + bash scripts/quick-deploy-ubuntu.sh +``` + +Скрипт: Node.js (если нет), PostgreSQL (PGDG), `.env`, `npm install`, служба **shop** (systemd). + +--- + +## Обновление кода (сайт уже работает) + +```bash +cd "$SHOP_ROOT" +bash scripts/git-sync.sh +bash scripts/server-update.sh +``` + +Или одной строкой (путь к скриптам в вашем клоне): + +```bash +bash "$SHOP_ROOT/scripts/server-update.sh" +``` + +--- + +## Скрипты в `scripts/` + +| Скрипт | Назначение | +|--------|------------| +| `quick-deploy-ubuntu.sh` | Первая установка / полный цикл | +| `server-update.sh` | `git pull`, `npm install`, перезапуск shop | +| `git-sync.sh` | Исправить detached HEAD, синхронизация с `main` | +| `install-postgresql-ubuntu.sh` | PostgreSQL 17 через PGDG | +| `setup-postgres-ubuntu.sh` | Пользователь и БД `shop` | +| `install-shop-service.sh` | Установка systemd unit | +| `free-port-3000.sh` | Освободить порт (старый `npm start`) | +| `fix-db-connection.sh` | ECONNREFUSED :5432 | +| `diagnose-502.sh` | HTTP 502, Caddy | +| `diagnose-shop-service.sh` | Падение shop.service | + +Все скрипты сами ищут `SHOP_ROOT` (каталог, откуда вызван `scripts/`, или переменная окружения). + +--- + +## Частые ошибки + +### `Unable to locate package postgresql-17` + +В стандартном Ubuntu нет пакета 17. Не копируйте `apt install postgresql-17` из старых заметок. + +```bash +sudo bash "$SHOP_ROOT/scripts/install-postgresql-ubuntu.sh" +bash "$SHOP_ROOT/scripts/setup-postgres-ubuntu.sh" +``` + +### `URL_РЕПОЗИТОРИЯ: No such file` или placeholder в команде + +В документации иногда указан **шаблон**, а не команда. Клонируйте так: + +```bash +git clone 'https://ВАШ-FORGE/shop.git' "$SHOP_ROOT" +``` + +### `package.json` ENOENT в `/opt/shop` + +Вы в **родительской** папке, а клон в подкаталоге (или наоборот). + +```bash +find /opt -name package.json 2>/dev/null +export SHOP_ROOT=/путь/где/найден +cd "$SHOP_ROOT" +``` + +### `You are not currently on a branch` + +После `git checkout v0.x.x` репозиторий в detached HEAD. + +```bash +cd "$SHOP_ROOT" +bash scripts/git-sync.sh +``` + +### `scripts/...: No such file or directory` + +Запуск не из клона. Используйте полный путь: + +```bash +bash "$SHOP_ROOT/scripts/server-update.sh" +``` + +### `Служба shop не установлена` / `Unit shop.service could not be found` + +```bash +cd "$SHOP_ROOT" +sudo bash scripts/install-shop-service.sh +``` + +В `/etc/systemd/system/shop.service` поля `WorkingDirectory` и `EnvironmentFile` должны указывать на **`$SHOP_ROOT`**. + +### `shop.service: status=1/FAILURE`, `activating (auto-restart)` + +1. **Порт 3000 занят** (старый ручной Node) — health отвечает, systemd падает: + +```bash +sudo bash "$SHOP_ROOT/scripts/free-port-3000.sh" +sudo systemctl restart shop +systemctl status shop +``` + +2. **PostgreSQL** — смотрите лог: + +```bash +journalctl -u shop -n 40 --no-pager +bash "$SHOP_ROOT/scripts/diagnose-shop-service.sh" +``` + +3. **`.env` не в `SHOP_ROOT`** — скопируйте с прежнего места: + +```bash +cp /старый/путь/.env "$SHOP_ROOT/.env" +sudo bash "$SHOP_ROOT/scripts/install-shop-service.sh" +``` + +### Изменения в git не видны на сайте + +Обновление делали не в том каталоге или служба смотрит на другой путь: + +```bash +cd "$SHOP_ROOT" && git log -1 --oneline +grep WorkingDirectory /etc/systemd/system/shop.service +bash scripts/server-update.sh +``` + +--- + +## Проверка + +```bash +systemctl status shop +curl -s http://127.0.0.1:3000/health +``` + +Ожидается: `{"ok":true,"service":"shop","database":"postgresql"}` и **`Active: active (running)`**. + +--- + +## Caddy / HTTPS + +Пока `curl http://127.0.0.1:3000/health` не OK, reverse proxy будет отдавать **502**. Сначала backend, потом Caddy. + +См. также: [Решение проблем](Troubleshooting), [Установка без Docker](Install-Native). diff --git a/wiki/Troubleshooting.md b/wiki/Troubleshooting.md index 62a6633..33f9279 100644 --- a/wiki/Troubleshooting.md +++ b/wiki/Troubleshooting.md @@ -1,190 +1,56 @@ # Решение проблем -## Диагностика одной командой +Полное руководство по развёртыванию: **[Сервер: установка и обновление](Server-Operations)**. + +Перед любыми командами задайте каталог клона: ```bash -bash /opt/shop/shop10/scripts/diagnose-502.sh +export SHOP_ROOT=/opt/shop # замените на свой путь (где есть package.json) +cd "$SHOP_ROOT" ``` -(замените путь на каталог вашего клона — где есть `package.json`) +--- -## Ошибки при «быстром развёртывании» - -| Ошибка | Причина | Решение | -|--------|---------|---------| -| `Unable to locate package postgresql-17` | В Ubuntu нет PG 17 без PGDG | `sudo bash /opt/shop/shop10/scripts/install-postgresql-ubuntu.sh` | -| `URL_РЕПОЗИТОРИЯ: No such file` | Скопирован placeholder из README | Используйте реальный URL: `git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10` | -| `package.json` в `/opt/shop` | Неверный каталог | Репозиторий в `/opt/shop/shop10` | -| Изменения не применились | `git pull` не в том каталоге | `bash /opt/shop/shop10/scripts/server-update.sh` | - -Полное развёртывание / обновление: +## Диагностика ```bash -cd /opt/shop/shop10 && git pull -sudo bash scripts/quick-deploy-ubuntu.sh -``` - -Только обновление кода (сайт уже работает): - -```bash -bash /opt/shop/shop10/scripts/server-update.sh -``` - -## git: You are not currently on a branch / not a git repository - -Клон на теге (detached HEAD) или обновление из `/opt/shop` вместо `/opt/shop/shop10`: - -```bash -cd /opt/shop/shop10 -git status -bash scripts/git-sync.sh -bash scripts/server-update.sh -``` - -Если `fatal: not a git repository` в `/opt/shop/shop10`: - -```bash -ls -la /opt/shop/shop10/.git -# нет .git — заново: -mv /opt/shop/shop10 /opt/shop/shop10.bak.$(date +%s) -git clone https://git.evilfox.cc/test/shop10.git /opt/shop/shop10 -cp /opt/shop/shop10.bak.*/.env /opt/shop/shop10/.env 2>/dev/null || cp /opt/shop/shop10/.env.example /opt/shop/shop10/.env -bash /opt/shop/shop10/scripts/server-update.sh -``` - -## shop.service: exit-code / activating (auto-restart) - -**Health ответил OK, но systemd падает** — часто порт 3000 занят старым `npm start`: - -```bash -cd /opt/shop/shop10 -git pull -sudo bash scripts/free-port-3000.sh -sudo systemctl restart shop -systemctl status shop -``` - -Лог: - -```bash -journalctl -u shop -n 30 --no-pager -# EADDRINUSE → free-port-3000.sh -# MODULE_NOT_FOUND → npm install --omit=dev -``` - -## Job for shop.service failed (control process exited) - -Чаще всего не запущен PostgreSQL или не прошёл `ExecStartPre`: - -```bash -cd /opt/shop/shop10 -git pull -sudo bash scripts/install-postgresql-ubuntu.sh -bash scripts/setup-postgres-ubuntu.sh -sudo bash scripts/install-shop-service.sh -``` - -Диагностика: - -```bash -bash /opt/shop/shop10/scripts/diagnose-shop-service.sh +bash "$SHOP_ROOT/scripts/diagnose-502.sh" +bash "$SHOP_ROOT/scripts/diagnose-shop-service.sh" journalctl -u shop -n 50 --no-pager ``` -Скопировать старый `.env`: +--- -```bash -cp /opt/shop/.env /opt/shop/shop10/.env -sudo bash /opt/shop/shop10/scripts/install-shop-service.sh -``` +## Краткая таблица ошибок -## Служба shop не установлена +| Симптом | Что делать | +|---------|------------| +| `postgresql-17` not found | `sudo bash scripts/install-postgresql-ubuntu.sh` | +| Placeholder / `URL_РЕПОЗИТОРИЯ` | `git clone <ваш-url> "$SHOP_ROOT"` — не копировать шаблоны как команды | +| Нет `package.json` | `find /opt -name package.json`; `cd` в найденный каталог | +| detached HEAD | `bash scripts/git-sync.sh` | +| Нет `scripts/...` | `bash "$SHOP_ROOT/scripts/server-update.sh"` | +| Unit shop not found | `sudo bash scripts/install-shop-service.sh` | +| shop exit-code / auto-restart | `sudo bash scripts/free-port-3000.sh`; `systemctl restart shop` | +| 502 в браузере | `curl http://127.0.0.1:3000/health` — сначала backend | +| ECONNREFUSED :5432 | `bash scripts/fix-db-connection.sh` | -Код обновился, но systemd unit не настроен: - -```bash -cd /opt/shop/shop10 -sudo bash scripts/install-shop-service.sh -``` - -Проверка: - -```bash -systemctl status shop -curl -s http://127.0.0.1:3000/health -``` - -## scripts/server-update.sh: No such file or directory - -Вы не в каталоге репозитория или клон в подпапке (например `/opt/shop/shop10`): - -```bash -ls /opt/shop/shop10/package.json -bash /opt/shop/shop10/scripts/server-update.sh -``` - -В `deploy/shop.service` укажите тот же путь в `WorkingDirectory` и `EnvironmentFile`. +Подробности — в [Server-Operations](Server-Operations). --- ## HTTP 502 (Caddy / браузер) -**SSL работает, страница 502** — Caddy жив, backend (Node) не отвечает. - ```bash curl -s http://127.0.0.1:3000/health systemctl status shop -journalctl -u shop -n 30 --no-pager ``` Пока `/health` не OK — Caddy будет отдавать 502. --- -## ECONNREFUSED 127.0.0.1:5432 - -PostgreSQL не запущен или не установлен. - -```bash -bash /opt/shop/shop10/scripts/fix-db-connection.sh -``` - -Или вручную: - -```bash -systemctl start postgresql -pg_isready -h 127.0.0.1 -p 5432 -bash scripts/setup-postgres-ubuntu.sh -``` - -Проверьте `DATABASE_URL` в `/opt/shop/shop10/.env`. - ---- - -## Служба shop сразу останавливается - -В логе только «База уже содержит товары» без строки `Магазин: http://...`: - -```bash -bash /opt/shop/shop10/scripts/server-update.sh -systemctl restart shop -``` - ---- - -## dubious ownership (git pull) - -Не делайте `chown -R www-data /opt/shop`. - -```bash -chown -R root:root /opt/shop -git config --global --add safe.directory /opt/shop -git pull -``` - ---- - -## Docker: контейнер app unhealthy +## Docker ```bash docker compose logs app @@ -192,16 +58,23 @@ docker compose logs postgres docker compose up -d --build ``` ---- - -## Docker: нет связи с БД - -Проверьте, что `DATABASE_URL` в compose указывает на хост `postgres`, а не `127.0.0.1` (внутри контейнера app). +`DATABASE_URL` в compose должен указывать на сервис `postgres`, не на `127.0.0.1` внутри контейнера app. --- -## Полезные ссылки +## git pull / dubious ownership +Не делайте `chown -R www-data` на весь каталог репозитория. + +```bash +git config --global --add safe.directory "$SHOP_ROOT" +cd "$SHOP_ROOT" && git pull +``` + +--- + +## Ссылки + +- [Сервер: установка и обновление](Server-Operations) - [Установка Docker](Install-Docker) - [Установка без Docker](Install-Native) -- [Репозиторий](https://git.evilfox.cc/test/shop10)