Представьте, что вы запускаете новый сервер, и уже через несколько минут он полностью настроен и готов к работе — без малейшего ручного вмешательства. Звучит невероятно? Но это реальность благодаря инструменту cloud-init. Эта технология позволяет автоматически конфигурировать сервер сразу после запуска, передав все необходимые параметры через специальный конфигурационный файл. В результате система сама установит нужные пакеты, настроит веб-сервер, обновит ОС и даже запустит ваше приложение — всё это без участия администратора.

В сервисе RX-NAME возможности cloud-init доступны прямо в личном кабинете. Вы можете воспользоваться ими в несколько кликов, что делает развёртывание серверов максимально быстрым, надёжным и удобным как для разработчиков, так и для бизнеса.

Примеры использования user-data

Многие IT-ресурсы приводят примеры того, как передавать конфигурационные данные (user-data) при запуске виртуальной машины для автоматической настройки сервера. Часто в таких случаях используются скрипты, которые устанавливают и настраивают веб-сервер NGINX, инсталлируют Node.js и запускают веб-приложения. Такой подход позволяет сразу задать все необходимые параметры безопасности, конфигурацию обратного прокси-сервера и автоматический запуск приложения. В результате существенно сокращается время вывода продукта на рынок.

Что такое cloud-init и почему это важно?

Cloud-init — это универсальный инструмент для автоматической инициализации облачных серверов. Он позволяет выполнять целый ряд задач:

  • Установка пакетов и обновлений. С помощью cloud-init сервер сразу получает все нужные утилиты (например, curl, git, apt-transport-https) для подготовки системы к работе.
  • Настройка веб-сервера NGINX. Автоматически создаются конфигурационные файлы для безопасной работы NGINX и корректного проксирования запросов к приложению.
  • Установка Node.js и зависимостей. Скрипт проверяет наличие нужных версий Node.js и npm, при необходимости обновляет их и устанавливает зависимости проекта.
  • Автоматический запуск приложения. С помощью systemd можно добавить unit-файл, который будет запускать ваше приложение как сервис. Это обеспечивает его стабильную работу и автоматический перезапуск в случае сбоя.

Благодаря этим возможностям cloud-init устраняет человеческий фактор, снижает вероятность ошибок при настройке и значительно ускоряет развёртывание серверов. Подробнее о функциях и преимуществах cloud-init читайте в нашем блоге (мы подготовили отдельный материал на эту тему).

Пример скрипта cloud-init для установки Svelte-приложения

Рассмотрим реальный пример: приведённый ниже конфигурационный файл cloud-init выполняет автоматическое развёртывание и настройку веб-сервера, Node.js и самого приложения на Svelte. Пройдёмся по этапам:

  1. Установка базовых пакетов. В секции packages указаны утилиты (curl, git, apt-transport-https), которые нужно установить на старте. Это гарантирует наличие на сервере всех инструментов для загрузки ключей, добавления репозиториев и клонирования проектов.
  2. Создание конфигурационных файлов. С помощью директивы write_files скрипт создаёт несколько конфигурационных файлов:
    • Сниппет HTTP-заголовков безопасности для NGINX: набор настроек для защиты от XSS, clickjacking и т.д.
    • Конфигурация сайта по умолчанию: простая страница для проверки работы NGINX (без прокси).
    • Конфигурация обратного прокси для Svelte-приложения: сервер перенаправляет запросы на приложение, работающее на порту 8080.
    • Тестовая HTML-страница: подтверждает корректную работу веб-сервера.
    • Unit-файл systemd: обеспечивает автоматический запуск и перезапуск приложения.
  3. Выполнение команд (runcmd). В этом блоке перечислены команды, пошагово настраивающие сервер:
    • Проверка наличия NGINX и Node.js: скрипт определяет наличие и версии.
    • Подключение репозитория и установка NGINX: добавляется официальный репозиторий и устанавливается последняя версия.
    • Установка Node.js 20: при отсутствии или устаревании — инсталляция актуальной версии.
    • Клонирование и сборка Svelte-приложения: проект скачивается с GitHub, устанавливаются зависимости, настраиваются права доступа.
    • Запуск через systemd: сервис запускается и проверяется его доступность.
    • Активация конфигурации прокси в NGINX: включается svelte_app_proxy, отключается default, перезапускается сервер.
#cloud-config
packages:
- curl
- git
- apt-transport-https

write_files:
# Сниппет заголовков безопасности для nginx
- path: /etc/nginx/snippets/security-headers.conf
  permissions: '0644'
  content: |
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header Cache-Control "no-cache, no-store, max-age=0, must-revalidate" always;
    add_header Pragma "no-cache" always;

# Конфигурация nginx для страницы по умолчанию (без проксирования)
- path: /etc/nginx/sites-available/default
  permissions: '0644'
  content: |
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name localhost;
        root /var/www/html;
        index index.html index.htm;
        location / {
            try_files $uri $uri/ =404;
            include /etc/nginx/snippets/security-headers.conf;
        }
    }

# Конфигурация nginx для проксирования запросов к Svelte-приложению
- path: /etc/nginx/sites-available/svelte_app_proxy
  permissions: '0644'
  content: |
    server {
        listen 80;
        server_name localhost;
        location / {
            proxy_pass http://127.0.0.1:8080;
            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;
            include /etc/nginx/snippets/security-headers.conf;
        }
    }

# Простая страница по умолчанию для проверки работы nginx
- path: /var/www/html/index.html
  permissions: '0644'
  content: |
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>NGINX Test</title>
      </head>
      <body>
        <h1>Добро пожаловать в NGINX!</h1>
        <p>NGINX работает корректно!</p>
      </body>
    </html>

# Unit-файл systemd для запуска Svelte-приложения
- path: /etc/systemd/system/svelte-app.service
  permissions: '0644'
  content: |
    [Unit]
    Description=Svelte Application Service
    After=network.target

    [Service]
    WorkingDirectory=/var/www/svelte-app
    ExecStart=/usr/bin/npx sirv public --no-clear --dev --host 127.0.0.1 --port 8080
    Restart=always
    User=www-data
    Environment=NODE_ENV=production

    [Install]
    WantedBy=multi-user.target

runcmd:
- |
    LOG_FILE="/var/log/cloud-init-custom.log"
    echo "[$(date)] *** Запуск скрипта cloud-init ***" >> ${LOG_FILE}

    # Проверка наличия nginx и Node.js/npm
    if command -v nginx >/dev/null 2>&1; then
        INSTALLED_NGINX=$(nginx -v 2>&1)
        echo "[$(date)] NGINX уже установлен: ${INSTALLED_NGINX}" >> ${LOG_FILE}
    else
        echo "[$(date)] NGINX не найден" >> ${LOG_FILE}
    fi

    if command -v node >/dev/null 2>&1; then
        NODE_VER=$(node -v)
        echo "[$(date)] Node.js уже установлен: ${NODE_VER}" >> ${LOG_FILE}
    else
        echo "[$(date)] Node.js не найден" >> ${LOG_FILE}
    fi

    if command -v npm >/dev/null 2>&1; then
        NPM_VER=$(npm -v)
        echo "[$(date)] npm уже установлен: ${NPM_VER}" >> ${LOG_FILE}
    else
        echo "[$(date)] npm не найден" >> ${LOG_FILE}
    fi

    # Добавление репозитория и установка NGINX
    echo "deb http://nginx.org/packages/ubuntu/ ${UBUNTU_CODENAME:-jammy} nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
    echo "deb-src http://nginx.org/packages/ubuntu/ ${UBUNTU_CODENAME:-jammy} nginx" | sudo tee -a /etc/apt/sources.list.d/nginx.list
    curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
    sudo apt-get update >> ${LOG_FILE} 2>&1
    sudo apt-get install -y nginx >> ${LOG_FILE} 2>&1
    echo "[$(date)] Установлен NGINX: $(nginx -v 2>&1)" >> ${LOG_FILE}

    # Установка Node.js 20
    if command -v node >/dev/null 2>&1; then
        CURRENT_NODE=$(node -v | sed 's/v//')
        if [ "$(printf '%s\n' "20.0.0" "$CURRENT_NODE" | sort -V | head -n1)" = "20.0.0" ]; then
            echo "[$(date)] Node.js актуальной версии ($CURRENT_NODE)" >> ${LOG_FILE}
        else
            curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - >> ${LOG_FILE} 2>&1
            sudo apt-get install -y nodejs >> ${LOG_FILE} 2>&1
        fi
    else
        curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - >> ${LOG_FILE} 2>&1
        sudo apt-get install -y nodejs >> ${LOG_FILE} 2>&1
    fi

    # Проверка npm
    if ! command -v npm >/dev/null 2>&1; then
        echo "[$(date)] Ошибка: npm не установлен" >> ${LOG_FILE}
        exit 1
    fi

    # Тест работы NGINX по умолчанию
    sudo systemctl restart nginx
    if ! sudo systemctl is-active --quiet nginx; then
        echo "[$(date)] Ошибка запуска nginx" >> ${LOG_FILE}
        exit 1
    fi

    HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1)
    if [ "$HTTP_CODE" -ne 200 ]; then
        echo "[$(date)] Страница по умолчанию не отдала HTTP 200" >> ${LOG_FILE}
        exit 1
    fi

    # Установка Svelte-приложения
    SVELTE_DIR="/var/www/svelte-app"
    if [ ! -d "${SVELTE_DIR}" ]; then
        sudo git clone https://github.com/sveltejs/template ${SVELTE_DIR} >> ${LOG_FILE} 2>&1
        sudo chown -R www-data:www-data ${SVELTE_DIR}
    fi

    cd ${SVELTE_DIR}
    if [ -f package.json ]; then
        npm install >> ${LOG_FILE} 2>&1
    else
        echo "[$(date)] Файл package.json не найден" >> ${LOG_FILE}
        exit 1
    fi

    # Запуск Svelte через systemd
    sudo systemctl daemon-reload
    sudo systemctl enable svelte-app.service >> ${LOG_FILE} 2>&1
    sudo systemctl start svelte-app.service
    sleep 5

    if ! sudo systemctl is-active --quiet svelte-app.service; then
        echo "[$(date)] Ошибка запуска Svelte-приложения" >> ${LOG_FILE}
        exit 1
    fi

    SVELTE_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8080)
    if [ "$SVELTE_CODE" -ne 200 ]; then
        echo "[$(date)] Приложение не отдало HTTP 200" >> ${LOG_FILE}
        exit 1
    fi

    # Активация прокси для Svelte в nginx
    sudo mkdir -p /etc/nginx/sites-enabled
    sudo ln -sf /etc/nginx/sites-available/svelte_app_proxy /etc/nginx/sites-enabled/svelte_app_proxy
    sudo rm -f /etc/nginx/sites-enabled/default

    if ! grep -q "include /etc/nginx/sites-enabled/*;" /etc/nginx/nginx.conf; then
        sudo sed -i '/include \/etc\/nginx\/conf.d\/\*.conf;/a include /etc/nginx/sites-enabled/*;' /etc/nginx/nginx.conf
    fi

    sudo systemctl restart nginx

    PROXY_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1)
    if [ "$PROXY_CODE" -ne 200 ]; then
        echo "[$(date)] Ошибка: nginx не проксирует корректно" >> ${LOG_FILE}
        exit 1
    fi

    echo "[$(date)] *** Установка и настройка завершена ***" >> ${LOG_FILE}

final_message: "Cloud-init завершён. Проверьте лог /var/log/cloud-init-custom.log для деталей."

Svelte vs Nuxt vs Next: сравнение фреймворков

При выборе фреймворка для фронтенд-разработки многие разработчики рассматривают Svelte, Nuxt или Next. Каждый из них имеет свои плюсы и минусы.

Svelte

Преимущества:

  • Компилируется в чистый JavaScript без виртуального DOM, создавая лёгкие и быстрые приложения.
  • Минимум кода и высокая читаемость — проще разрабатывать и поддерживать.
  • Интуитивно понятный синтаксис, низкий порог входа.

Недостатки:

  • Относительно небольшая экосистема и число готовых решений.
  • Меньше обучающих материалов и примеров по сравнению с Nuxt и Next.

Nuxt

Преимущества:

  • Основан на Vue.js — популярен среди знакомых с Vue-разработчиков.
  • Поддерживает серверный рендеринг (SSR) и генерацию статических сайтов.
  • Активное сообщество, развитая экосистема плагинов и модулей.

Недостатки:

  • Более сложная конфигурация и оптимизация, чем у Svelte.
  • Может требовать больше ресурсов на разработку и поддержку.

Next

Преимущества:

  • Основан на React — огромная поддержка и множество готовых компонентов.
  • Отличная интеграция SSR и статической генерации страниц.
  • Подходит для крупных проектов.

Недостатки:

  • Может быть слишком «тяжёлым» для малых проектов, где важна простота.
  • Более сложные настройки по сравнению с Svelte.

Выводы

Автоматическая настройка серверов с помощью cloud-init позволяет значительно ускорить развёртывание и конфигурацию инфраструктуры. С его помощью можно не только установить необходимые пакеты и настроить веб-сервер, но и развернуть приложение на современном фреймворке Svelte.

По сравнению с Nuxt и Next, Svelte выигрывает за счёт простоты, компактности кода и высокой производительности. Однако для более масштабных проектов чаще выбирают Nuxt или Next из-за развитой экосистемы и дополнительных возможностей.

Благодаря интеграции cloud-init в личном кабинете сервиса RX-NAME, вы получаете мощный инструмент автоматизации, который помогает быстро и безопасно запускать проекты. Попробуйте этот подход и убедитесь, насколько он упрощает процесс разработки и развёртывания. Для получения дополнительной информации о возможностях cloud-init и других решениях — загляните в наш блог.