initial: server + shared
This commit is contained in:
Executable
+196
@@ -0,0 +1,196 @@
|
||||
# Первичная настройка LXC для Craftshop
|
||||
|
||||
Выполнять от **root** на свежем Debian/Ubuntu LXC.
|
||||
|
||||
---
|
||||
|
||||
## 1. Базовые пакеты и Node.js
|
||||
|
||||
```bash
|
||||
apt-get update -y
|
||||
apt-get install -y ca-certificates curl gnupg curl git
|
||||
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
||||
apt-get install -y nodejs
|
||||
|
||||
node --version # ожидается >= 22
|
||||
npm --version
|
||||
```
|
||||
|
||||
## 2. Каталоги
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/craftshop/server/uploads /opt/craftshop/www
|
||||
```
|
||||
|
||||
## 3. systemd unit
|
||||
|
||||
```bash
|
||||
cat >/etc/systemd/system/craftshop-api.service <<'UNIT'
|
||||
[Unit]
|
||||
Description=Craftshop API (Fastify)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
Group=root
|
||||
WorkingDirectory=/opt/craftshop/server
|
||||
EnvironmentFile=-/opt/craftshop/server/.env
|
||||
ExecStart=/usr/bin/node src/index.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable craftshop-api.service
|
||||
```
|
||||
|
||||
## 4. Nginx
|
||||
|
||||
```bash
|
||||
apt-get install -y nginx
|
||||
|
||||
cat >/etc/nginx/sites-available/craftshop <<'NGX'
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
|
||||
root /opt/craftshop/www;
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
client_max_body_size 250m;
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /uploads/ {
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location /uploads-resized/ {
|
||||
client_max_body_size 250m;
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
NGX
|
||||
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
ln -sf /etc/nginx/sites-available/craftshop /etc/nginx/sites-enabled/craftshop
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
|
||||
## 5. NetBird VPN
|
||||
|
||||
```bash
|
||||
curl -fsSL https://pkgs.netbird.io/install.sh | sh
|
||||
netbird up
|
||||
```
|
||||
|
||||
После `netbird up` появится интерфейс `wt0` с IP из твоей NetBird-сети. Запомни его — он понадобится для NPM.
|
||||
|
||||
## 6. Переменные окружения
|
||||
|
||||
Сгенерируй JWT_SECRET:
|
||||
|
||||
```bash
|
||||
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
|
||||
```
|
||||
|
||||
Создай `.env`:
|
||||
|
||||
```bash
|
||||
cat >/opt/craftshop/server/.env <<'ENV'
|
||||
DATABASE_URL="file:./prod.db"
|
||||
PORT=3333
|
||||
JWT_SECRET=<вставь сгенерированную строку>
|
||||
ADMIN_EMAIL=<твой email>
|
||||
CORS_ORIGIN=https://<твой-домен>
|
||||
IS_DEFAULT_CODE_ENABLED=false
|
||||
ENV
|
||||
chmod 600 /opt/craftshop/server/.env
|
||||
```
|
||||
|
||||
## 7. Первый деплой
|
||||
|
||||
На машине разработчика (после заполнения `scripts/deploy.env`):
|
||||
|
||||
```bash
|
||||
./scripts/deploy-auto.sh --force
|
||||
```
|
||||
|
||||
После завершения — на сервере:
|
||||
|
||||
```bash
|
||||
systemctl start craftshop-api
|
||||
systemctl status craftshop-api
|
||||
curl http://127.0.0.1:3333/health
|
||||
```
|
||||
|
||||
## 8. VPS с Nginx Proxy Manager
|
||||
|
||||
На VPS (где установлен NPM):
|
||||
|
||||
1. DNS-запись A: `craftshop.твой-домен` → IP VPS
|
||||
2. В NPM → Proxy Hosts → Add:
|
||||
- Domain: `craftshop.твой-домен`
|
||||
- Forward Hostname: `<NetBird-IP-LXC>` (IP wt0 на LXC)
|
||||
- Forward Port: `80`
|
||||
- SSL: Let's Encrypt
|
||||
3. Сохрани
|
||||
|
||||
Проверка:
|
||||
|
||||
```bash
|
||||
curl https://craftshop.твой-домен/api/health
|
||||
```
|
||||
|
||||
## 9. Бэкапы БД (systemd timer)
|
||||
|
||||
Установить таймер для автоматического бэкапа каждые 6 часов:
|
||||
|
||||
```bash
|
||||
# Установить sqlite3 для безопасного копирования
|
||||
apt-get install -y sqlite3
|
||||
|
||||
# Скопировать unit-файлы
|
||||
cp /opt/craftshop/scripts/craftshop-backup.service /etc/systemd/system/
|
||||
cp /opt/craftshop/scripts/craftshop-backup.timer /etc/systemd/system/
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now craftshop-backup.timer
|
||||
|
||||
# Проверить статус
|
||||
systemctl list-timers craftshop-backup.timer
|
||||
|
||||
# Ручной запуск для проверки
|
||||
systemctl start craftshop-backup.service
|
||||
ls /opt/craftshop/server/backups/
|
||||
```
|
||||
|
||||
Бэкапы хранятся 30 дней (настраивается в `scripts/backup-db.sh`).
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
# Backup SQLite database — копирует .db файл с timestamp в директорию бэкапов.
|
||||
# Вызывается из systemd timer или cron.
|
||||
#
|
||||
# Использование: ./scripts/backup-db.sh [path-to-db] [backup-dir] [retention-days]
|
||||
# По умолчанию: db=server/prisma/prod.db, backup=server/backups, retention=30
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
DB_PATH="${1:-$ROOT/server/prisma/prod.db}"
|
||||
BACKUP_DIR="${2:-$ROOT/server/backups}"
|
||||
RETENTION_DAYS="${3:-30}"
|
||||
|
||||
if [[ ! -f "$DB_PATH" ]]; then
|
||||
echo "[$(date -Iseconds)] DB not found: $DB_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||
BACKUP_FILE="$BACKUP_DIR/craftshop_${TIMESTAMP}.db"
|
||||
|
||||
# SQLite-safe copy: use .backup to avoid copying a file mid-write
|
||||
if command -v sqlite3 &>/dev/null; then
|
||||
sqlite3 "$DB_PATH" ".backup '$BACKUP_FILE'"
|
||||
else
|
||||
# Fallback: plain copy (risk of inconsistent state if DB is being written)
|
||||
cp "$DB_PATH" "$BACKUP_FILE"
|
||||
fi
|
||||
|
||||
# Compress
|
||||
gzip -f "$BACKUP_FILE"
|
||||
|
||||
# Remove old backups
|
||||
find "$BACKUP_DIR" -name 'craftshop_*.db.gz' -mtime +"$RETENTION_DAYS" -delete
|
||||
|
||||
echo "[$(date -Iseconds)] Backup created: ${BACKUP_FILE}.gz"
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
[Unit]
|
||||
Description=Craftshop SQLite Database Backup
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/opt/craftshop/scripts/backup-db.sh /opt/craftshop/server/prisma/prod.db /opt/craftshop/server/backups 30
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Craftshop Database Backup Timer
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 00/6:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
# Nginx для доступа к админке через Netbird
|
||||
# Размещается на сервере в /etc/nginx/sites-available/craftshop-netbird
|
||||
# с симлинком в /etc/nginx/sites-enabled/
|
||||
|
||||
server {
|
||||
listen 100.109.3.6:80;
|
||||
server_name 100.109.3.6;
|
||||
|
||||
root /opt/craftshop/www;
|
||||
index index.html;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /uploads/ {
|
||||
proxy_pass http://127.0.0.1:3333;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user