95 lines
2.6 KiB
Bash
95 lines
2.6 KiB
Bash
|
|
#!/usr/bin/env bash
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
APP_USER="${APP_USER:-daniel}"
|
|||
|
|
APP_DIR="${APP_DIR:-/opt/investor-rpg}"
|
|||
|
|
SERVICE_NAME="${SERVICE_NAME:-investor-rpg}"
|
|||
|
|
SERVER_NAME="${SERVER_NAME:-_}"
|
|||
|
|
|
|||
|
|
if [[ "${EUID}" -ne 0 ]]; then
|
|||
|
|
echo "請用 sudo 執行:sudo bash $0" >&2
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
apt-get update
|
|||
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl nginx rsync sqlite3
|
|||
|
|
|
|||
|
|
if ! command -v node >/dev/null 2>&1 || [[ "$(node -p 'Number(process.versions.node.split(".")[0])')" -lt 22 ]]; then
|
|||
|
|
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
|||
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
install -d -o "${APP_USER}" -g "${APP_USER}" "${APP_DIR}" "${APP_DIR}/backups"
|
|||
|
|
install -d -o "${APP_USER}" -g "${APP_USER}" "/opt/content" "/opt/content/raw" "/opt/content/raw/patterns"
|
|||
|
|
|
|||
|
|
cat >"/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
|||
|
|
[Unit]
|
|||
|
|
Description=Investor RPG Node backend
|
|||
|
|
After=network-online.target
|
|||
|
|
Wants=network-online.target
|
|||
|
|
|
|||
|
|
[Service]
|
|||
|
|
Type=simple
|
|||
|
|
User=${APP_USER}
|
|||
|
|
Group=${APP_USER}
|
|||
|
|
WorkingDirectory=${APP_DIR}
|
|||
|
|
Environment=NODE_ENV=production
|
|||
|
|
Environment=PORT=3000
|
|||
|
|
Environment=HOST=127.0.0.1
|
|||
|
|
ExecStart=/usr/bin/npm start
|
|||
|
|
Restart=always
|
|||
|
|
RestartSec=5
|
|||
|
|
TimeoutStopSec=20
|
|||
|
|
|
|||
|
|
[Install]
|
|||
|
|
WantedBy=multi-user.target
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
cat >"/etc/nginx/sites-available/${SERVICE_NAME}" <<EOF
|
|||
|
|
server {
|
|||
|
|
listen 80 default_server;
|
|||
|
|
listen [::]:80 default_server;
|
|||
|
|
server_name ${SERVER_NAME};
|
|||
|
|
|
|||
|
|
root ${APP_DIR}/dist;
|
|||
|
|
index index.html;
|
|||
|
|
client_max_body_size 5m;
|
|||
|
|
|
|||
|
|
location /api/ {
|
|||
|
|
proxy_pass http://127.0.0.1:3000;
|
|||
|
|
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;
|
|||
|
|
proxy_read_timeout 180s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
location /book-patterns/ {
|
|||
|
|
proxy_pass http://127.0.0.1:3000;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
proxy_set_header Host \$host;
|
|||
|
|
proxy_read_timeout 60s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
try_files \$uri \$uri/ /index.html;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
rm -f /etc/nginx/sites-enabled/default
|
|||
|
|
ln -sfn "/etc/nginx/sites-available/${SERVICE_NAME}" "/etc/nginx/sites-enabled/${SERVICE_NAME}"
|
|||
|
|
|
|||
|
|
cat >"/etc/sudoers.d/${SERVICE_NAME}-deploy" <<EOF
|
|||
|
|
${APP_USER} ALL=(root) NOPASSWD: /usr/bin/systemctl restart ${SERVICE_NAME}, /usr/sbin/nginx -t
|
|||
|
|
EOF
|
|||
|
|
chmod 0440 "/etc/sudoers.d/${SERVICE_NAME}-deploy"
|
|||
|
|
|
|||
|
|
systemctl daemon-reload
|
|||
|
|
systemctl enable "${SERVICE_NAME}" nginx
|
|||
|
|
nginx -t
|
|||
|
|
systemctl restart nginx
|
|||
|
|
|
|||
|
|
echo "Bootstrap 完成:Node $(node -v),Nginx 已啟動,應用程式目錄為 ${APP_DIR}。"
|