Как правильно развернуть SvelteKit на собственном сервере, не отвлекая пользователя?

Итак, я создал эту информационную систему с Sveltekit, Ubuntu 22.04 в качестве серверной ОС, PM2 в качестве менеджера процессов и запускаю приложение в Node.Js. Я прочитал документацию Sveltekit о том, как собрать и развернуть приложение для адаптера узла, и вот мой svelte.config.js код:

import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/kit/vite';

import path from 'path';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://kit.svelte.dev/docs/integrations#preprocessors
    // for more information about preprocessors
    preprocess: vitePreprocess(),

    kit: {
        // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
        // If your environment is not supported or you settled on a specific environment, switch out the adapter.
        // See https://kit.svelte.dev/docs/adapters for more information about adapters.
        adapter: adapter({
            // default options are shown
            out: 'build',
            precompress: false,
            envPrefix: '',
            polyfill: true
        }),
        // Disable CSRF
        csrf: {
            checkOrigin: false,
        },
        alias: {
            // these are the aliases and paths to them
            '$src': path.resolve('./src')
        }
    },
    vitePlugin: {
        inspector: false
    }
};

export default config;

После его создания все, что мне нужно сделать, это отправить команду npm run preview, чтобы запустить приложение.

Поскольку я использую PM2, я создал файл ecosystem.config.cjs, чтобы можно было запускать приложение с помощью команды PM2. Вот конфигурация:

module.exports = {
    apps: [
        {
            name: "app_sistamu",
            script: "npm",
            args: "run preview -- --host --port 8080",
            watch: false,
            instances: "max",
            exec_mode: "cluster"
        },
        {
            name: "app_sistamu_DEV",
            script: "npm",
            args: "run dev -- --host --port 5173",
            out_file: "/dev/null",
            watch: false
        }
    ],
};

После всей подготовки все, что мне нужно сделать, это объединить все, от ветки разработки до основной ветки. Вот что я делаю:

git merge -m "Merging branch development to master" development; npm install; npm run build; pm2 reload ecosystem.config.cjs --only app_sistamu

Благодаря этому мое приложение теперь может работать на сервере. Есть только одна вещь. В следующий раз, если я захочу внести изменения, мне придется пересобрать приложение, а затем перезагрузить PM2. Я имею в виду, да, это имеет смысл, потому что для развертывания приложения мне нужно собрать его заново. Но это вызывает проблему: во время процесса сборки приложение возвращает ошибку 502 Bad Gateway. Но после того, как все будет сделано, приложение снова вернется в нормальное состояние без каких-либо ошибок.

Возникает вопрос: как правильно развернуть приложение, не нарушая взаимодействия пользователя с ним?

🤔 А знаете ли вы, что...
JavaScript поддерживает работу с графикой и аудио, что позволяет создавать мультимедийные веб-приложения.


1
100
3

Ответы:

Чтобы мой комментарий стал ответом:

Если ты делаешь

git merge -m «Объединение разработки ветки с основной разработкой»; установка НПМ; npm запустить сборку; pm2 перезагрузить экосистему.config.cjs --only app_sistamu

и вы говорите, что работа приложения прерывается во время сборки, это, вероятно, означает, что npm run build очищает или даже удаляет каталог dist, который обслуживает npm run preview.

При таком развертывании вы, вероятно, могли бы встроить другой каталог, а затем быстро поменять их местами, чтобы минимизировать помехи:

# build into new directory
npm run build --outDir=dist-new
# move current dist out of the way
mkdir -p old-dist
mv dist old-dist/"$(date +%s)"
# move new directory into place
mv dist-new dist

Не забудьте очистить каталоги old-dist, иначе они начнут накапливаться. :)


как правильно развернуть приложение, не нарушая взаимодействия пользователя с приложением?

Очень распространенное решение –

  • Используйте Docker-контейнеры

Типичный рабочий процесс в этом случае — разбить сборку приложения и его развертывание на две разные части.

  • Оберните ваше внешнее приложение SvelteKit адаптером узла (пример) и запустите веб-сервер node.js внутри контейнера Docker.
  • Создайте образ Docker , используя рабочий процесс Github Actions (пример)

Затем на производственном сервере.

  • Запустите команду Docker, чтобы обновить работающий контейнер до нового образа. Docker мгновенно заменит контейнер на новый образ, и никаких перебоев не произойдет.
docker pull frontend  # Pulls the new image to the local server cache
docker compose up -d frontend  # Switches to the new version 

Это относится не только к SvelteKit, но и к любому веб-серверу и веб-разработке сегодня.

Недостатком этого подхода является то, что вам сначала нужно научиться использовать Docker, а этому нужно многому научиться. Однако знания Docker можно использовать повторно и подходят для множества различных рабочих процессов развертывания независимо от инструментов и отрасли.


Решено

Думаю, после нескольких попыток я наконец решил эту проблему. Благодаря видео на YouTube, предоставленному aqust, я решил эту проблему:

  1. Прежде чем создавать приложение, убедитесь, что вы установили узел адаптера согласно документации в свой проект SvelteKit. Если да, запустите команду сборки, чтобы создать приложение, в этом примере запустите npm run build;
  2. После завершения сборки приложения должна появиться папка с именем «build». Затем я скопировал все файлы внутри него в отдельный каталог /var/www/production/. Чтобы скопировать все файлы, просто запустите эту команду cp -a build/. /var/www/production/;
  3. Откройте целевой каталог. Инициализируйте npm, а затем добавьте "type" = "module" в package.json файл. Затем добавьте пакет express.js, введя npm install -D express;
  4. Создайте новый файл с именем server.js для последующего обслуживания приложения:
import express from "express";
import { handler } from "./handler.js";


const app  = express();
const port = 8080;

app.use(handler);

app.listen(port, () => {
    console.info(`The application is running on port ${port}`);
});
  1. Поскольку для запуска приложения я использую PM2, я создал файл ecosystem.config.cjs для запуска PM2:
module.exports = {
    apps: [
        {
            name     : "app_sistamu",
            script   : "server.js",
            watch    : false,
            instances: "max",
            exec_mode: "cluster"
        }
    ],
};

Чтобы запустить PM2, я запускаю эту команду pm2 start ecosystem.config.cjs --only app_sistamu.

Делая это в следующий раз, когда мне придется применить новые изменения, я просто запускаю команду сборки, вставляю файлы сборки в целевой каталог, а затем перезагружаю экземпляры PM2. Этот метод обеспечивает нулевое время простоя, что означает отсутствие перерывов в работе пользователя.

Я надеюсь, что это поможет другим в будущем. Если я допустил какую-то ошибку или, возможно, есть какое-либо другое решение или подход, пожалуйста, прокомментируйте здесь ниже.