9.8 KiB
部署文档(JessieGem.zeotaki.com / backend:2088 / frontend:2099)
本文档假设目标服务器为 Linux(Ubuntu/Debian 系)。部署目标:
- 后端 Go 服务监听
127.0.0.1:2088 - 前端 Vite 预览服务监听
127.0.0.1:2099 - Nginx 对外提供
https://JessieGem.zeotaki.com,并转发:/-> 前端2099/api/-> 后端2088
这样前端请求
/api/*仍然同域,不需要浏览器跨域。
0. 服务器前置
0.1 依赖软件
在服务器安装:
- Nginx
- MySQL(或可访问的 MySQL 实例)
- Go 1.22+
- Node.js 20+(用于构建与运行
vite preview)
Ubuntu 示例:
sudo apt update
sudo apt install -y nginx git
Go/Node 的安装方式你可按服务器习惯来(官方包、nvm、asdf 都可),但要满足版本要求:
- Go:
go version>= 1.22 - Node:
node -v>= 20
0.2 端口规划与防火墙
- 对公网开放:80/443
- 仅本机监听:2088/2099(不要直接暴露公网)
如使用 UFW:
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enable
1. 后端部署(Go / 2088)
1.1 创建运行用户与目录
sudo useradd -r -s /usr/sbin/nologin cockpit || true
sudo mkdir -p /opt/jessiegem-cockpit/backend
sudo mkdir -p /etc/jessiegem-cockpit
sudo chown -R cockpit:cockpit /opt/jessiegem-cockpit
1.2 准备后端配置
后端读取 backend/configs/config.yaml(相对工作目录 ./configs),同时也支持环境变量覆盖(COCKPIT_ 前缀)。
推荐在服务器用独立配置目录 /etc/jessiegem-cockpit/config.yaml,然后 systemd 的 WorkingDirectory 指向 /opt/jessiegem-cockpit/backend,并把配置复制到 ./configs/config.yaml。
创建配置:
sudo mkdir -p /opt/jessiegem-cockpit/backend/configs
sudo tee /opt/jessiegem-cockpit/backend/configs/config.yaml >/dev/null <<'YAML'
server:
addr: "127.0.0.1:2088"
db:
driver: "mysql"
# 按你的服务器实际 MySQL 修改
dsn: "root:root@tcp(127.0.0.1:3306)/cockpit?charset=utf8mb4&parseTime=True&loc=Local"
auth:
# 必须替换为强随机串
accessTokenSecret: "REPLACE_ME_ACCESS"
refreshTokenSecret: "REPLACE_ME_REFRESH"
accessTokenTtl: "15m"
refreshTokenTtl: "720h"
cors:
allowOrigins:
- "https://JessieGem.zeotaki.com"
YAML
sudo chown -R cockpit:cockpit /opt/jessiegem-cockpit/backend
sudo chmod 600 /opt/jessiegem-cockpit/backend/configs/config.yaml
注意:后端启动会自动 AutoMigrate + Seed(包含默认管理员
admin/admin123)。生产环境建议你首次登录后立即改密码。
1.3 systemd 服务(backend)
创建 /etc/systemd/system/cockpit-backend.service:
sudo tee /etc/systemd/system/cockpit-backend.service >/dev/null <<'UNIT'
[Unit]
Description=Cockpit Backend (Go)
After=network.target
[Service]
User=cockpit
Group=cockpit
WorkingDirectory=/opt/jessiegem-cockpit/backend
ExecStart=/opt/jessiegem-cockpit/backend/cockpit-server
Restart=always
RestartSec=2
Environment=GIN_MODE=release
[Install]
WantedBy=multi-user.target
UNIT
启动:
sudo systemctl daemon-reload
sudo systemctl enable --now cockpit-backend
sudo systemctl status cockpit-backend --no-pager
日志查看:
journalctl -u cockpit-backend -f
2. 前端部署(Vite preview / 2099)
前端推荐构建后用 vite preview 在本机端口提供服务,再由 Nginx 反代。这样部署简单,但注意 Node 进程稳定性要交给 systemd 管理。
2.1 构建环境变量(非常重要)
前端生产构建时需要 VITE_API_BASE 指向站点域名(同域走 Nginx /api 反代):
export VITE_API_BASE="https://JessieGem.zeotaki.com"
2.2 systemd 服务(frontend)
创建目录:
sudo mkdir -p /opt/jessiegem-cockpit/frontend
sudo chown -R cockpit:cockpit /opt/jessiegem-cockpit/frontend
创建 /etc/systemd/system/cockpit-frontend.service:
sudo tee /etc/systemd/system/cockpit-frontend.service >/dev/null <<'UNIT'
[Unit]
Description=Cockpit Frontend (Vite preview)
After=network.target
[Service]
User=cockpit
Group=cockpit
WorkingDirectory=/opt/jessiegem-cockpit/frontend
Environment=NODE_ENV=production
Environment=HOST=127.0.0.1
Environment=PORT=2099
ExecStart=/usr/bin/npm run preview -- --host 127.0.0.1 --port 2099 --strictPort
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
UNIT
启动:
sudo systemctl daemon-reload
sudo systemctl enable --now cockpit-frontend
sudo systemctl status cockpit-frontend --no-pager
3. Nginx 配置(JessieGem.zeotaki.com)
目标:
/->http://127.0.0.1:2099/api/->http://127.0.0.1:2088
创建站点配置:
sudo tee /etc/nginx/sites-available/jessiegem-cockpit.conf >/dev/null <<'NGINX'
server {
listen 80;
server_name JessieGem.zeotaki.com;
# 如果你使用 certbot,建议这里仅用于 http->https 跳转
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name JessieGem.zeotaki.com;
# 证书路径按你服务器实际情况填写(certbot 默认示例)
ssl_certificate /etc/letsencrypt/live/JessieGem.zeotaki.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/JessieGem.zeotaki.com/privkey.pem;
client_max_body_size 50m;
# 前端
location / {
proxy_pass http://127.0.0.1:2099;
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;
}
# 后端 API
location /api/ {
proxy_pass http://127.0.0.1:2088;
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;
}
}
NGINX
启用并检查:
sudo ln -sf /etc/nginx/sites-available/jessiegem-cockpit.conf /etc/nginx/sites-enabled/jessiegem-cockpit.conf
sudo nginx -t
sudo systemctl reload nginx
证书(如未配置):
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d JessieGem.zeotaki.com
4. 手工发布流程(不使用 Jenkins)
4.1 拉取代码
在服务器上:
cd /opt/jessiegem-cockpit
sudo -u cockpit git clone <你的-gitea-仓库-url> repo
后续更新:
cd /opt/jessiegem-cockpit/repo
sudo -u cockpit git pull
4.2 构建并发布后端
cd /opt/jessiegem-cockpit/repo/backend
sudo -u cockpit go build -o /opt/jessiegem-cockpit/backend/cockpit-server ./cmd/server
sudo systemctl restart cockpit-backend
4.3 构建并发布前端
cd /opt/jessiegem-cockpit/repo/frontend
sudo -u cockpit npm ci
sudo -u cockpit VITE_API_BASE="https://JessieGem.zeotaki.com" npm run build
# vite preview 需要 dist,所以把 dist 与 package 相关文件同步到运行目录
sudo -u cockpit rsync -a --delete dist/ /opt/jessiegem-cockpit/frontend/dist/
sudo -u cockpit rsync -a package.json package-lock.json vite.config.ts /opt/jessiegem-cockpit/frontend/
cd /opt/jessiegem-cockpit/frontend
sudo -u cockpit npm ci
sudo systemctl restart cockpit-frontend
5. Jenkins + Gitea 自动部署(推荐)
5.1 Jenkins 准备
在 Jenkins 配置以下内容:
- 凭据 1:Gitea 访问令牌/账号(用于拉取仓库)
- 凭据 2:SSH 私钥(用于从 Jenkins 服务器 SSH 到部署服务器)
- 在 Gitea 仓库配置 Webhook -> Jenkins(push 触发构建)
5.2 服务器准备(用于 Jenkins 部署)
保证 Jenkins 可以 SSH 到服务器,并且服务器上已创建:
/opt/jessiegem-cockpit/backend/opt/jessiegem-cockpit/frontend- systemd 服务:
cockpit-backend、cockpit-frontend
5.3 Jenkinsfile 示例(Pipeline)
把下面内容保存为仓库根目录 Jenkinsfile(或在 Jenkins Pipeline 脚本里粘贴):
pipeline {
agent any
environment {
DEPLOY_HOST = '你的服务器IP或域名'
DEPLOY_USER = 'root' // 或具备 sudo 权限的用户
VITE_API_BASE = 'https://JessieGem.zeotaki.com'
}
stages {
stage('Checkout') {
steps { checkout scm }
}
stage('Build Backend') {
steps {
dir('backend') {
sh 'go version'
sh 'go build -o cockpit-server ./cmd/server'
}
}
}
stage('Build Frontend') {
steps {
dir('frontend') {
sh 'node -v && npm -v'
sh 'npm ci'
sh "VITE_API_BASE=${VITE_API_BASE} npm run build"
}
}
}
stage('Deploy') {
steps {
sshagent(credentials: ['你的-jenkins-ssh-credential-id']) {
sh '''
set -e
rsync -avz --delete backend/cockpit-server ${DEPLOY_USER}@${DEPLOY_HOST}:/opt/jessiegem-cockpit/backend/cockpit-server
rsync -avz --delete frontend/dist/ ${DEPLOY_USER}@${DEPLOY_HOST}:/opt/jessiegem-cockpit/frontend/dist/
rsync -avz frontend/package.json frontend/package-lock.json ${DEPLOY_USER}@${DEPLOY_HOST}:/opt/jessiegem-cockpit/frontend/
ssh ${DEPLOY_USER}@${DEPLOY_HOST} "cd /opt/jessiegem-cockpit/frontend && npm ci && sudo systemctl restart cockpit-frontend"
ssh ${DEPLOY_USER}@${DEPLOY_HOST} "sudo systemctl restart cockpit-backend"
'''
}
}
}
}
}
如果 Jenkins 机器不是 Linux(例如 Windows),上面
sh需要改成对应的bat/powershell,或者让 Jenkins agent 跑在 Linux 节点上。
6. 验收清单
6.1 服务状态
sudo systemctl status cockpit-backend --no-pager
sudo systemctl status cockpit-frontend --no-pager
6.2 端口监听(应仅 127.0.0.1)
sudo ss -lntp | egrep '2088|2099'
6.3 站点验证
- 打开:
https://JessieGem.zeotaki.com - 登录:
admin / admin123 - Network 面板确认 API 请求是:
https://JessieGem.zeotaki.com/api/...(同域)