Files
shop-server/scripts/server-bootstrap.sh
T
@kirill.komarov e67d8bdc0a deploy
2026-05-10 16:49:55 +05:00

203 lines
6.9 KiB
Bash

#!/usr/bin/env bash
#
# Этап A: первичная настройка свежего Debian/Ubuntu (LXC/VM) под Craftshop.
# Запускать НА СЕРВЕРЕ от root один раз:
# curl -fsSL … | bash или scp + bash server-bootstrap.sh
#
# По умолчанию: ставит Node 22.x (NodeSource), nginx, пользователя deploy, каталоги
# /opt/craftshop/server и /opt/craftshop/www, systemd craftshop-api, сайт nginx.
#
# После выполнения:
# 1) Положите .env в /opt/craftshop/server/ (DATABASE_URL, JWT_SECRET, ADMIN_EMAIL, CORS_ORIGIN, PORT=3333)
# 2) DEPLOY_RESTART_CMD при SSH от root: «systemctl restart craftshop-api» (без sudo)
# 3) Запустите deploy-ssh.sh с вашей машины (по умолчанию пользователь SSH — root, см. scripts/deploy.env.example)
#
set -euo pipefail
if [[ "$(id -u)" != "0" ]]; then
echo "Запускайте от root: sudo $0" >&2
exit 1
fi
CRAFTSHOP_ROOT="${CRAFTSHOP_ROOT:-/opt/craftshop}"
CRAFTSHOP_USER="${CRAFTSHOP_USER:-deploy}"
CRAFTSHOP_SERVER_NAME="${CRAFTSHOP_SERVER_NAME:-_}"
CRAFTSHOP_NODE_MAJOR="${CRAFTSHOP_NODE_MAJOR:-22}"
SKIP_NODE_INSTALL="${SKIP_NODE_INSTALL:-0}"
SKIP_NGINX="${SKIP_NGINX:-0}"
SKIP_SYSTEMD="${SKIP_SYSTEMD:-0}"
if [[ -f /etc/craftshop-bootstrap.env ]]; then
set -a
# shellcheck source=/dev/null
source /etc/craftshop-bootstrap.env
set +a
fi
detect_os() {
if [[ -f /etc/os-release ]]; then
# shellcheck source=/dev/null
source /etc/os-release
echo "${ID:-unknown}"
return 0
fi
echo unknown
}
OS="$(detect_os)"
if [[ "$OS" != "debian" && "$OS" != "ubuntu" ]]; then
echo "Ожидался Debian или Ubuntu (получено: $OS). Прервите выполнение, если образ другой." >&2
fi
echo ">>> apt-get update"
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
echo ">>> Базовые пакеты"
apt-get install -y ca-certificates curl gnupg
if [[ "$SKIP_NODE_INSTALL" != "1" ]]; then
if command -v node >/dev/null 2>&1; then
ver="$(node -p "parseInt(process.versions.node,10)" 2>/dev/null || echo 0)"
if [[ "${ver:-0}" -ge 20 ]]; then
echo ">>> Node уже есть (версия $(node --version)), пропуск NodeSource"
else
echo ">>> Node слишком старый, ставим ${CRAFTSHOP_NODE_MAJOR}.x через NodeSource"
curl -fsSL "https://deb.nodesource.com/setup_${CRAFTSHOP_NODE_MAJOR}.x" | bash -
apt-get install -y nodejs
fi
else
echo ">>> Установка Node.js ${CRAFTSHOP_NODE_MAJOR}.x через NodeSource"
curl -fsSL "https://deb.nodesource.com/setup_${CRAFTSHOP_NODE_MAJOR}.x" | bash -
apt-get install -y nodejs
fi
else
echo ">>> SKIP_NODE_INSTALL=1 — убедитесь, что node >= 20.6 есть в системе"
command -v node >/dev/null 2>&1 || {
echo "node не найден" >&2
exit 1
}
fi
echo ">>> Пользователь $CRAFTSHOP_USER"
if ! id -u "$CRAFTSHOP_USER" >/dev/null 2>&1; then
useradd --create-home --shell /bin/bash "$CRAFTSHOP_USER"
fi
echo ">>> Каталоги $CRAFTSHOP_ROOT/{server,www,uploads}"
mkdir -p "$CRAFTSHOP_ROOT/server/uploads" "$CRAFTSHOP_ROOT/www"
chown -R "$CRAFTSHOP_USER:$CRAFTSHOP_USER" "$CRAFTSHOP_ROOT"
chmod 755 "$CRAFTSHOP_ROOT" "$CRAFTSHOP_ROOT/server" "$CRAFTSHOP_ROOT/www"
if [[ "$SKIP_SYSTEMD" != "1" ]]; then
echo ">>> systemd craftshop-api"
cat >/etc/systemd/system/craftshop-api.service <<EOF
[Unit]
Description=Craftshop API (Fastify)
After=network.target
[Service]
Type=simple
User=$CRAFTSHOP_USER
Group=$CRAFTSHOP_USER
WorkingDirectory=$CRAFTSHOP_ROOT/server
EnvironmentFile=-$CRAFTSHOP_ROOT/server/.env
ExecStart=/usr/bin/node src/index.js
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable craftshop-api.service
echo "(сервис не запущен, пока не появится код и \$CRAFTSHOP_ROOT/server/.env)"
fi
if [[ "$SKIP_NGINX" != "1" ]]; then
apt-get install -y nginx
NGINX_SITE="/etc/nginx/sites-available/craftshop"
cat >"$NGINX_SITE" <<NGX
# Craftshop: статика SPA + proxy /api и /uploads на Node (:3333)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name $CRAFTSHOP_SERVER_NAME;
root $CRAFTSHOP_ROOT/www;
index index.html;
location /api/ {
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 / {
try_files \$uri \$uri/ /index.html;
}
}
NGX
if [[ -f /etc/nginx/sites-enabled/default ]]; then
rm -f /etc/nginx/sites-enabled/default
fi
ln -sf "$NGINX_SITE" /etc/nginx/sites-enabled/craftshop
nginx -t
systemctl reload nginx || systemctl restart nginx
echo ">>> nginx включён на порту 80 (server_name=$CRAFTSHOP_SERVER_NAME)"
fi
cat >"$CRAFTSHOP_ROOT/server/README-PLACE-ENV.txt" <<TXT
Создайте файл .env в этом каталоге (права только для $CRAFTSHOP_USER).
Минимум:
DATABASE_URL="file:./prod.db"
PORT=3333
JWT_SECRET=<длинная случайная строка>
ADMIN_EMAIL=<ваш email админа>
CORS_ORIGIN=http://<IP_или_домен_фронта>
IS_DEFAULT_CODE_ENABLED=false
Базу и код вы зальёте скриптом deploy-ssh.sh с машины разработчика:
первый запуск после деплоя: systemctl start craftshop-api (от root; иначе sudo)
TXT
chown "$CRAFTSHOP_USER:$CRAFTSHOP_USER" "$CRAFTSHOP_ROOT/server/README-PLACE-ENV.txt"
if [[ -n "${CRAFTSHOP_AUTHORIZED_KEY:-}" ]]; then
uhome="$(getent passwd "$CRAFTSHOP_USER" | cut -d: -f6)"
install -d -m 700 -o "$CRAFTSHOP_USER" -g "$CRAFTSHOP_USER" "$uhome/.ssh"
afile="$uhome/.ssh/authorized_keys"
if [[ ! -f "$afile" ]]; then
install -m 600 -o "$CRAFTSHOP_USER" -g "$CRAFTSHOP_USER" /dev/null "$afile"
fi
if ! grep -qFx "$CRAFTSHOP_AUTHORIZED_KEY" "$afile" 2>/dev/null; then
printf '%s\n' "$CRAFTSHOP_AUTHORIZED_KEY" >>"$afile"
fi
echo ">>> Добавлен SSH-ключ в $afile"
fi
echo ""
echo "Готово Этап A."
echo "- Каталог: $CRAFTSHOP_ROOT"
echo "- Пользователь: $CRAFTSHOP_USER"
echo "- Положите $CRAFTSHOP_ROOT/server/.env и выполните деплой кода (--backend-only), затем: systemctl start craftshop-api"