You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自有服务器上无中断正确部署SvelteKit应用?

无中断部署SvelteKit应用(PM2+Ubuntu)

1. 修正生产环境启动方式

生产环境不要用npm run preview(该命令仅用于本地预览构建产物),直接运行SvelteKit构建后的Node入口文件,更高效且符合生产规范:

  • 构建完成后,产物在build目录,入口逻辑可通过自定义启动文件管理
  • 修改ecosystem.config.cjs的生产应用配置:
module.exports = {
    apps: [
        {
            name: "app_sistamu",
            // 替换为自定义启动文件(下文会创建)
            script: "./server.js",
            args: "--port 8080",
            watch: false,
            instances: "max",
            exec_mode: "cluster",
            // 配置优雅重启参数,避免强制终止用户请求
            kill_timeout: 5000,
            wait_ready: true,
            listen_timeout: 10000
        },
        // 开发环境配置保留
        {
            name: "app_sistamu_DEV",
            script: "npm",
            args: "run dev -- --host --port 5173",
            out_file: "/dev/null",
            watch: false
        }
    ],
};

2. 实现零停机部署的核心方案

方案一:PM2优雅重载+预构建验证

先完成构建和可用性验证,再触发PM2的优雅重载,确保新进程就绪后才替换旧进程:

# 合并代码分支
git merge -m "Merge development to master" development
# 仅安装生产依赖(减少构建时间)
npm install --production
# 构建应用
npm run build
# 临时启动新构建的服务,验证可用性
node ./server.js --port 8081 &
TEST_PID=$!
sleep 5
# 测试服务是否正常响应
curl -s http://localhost:8081 > /dev/null
if [ $? -eq 0 ]; then
    # 验证通过,终止临时进程
    kill $TEST_PID
    # 触发PM2优雅重载,自动完成新旧进程切换
    pm2 reload app_sistamu --update-env
else
    # 验证失败,终止临时进程并中断部署
    kill $TEST_PID
    echo "Build verification failed, deployment aborted"
    exit 1
fi

关键参数说明:

  • --update-env:重载时同步更新环境变量
  • PM2配置中的wait_ready:等待进程发送ready信号后才标记为在线
  • kill_timeout:给旧进程预留处理完现有请求的时间

方案二:蓝绿部署(绝对零停机)

如果对可用性要求极高,可采用蓝绿部署,通过反向代理(如Nginx)切换流量:

  1. 修改ecosystem.config.cjs,添加蓝绿两个环境的配置:
module.exports = {
    apps: [
        {
            name: "app_sistamu_BLUE",
            script: "./server.js",
            args: "--port 8080",
            exec_mode: "cluster",
            instances: "max"
        },
        {
            name: "app_sistamu_GREEN",
            script: "./server.js",
            args: "--port 8081",
            exec_mode: "cluster",
            instances: "max"
        },
        // 开发环境配置保留...
    ]
};
  1. 部署脚本逻辑:
git merge -m "Merge development to master" development
npm install --production
npm run build

# 读取Nginx配置,确定当前活跃环境
ACTIVE_ENV=$(grep -o "app_sistamu_[A-Z]*" /etc/nginx/sites-available/your-app.conf | head -1)
DEPLOY_ENV="app_sistamu_GREEN"
DEPLOY_PORT=8081
if [ "$ACTIVE_ENV" = "app_sistamu_GREEN" ]; then
    DEPLOY_ENV="app_sistamu_BLUE"
    DEPLOY_PORT=8080
fi

# 启动新环境的应用
pm2 start ecosystem.config.cjs --only $DEPLOY_ENV
# 等待服务启动并验证可用性
sleep 10
curl -s http://localhost:$DEPLOY_PORT > /dev/null
if [ $? -eq 0 ]; then
    # 更新Nginx配置,切换流量到新环境
    sed -i "s/app_sistamu_[A-Z]*/$DEPLOY_ENV/g" /etc/nginx/sites-available/your-app.conf
    nginx -s reload
    # 停止旧环境的应用
    pm2 stop $ACTIVE_ENV
else
    # 验证失败,清理新环境进程
    pm2 stop $DEPLOY_ENV
    echo "Deployment failed, rolling back"
    exit 1
fi

3. 配置SvelteKit发送就绪信号

让PM2准确识别进程启动状态,需在项目根目录创建server.js:

import { handler } from './build/handler.js';
import express from 'express';

const app = express();
const port = process.argv[2] ? process.argv[2].split('=')[1] : 8080;

app.use(handler);

const server = app.listen(port, () => {
    console.log(`Server running on port ${port}`);
    // 向PM2发送就绪信号
    if (process.send) {
        process.send('ready');
    }
});

// 处理优雅关闭,确保完成现有请求后再终止
process.on('SIGTERM', () => {
    console.log('SIGTERM received, shutting down gracefully');
    server.close(() => {
        console.log('Server closed');
        process.exit(0);
    });
});

同时修改svelte.config.js的adapter配置,适配环境变量:

adapter: adapter({
    out: 'build',
    precompress: false,
    envPrefix: 'APP_',
    polyfill: true
}),

4. 补充优化建议

  • 配置PM2日志:在ecosystem.config.cjs中添加error_file和out_file参数,方便排查部署问题
  • Nginx静态缓存:在反向代理层启用静态资源缓存,降低应用服务器压力
  • 自动化CI/CD:结合GitHub Actions或GitLab CI实现自动构建、验证和部署,减少手动操作误差

内容的提问来源于stack exchange,提问作者Ichwanul Fadhli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 03:33:19