diff --git a/deploy/Dockerfile.backend b/deploy/Dockerfile.backend new file mode 100644 index 0000000..25fb71b --- /dev/null +++ b/deploy/Dockerfile.backend @@ -0,0 +1,14 @@ +FROM node:20-alpine AS builder +WORKDIR /app +COPY backend/package*.json ./ +RUN npm ci --production +COPY backend/ ./ +RUN npm run build --prefix backend + +FROM node:20-alpine +WORKDIR /app +COPY --from=builder /app/backend/dist ./dist +COPY backend/package*.json ./ +RUN npm ci --production --prefix /app +EXPOSE 4000 +CMD ["node", "./dist/index.js"] diff --git a/deploy/Dockerfile.frontend b/deploy/Dockerfile.frontend new file mode 100644 index 0000000..83d67f9 --- /dev/null +++ b/deploy/Dockerfile.frontend @@ -0,0 +1,12 @@ +FROM node:20-alpine AS builder +WORKDIR /app +COPY frontend/package*.json ./ +RUN npm ci +COPY frontend/ ./ +RUN npm run build --prefix frontend + +FROM nginx:stable-alpine +COPY --from=builder /app/frontend/dist /usr/share/nginx/html +COPY deploy/nginx/chat.conf /etc/nginx/conf.d/default.conf +EXPOSE 8443 +CMD ["nginx", "-g", "daemon off;"] diff --git a/deploy/README-deploy.md b/deploy/README-deploy.md new file mode 100644 index 0000000..86fd8da --- /dev/null +++ b/deploy/README-deploy.md @@ -0,0 +1,82 @@ +部署说明(Ubuntu 24, 阿里云) + +目标:把 frontend(Vite)构建为静态文件并通过 nginx 提供,后端运行在本机(端口 4000 作为示例),整个站点通过域名在非常用端口访问(示例使用 8443)。 + +主要思路(摘要) +- 后端:在服务器上安装 Node 20,构建并用 systemd 运行(或用 Docker/PM2)。 +- 前端:在服务器或 CI 上执行 `npm run build`,将 `frontend/dist` 拷贝到 `/var/www/chat/frontend`,由 nginx 提供静态文件。 +- nginx:配置反向代理 `/api` 到后端(127.0.0.1:4000),将主机监听在非标准端口(示例:8443)。 + +示例文件已放在 `deploy/` 目录: +- `deploy/nginx/chat.conf` - nginx server block 示例(监听 8443)。 +- `deploy/systemd/chat-backend.service` - systemd 服务单元示例,假设后端位于 `/var/www/chat/backend` 并且已构建到 `dist`。 +- `deploy/Dockerfile.backend` - 可选:后端 Dockerfile(多阶段构建)。 +- `deploy/Dockerfile.frontend` - 可选:前端构建并用 nginx 提供的 Dockerfile。 + +快速按步骤(拷贝/粘贴到服务器的命令,基于 Ubuntu 24) + +1) 登录服务器并切换到非 root 普通用户(假设使用 `ubuntu`): + + sudo -i + adduser --disabled-password --gecos "" chatuser || true + usermod -aG sudo chatuser + su - chatuser + +2) 安装基础依赖(Node 20 + nginx + build tools): + + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt update; sudo apt install -y nodejs nginx git build-essential + +3) 拉取代码并切到项目目录: + + git clone /var/www/chat + cd /var/www/chat + +4) 构建后端并生成产物(示例): + + cd backend + npm ci + npm run build + # 确认可执行入口(例如 dist/index.js 或 dist/server.js),如需修改 systemd 文件请调整 ExecStart + +5) 构建前端并准备静态文件: + + cd ../frontend + npm ci + npm run build + sudo mkdir -p /var/www/chat/frontend + sudo rm -rf /var/www/chat/frontend/* + sudo cp -r dist/* /var/www/chat/frontend/ + sudo chown -R www-data:www-data /var/www/chat/frontend + +6) 配置 systemd(后端) + + sudo cp deploy/systemd/chat-backend.service /etc/systemd/system/chat-backend.service + # 如果后台入口或工作目录不同,请编辑该文件 + sudo systemctl daemon-reload + sudo systemctl enable --now chat-backend.service + sudo systemctl status chat-backend.service + +7) 配置 nginx(监听非标准端口 8443) + + sudo cp deploy/nginx/chat.conf /etc/nginx/sites-available/chat + sudo ln -sf /etc/nginx/sites-available/chat /etc/nginx/sites-enabled/chat + sudo nginx -t && sudo systemctl reload nginx + + # 打开防火墙端口(如果使用 ufw) + sudo ufw allow 8443/tcp + +访问方式: +- 在浏览器中访问:https://your-domain:8443/ (如果未配置 HTTPS,可以先用 http://your-domain:8443/,但浏览器可能提示不安全) + +证书/HTTPS(建议) +- certbot 默认申请 HTTPS 在 80/443,如果你坚持使用非标准端口,可以申请证书然后在 nginx 上配置证书(证书本身不强制要求 443)。建议仍然把 80/443 暂时开放用于证书申请,然后可改回 8443 提供服务。 + +Docker 选项 +- 若你偏好 Docker 部署,参见 `deploy/Dockerfile.backend` 与 `deploy/Dockerfile.frontend`。 + +注意事项 +- systemd 的 `ExecStart` 假定后端构建后入口为 `/var/www/chat/backend/dist/index.js`,若不同请调整。 +- nginx config 中 proxy 与 websocket/SSE 头部已设置,但请根据你的后端 SSE 实现确认 `proxy_buffering off;` 是否需要在特定 location 启用。 + +如需我直接把这些配置拷贝到服务器并启用服务,需要给出 SSH 访问方式与权限或在服务器上运行命令并把输出贴回,我可以一步步协助。 diff --git a/deploy/nginx/chat.conf b/deploy/nginx/chat.conf new file mode 100644 index 0000000..778ebb2 --- /dev/null +++ b/deploy/nginx/chat.conf @@ -0,0 +1,32 @@ +server { + listen 8443; + server_name your-domain.com; + + root /var/www/chat/frontend; + index index.html; + + location /api/ { + proxy_pass http://127.0.0.1:4000/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_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; + # For SSE/streaming + proxy_buffering off; + chunked_transfer_encoding off; + } + + location / { + try_files $uri $uri/ /index.html; + } + + # optional: serve assets with long cache + location ~* \.(?:css|js|jpg|jpeg|gif|png|svg|ico|woff2?)$ { + expires 30d; + access_log off; + } +} diff --git a/deploy/systemd/chat-backend.service b/deploy/systemd/chat-backend.service new file mode 100644 index 0000000..197f1cb --- /dev/null +++ b/deploy/systemd/chat-backend.service @@ -0,0 +1,14 @@ +[Unit] +Description=Chat backend service +After=network.target + +[Service] +Type=simple +User=www-data +WorkingDirectory=/var/www/chat/backend +ExecStart=/usr/bin/node ./dist/index.js +Restart=on-failure +Environment=NODE_ENV=production + +[Install] +WantedBy=multi-user.target