Облачная платформаEvolution

Запуск приложения на виртуальной машине в качестве службы


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

Вы создадите служебный NodeJS-сервис, научитесь работать с дополнительным виртуальным диском, а также настроите запуск сервиса как systemd-службы для автоматизации процессов.

Вы будете использовать следующие сервисы:

  • «Виртуальные машины» — сервис, в рамках которого предоставляется виртуальная машина.

  • Systemd — системный менеджер служб в Linux.

  • NodeJS и TypeScript — стек для разработки серверных приложений на языке JavaScript.

Шаги:

  1. Разверните ресурсы в облаке.

  2. Подготовьте дополнительный диск к работе.

  3. Установите NodeJS и зависимости.

  4. Создайте и соберите сервис резервного копирования.

  5. Настройте запуск сервиса как systemd-службы.

Перед началом работы

Зарегистрируйтесь в личном кабинете Cloud.ru.

Если вы уже зарегистрированы, войдите под своей учетной записью.

1. Разверните ресурсы в облаке

На этом шаге вы создадите виртуальную машину c дополнительным диском для хренения резервных копий и назначите ей публичный IP-адрес.

  1. Создайте группу безопасности с названием backup-service и добавьте в нее правила:

    Трафик

    Протокол

    Порт

    Тип источника/адресата

    Источник/Адресат

    Исходящий

    Любой

    Оставьте пустым

    IP-адрес

    0.0.0.0/0

  2. Создайте виртуальную машину со следующими параметрами:

    • Названиеbackup-service.

    • Образ — публичный образ Ubuntu 22.04.

    • Диски — добавьте новый SSD-диск размером 10 ГБ.

    • Сетевой интерфейс — выберите тип Публичный IP.

    • Группы безопасностиbackup-service.

    • Логин — оставьте имя пользователя по умолчанию или укажите новое.

    • Метод аутентификацииПароль.

    • Пароль — задайте пароль пользователя.

    • Остальные параметры оставьте по умолчанию или выберите на свое усмотрение.

Убедитесь, что в личном кабинете:

  • На странице Инфраструктура → Виртуальные машины отображается виртуальная машина backup-service со статусом «Запущена» и назначенным публичным IP-адресом.

  • На вкладке Сетевые параметры страницы виртуальной машины для сетевого интерфейса с публичным IP-адресом отображается группа безопасности backup-service.

2. Подготовьте дополнительный диск к работе

На этом шаге вы отформатируете диск, смонтируете его и настроите права доступа.

  1. Подключитесь к виртуальной машине через серийную консоль.

  2. Получите список дисков виртуальной машины, выполнив команду:

    lsblk

    Подключенный диск должен отобразиться в конце списка с названием vdb.

  3. Отформатируйте диск и создайте файловую систему:

    sudo mkfs -t xfs /dev/vdb
  4. Создайте каталог для точки монтирования диска:

    sudo mkdir /backup-disk
  5. Выполните монтирование в созданный каталог:

    sudo mount /dev/vdb /backup-disk
  6. Предоставьте всем пользователям вашего проекта права на чтение и запись данных диска:

    sudo chmod a+rw /backup-disk
  7. Проверьте с помощью команды lsblk , что диск backup-disk смонтирован и доступен.

3. Установите NodeJS и зависимости

На этом шаге вы установите NodeJS через NVM, а также необходимые инструменты для работы сервиса резервного копирования.

  1. В серийной консоли виртуальной машины последовательно выполните команды:

    sudo apt-get update -y
    sudo apt-get install -y curl
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
    source ~/.bashrc
    nvm install 20
    nvm use 20
  2. Проверьте, что NodeJS и npm установлены:

    node -v
    npm -v

    В результате отобразятся установленные версии.

4. Создайте и соберите сервис резервного копирования

На этом шаге вы развернете проект резервного копирования, настроите параметры TypeScript, создадите конфигурационные и исходные файлы.

  1. Создайте директорию для файлов, которые будут копироваться:

    mkdir files
  2. Создайте директорию проекта:

    mkdir backup-service
  3. Перейдите в директорию проекта:

    cd backup-service
  4. Инициализируйте проект NodeJS:

    npm init -y
  5. Установите зависимости:

    npm install typescript ts-node @types/node --save-dev
    npm install node-cron fs-extra
    npm install @types/fs-extra --save-dev
  6. Сгенерируйте файл tsconfig.json:

    npx tsc --init --module commonjs
  7. Откройте файл tsconfig.json для редактирования:

    nano tsconfig.json
  8. Вставьте в файл конфигурацию:

    {
    "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "sourceMap": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules", "dist"]
    }
  9. Создайте директорию src и файл config.json:

    mkdir src
    touch config.json
    nano config.json
  10. Вставьте в файл конфигурацию:

    {
    "inputDir": "/home/user1/files",
    "outputDir": "/backup-disk/backups",
    "backupInterval": "*/10 * * * *",
    "logLevel": "info"
    }
  11. Создайте основной скрипт резервного копирования:

    cd src
    touch backup-service.ts
    nano backup-service.ts
  12. Вставьте код скрипта:

    import * as fs from 'fs-extra';
    import * as path from 'path';
    import * as cron from 'node-cron';
    interface BackupConfig {
    inputDir: string;
    outputDir: string;
    backupInterval: string;
    logLevel: string;
    }
    class BackupService {
    private config: BackupConfig;
    constructor(configPath: string) {
    this.config = this.loadConfig(configPath);
    }
    private loadConfig(configPath: string): BackupConfig {
    try {
    const configData = fs.readFileSync(configPath, 'utf8');
    return JSON.parse(configData);
    } catch (error) {
    console.error('Error loading configuration:', error);
    process.exit(1);
    }
    }
    private async performBackup(): Promise<void> {
    try {
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
    const backupDir = path.join(this.config.outputDir, `backup-${timestamp}`);
    console.log(`Starting backup from ${this.config.inputDir} to ${backupDir}`);
    // Ensure output directory exists
    await fs.ensureDir(this.config.outputDir);
    // Copy directory recursively
    await fs.copy(this.config.inputDir, backupDir);
    console.log(`Backup completed successfully at ${new Date().toISOString()}`);
    } catch (error) {
    console.error('Backup failed:', error);
    }
    }
    public start(): void {
    console.log(`Backup service started with interval: ${this.config.backupInterval}`);
    // Schedule backup job
    cron.schedule(this.config.backupInterval, () => {
    this.performBackup();
    });
    // Perform initial backup
    this.performBackup();
    }
    }
    // Start the service
    const configPath = process.env.CONFIG_PATH || '../config.json';
    const backupService = new BackupService(configPath);
    backupService.start();
    // Keep the process running
    process.on('SIGINT', () => {
    console.log('Backup service shutting down...');
    process.exit(0);
    });
    process.on('SIGTERM', () => {
    console.log('Backup service shutting down...');
    process.exit(0);
    });
  13. Откройте файл package.json для редактирования:

    cd ..
    nano package.json
  14. Отредактируйте скрипты запуска в секции scripts:

    {
    "scripts": {
    "build": "tsc",
    "start": "node dist/backup-service.js",
    "dev": "ts-node src/backup-service.ts"
    },
    }
  15. Соберите проект:

    npm run build
  16. Проверьте, что сборка успешно завершена — файл dist/backup-service.js создан:

    cat dist/backup-service.js

5. Настройте запуск сервиса как systemd-службы

На этом шаге вы настроите автоматический запуск сервиса резервного копирования через systemd.

  1. Создайте конфигурацию службы:

    sudo nano /etc/systemd/system/backup-service.service
  2. Вставьте следующее содержимое:

    [Unit]
    Description=Directory Backup Service
    After=network.target
    [Service]
    Type=simple
    User=user1
    Group=user1
    WorkingDirectory=/home/user1/backup-service
    ExecStart=/home/user1/.nvm/versions/node/v20.19.3/bin/node /home/user1/backup-service/dist/backup-service.js
    Environment=NODE_ENV=production
    Environment=CONFIG_PATH=/home/user1/backup-service/config.json
    Restart=always
    RestartSec=10
    StandardOutput=syslog
    StandardError=syslog
    SyslogIdentifier=backup-service
    [Install]
    WantedBy=multi-user.target
  3. Перезапустите менеджер systemd и активируйте службу:

    sudo systemctl daemon-reload
    sudo systemctl enable backup-service
    sudo systemctl start backup-service

    После запуска службы копирование файлов будет автоматически запускаться каждые 10 минут.

  4. Проверьте работоспособность службы:

    sudo systemctl status backup-service

    Ожидаемый результат:

    backup-service.service - Directory Backup Service
    Loaded: loaded (/etc/systemd/system/backup-service.service; enabled; vendor preset: enabled)
    Active: active (running) since Tue 2025-07-15 13:35:55 MSK; 1h 3min ago
    Main PID: 2977 (node)
    Tasks: 11 (limit: 1016)
    Memory: 17.9M
    CPU: 213ms
    CGroup: /system.slice/backup-service.service
    └─2977 /home/user1/.nvm/versions/node/v20.19.3/bin/node /home/user1/backup-service/dist/backup-service.js

    У работающей службы в поле «Active» должно отобразиться значение «active (running)».

  5. Создайте несколько файлов в директории files:

    cd ../files
    touch 1.txt
    touch 2.txt
  6. Проверьте, что резервные копии директории files появляются в директории /backup-disk/backups.

    cd ../../../backup-disk/backups

    Каждая копия хранится в отдельной директории внутри /backup-disk/backups.

  7. Перезагрузите виртуальную машину и убедитесь, что служба автоматически запустилась.

Результат

Вы развернули сервис резервного копирования на NodeJS и systemd в облаке Cloud.ru, освоили управление дополнительным диском и автоматизацию обслуживающих процессов Linux.