Давайте в этой статье создадим приложение с помощью Shopify CLI на VPS. Начнем с выбора конфигурации хостинга и закончим продакшеном на реально работающем магазине. Естественно, нам необходимо иметь доступ к партнерскому аккаунту Shopify для разработки приложений. И полный доступ к аккаунту с рабочим магазином и devstore.

ЭТАП 1: Создаем VPS на хостинге.

Перед тем, как создавать VPS в облаке, нужно понимать какая конфигурация подойдет для нашего приложения. В нашем случае мы будем использовать самый дешевый вариант, так как это всего лишь пример. Но если делать серьезное приложение, то минимум нужно 2 процессора, 4 GB RAM и 40 GB SSD.

Из коробки Beget предлагает установить Ubuntu 22.04. Этот вариант нас вполне устроит. Так что создаем VPS сервер с дефолтными настройками которые предлагает сервис.

После того, как виртуальный сервер будет создан, на ваш e-mail сервис хостинга отправит пароль для SSH доступа.

ЭТАП 2: Создаем домен и привязываем его к VPS

2.1 Создание домена третьего уровня

Заходим в панель управления хостингом, в данном случае Beget, в раздел «Управление доменами и поддоменами».

Создаем новый домен. У меня уже есть домен второго уровня wtemu.ru, поэтому создаю на его основе домен третьего уровня:

shop-app.wtemu.ru

Привязываем его к созданному VPS серверу. Для этого используем кнопку «Добавить домены». После этого домен третьего уровня будет связан с нашим VPS.


2.2 Проверка привязки через DNS

Убедиться в корректной привязке можно через «Управление записями DNS».

  1. В выпадающем списке выбираем домен-родитель (wtemu.ru).
  2. Скроллим вниз до подзон и записей DNS.
  3. Здесь появится наш поддомен shop-app.wtemu.ru с четырьмя записями: A, MX, MX и TXT.

Для работы нам нужна только A-запись, остальные можно игнорировать.


2.3 Проверка резолва домена на VPS

Следующим шагом проверяем, что домен корректно резолвится в IP VPS.

  1. Заходим на VPS по SSH как root.
  2. Выполняем команду:
ping shop-app.wtemu.ru

Если все сделано правильно, увидите примерно следующее:

root@spurhanwfx:/# ping shop-app.wtemu.ru
PING shop-app.wtemu.ru (31.129.111.75) 56(84) bytes of data.
64 bytes from 31.129.111.75: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 31.129.111.75: icmp_seq=2 ttl=64 time=0.031 ms

Это подтверждает, что домен успешно привязан к VPS и корректно резолвится в IP.

ЭТАП 3: Создаем SWAP файл подкачки, чтобы VPS не падал

3.1 Зачем нужен SWAP

Так как мы создали VPS с минимальной конфигурацией, при повышенной нагрузке могут происходить OOM Kill — когда системе не хватает оперативной памяти. Чтобы этого избежать, создаем файл подкачки (swap). Это обеспечит стабильную работу слабого виртуального сервера.


3.2 Проверка существующего swap

Сначала проверим, не включён ли swap по умолчанию:

free -h

Если в строке Swap все значения равны нулю — swap отсутствует, можно безопасно создавать свой файл.


3.3 Создание swap-файла

Создадим файл подкачки размером 2 ГБ. Самый быстрый способ — через fallocate:

fallocate -l 2G /swapfile

Файл будет располагаться в корне системы и использоваться под swap.

На некоторых файловых системах fallocate может не сработать. В этом случае используем:

dd if=/dev/zero of=/swapfile bs=1M count=2048


3.4 Настройка прав доступа

Swap-файл должен быть доступен только пользователю root, иначе система не примет его:

chmod 600 /swapfile
ls -lh /swapfile

Если всё верно, увидите примерно:

-rw------- 1 root root 2.0G /swapfile


3.5 Превращаем файл в swap

Теперь делаем файл подкачки активным:

mkswap /swapfile
swapon /swapfile

Проверяем подключение:

free -h

Если в выводе отображается 2.0G — swap успешно подключён.


3.6 Автоподключение swap после ребута

По умолчанию после перезагрузки VPS swap отключается. Чтобы подключался автоматически, редактируем файл fstab:

nano /etc/fstab

Добавляем в конец:

/swapfile none swap sw 0 0

Сохраняем файл: Ctrl + O → Enter → Ctrl + X.

Теперь swap будет подключаться при каждом запуске системы.


3.7 Настройка swappiness

Ubuntu по умолчанию активно использует swap, что не всегда хорошо для VPS. Проверим текущее значение:

cat /proc/sys/vm/swappiness

Обычно оно равно 60. Для сервера лучше оставить 10:

sysctl vm.swappiness=10

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

nano /etc/sysctl.conf

В конец файла добавляем:

vm.swappiness=10

Сохраняем: Ctrl + O → Enter → Ctrl + X.


Мы создали swap-файл на 2 ГБ, который:

  • работает сразу,
  • подключается автоматически после перезагрузки,
  • гарантирует стабильную работу VPS при нехватке оперативки.

При необходимости swap можно увеличить или удалить.

ЭТАП 4: Подготовка сервера для корректной работы Shopify CLI на VPS

4.1 Обновление системы

Предполагается, что вы уже зашли на виртуальный сервер по SSH как пользователь root. На первом этапе обновим систему:

apt update && apt upgrade -y

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


4.2 Установка Node.js через официальный репозиторий

Далее нам нужно подготовить корректное Node.js окружение для Shopify CLI и будущего продакшен-приложения. Не используем Node.js из apt, так как там устаревшие версии. Используем официальный репозиторий NodeSource и устанавливаем Node.js LTS (20.x):

curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
apt install -y nodejs

Проверяем версии Node.js и npm:

node -v
npm -v

Обновляем npm до актуальной версии:

npm install -g npm@latest
npm -v


4.3 Установка Git и подготовка инфраструктуры

Для управления проектом и клонирования репозиториев потребуется Git:

apt install -y git
git --version

Далее устанавливаем Nginx и PM2 для управления приложением, а также подготавливаем сервер под боевой домен shop-app.wtemu.ru:

apt install nginx -y
systemctl status nginx

Если всё корректно, статус будет active (running).
После этого при переходе по адресу http://ip_сервера вы должны увидеть стандартную страницу «Welcome to nginx». Это означает, что Nginx работает корректно. Полную настройку конфигурации nginx и подключение сертификатов мы сделаем позже, на этапе подготовки HTTPS.


4.4 Установка PM2 и настройка автозапуска

PM2 нужен для того, чтобы приложение не падало и автоматически перезапускалось. Устанавливаем его глобально:

npm install -g pm2
pm2 -v

Настроим автозапуск, чтобы процессы PM2 перезапускались после reboot:

pm2 startup
pm2 save


4.5 Установка build-essential

Для компиляции зависимостей Node.js и будущих модулей проекта установим build-essential:

apt install -y build-essential


Теперь VPS полностью подготовлен:

  • обновлена система,
  • установлена актуальная версия Node.js,
  • настроен npm,
  • установлен Git,
  • развернут Nginx,
  • установлен PM2 с автозапуском,
  • добавлены системные инструменты для сборки зависимостей.

Сервер готов для развертывания Shopify приложения в dev и продакшен режимах.

ЭТАП 5: Поднимаем приложение в dev режиме

5.1 Подготовка и понимание процесса

Наша задача — подготовить Shopify к работе с приложением, которое будет работать на нашем боевом домене shop-app.wtemu.ru. На этом этапе мы пока не трогаем VPS и код, а сосредоточимся на Shopify и ключевых решениях для разработки.

Важно понимать, что в будущем приложение (в production-версии) будет жить на сервере, иметь домен и устанавливаться в магазин Shopify. Для этого оно сначала создается в Shopify Partner Account в режиме разработки, независимо от того, будет оно публичным или приватным.

Любое приложение создается в Partner Account на тестовом DevStore. После окончания разработки готовое приложение билдят под рабочий магазин. Рабочий магазин принимает только продакшен-код. В режиме разработки ни одно приложение в рабочем магазине работать не будет. Для этого существует DevStore — магазин для разработки и тестирования приложений.

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

Еще один важный нюанс касается scopes: для приватного приложения большинство scopes доступно сразу, но для публичного приложения на многие scopes требуется одобрение Shopify.


5.2 Создание приложения с помощью Shopify CLI на VPS

Создадим приложение с помощью Shopify CLI от имени root. Сначала устанавливаем необходимые утилиты для корректной аутентификации через браузер:

apt-get install xdg-utils
cd /var/www/
npm init @shopify/app@latest

Первая команда устанавливает утилиты для аутентификации, вторая запускает установку окружения shopify@cli и стартового шаблона приложения. В терминале появится ссылка для аутентификации: нужно скопировать её и открыть в браузере, ввести логин и пароль, подтвердить создание приложения. CLI запомнит токен для сервера и продолжит установку с предложением выбрать опции:

? Get started building your app:
Build a React Router app (recommended)

? For your React Router template, which language do you want?
JavaScript

? We recommend installing Shopify CLI globally in your system. Would you like to install it now?
Yes

? Which organization is this work for?
Partner Company Ltd

? Create this project as a new app on Shopify?
Yes, create it as a new app

? App name:
shop-app

После завершения установки в панели DevStore появится новое приложение.


5.3 Настройка Custom Distribution и запуск в dev режиме

В панели разработчика DevStore выберите вкладку Home, затем в правой колонке Select Distribution Method.

Далее выбираем Custom Distribution и подтверждаем. Появится страница с кнопкой Generate Link, которую можно закрыть — на этом этапе ссылка нам не нужна. Благодаря Custom Distribution приложение получает одобрение почти на все scopes для работы с API Shopify.

Возвращаемся в терминал и выполняем команды:

cd /var/www/shop-app
shopify app dev

Эта команда запускает приложение в режиме разработки на VPS, и оно становится доступным в DevStore.

Чтобы открыть приложение, перейдите:

devstore > settings > apps > shop-app > open

Первый раз приложение нужно открыть из раздела devstore → settings → apps. Если всё прошло успешно, откроется стартовое приложение, готовое для дальнейшей разработки и тестирования.

ЭТАП 6: Настройка SSL-сертификатов и Nginx.

Теперь нам нужно создать SSL-сертификаты через Let’s Enscript с помощью модуля CertBot. Сертификаты нужны для HTTPS протокола. Без данного протокола приложение Shopify работать не будет на продакшене.

apt install certbot python3-certbot-nginx -y
certbot --nginx -d shop-app.wtemu.ru

Теперь создай для приложения новый конфиг nginx :

nano /etc/nginx/sites-available/shop-app

И введи ровно такое содержание :

server {
listen 80;
server_name shop-app.wtemu.ru;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name shop-app.wtemu.ru;

ssl_certificate /etc/letsencrypt/live/shop-app.wtemu.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/shop-app.wtemu.ru/privkey.pem;

location / {
proxy_pass http://localhost:3000;
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;
}
}

Включи конфиг:

ln -s /etc/nginx/sites-available/shop-app /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx

Если почему то у вас возникают проблемы то возможны несколько причин:
— нужно убедиться в наличие сертификатов по пути указанному в конфиге;
— проверьте наличие конфига в папке /etc/nginx/sites-enabled/

Проверка:

systemctl status nginx

Открыть браузер:

https://shop-app.wtemu.ru

Если ты видишь 502 BadGateway — все отлично ! Это свидетельствует о правильной настройке Nginx и применении SSL-сертификатов к домену, в нашем случае shop-app.wtemu.ru. Если же ты видишь приветственную страницу Nginx — это скорее всего конфликт конфигураций. Одной из причин может стать задваивание, то есть если ты по какой-то причине(ошибке) дважды указал домен в разных конфигах /etc/nginx/sites-enabled/

ЭТАП 7: Билдим приложение с помощью Shopify CLI на VPS в Production

7.1 Подготовка продакшен-приложения

Сейчас наш домен готов, поэтому мы переходим к настройке приложения для продакшена. Важно понимать, что в рабочем магазине нельзя запускать приложение в режиме разработки. В то же время, в DevStore без проблем можно использовать как build, так и dev-режим. Хотя процесс в целом одинаковый, существует одно ключевое различие: для рабочего магазина необходимо создать новую точку входа (приложение), тогда как для DevStore можно использовать одно и то же приложение для разработки и тестирования build.

Для того чтобы сделать продакшен-версию нашего стартового приложения и запустить её на рабочем магазине, нам нужно получить точку входа для этого магазина. Иными словами, в Admin-панели разработчика рабочего магазина необходимо создать новое приложение, получить клиентский ID и секрет, указать scopes и ввести корректные ссылки:

  • App URLhttps://shop-app.wtemu.ru
  • Scopeswrite_products
  • Redirect URLs["https://shop-app.wtemu.ru/api/auth"]

Нажимаем кнопку Release — это выпустит версию приложения.


7.2 Настройка окружения и подключение к коду

Для доступа к приложению через SSH и редактирования кода понадобится VSCode с расширением SSH Remote. Подключаемся и открываем проект.

Открываем файл shopify.app.toml и корректируем строки:

client_id = "полученный клиент ID"
name = "shop-app"
application_url = "https://shop-app.wtemu.ru"
automatically_update_urls_on_dev = false
scopes = "write_products"
redirect_urls = ["https://shop-app.wtemu.ru/api/auth"]

В режиме разработки приложение берет переменные из ядра, а в продакшене — из файла .env. Поэтому создаем в корне приложения файл .env и прописываем минимальный набор констант:

SHOPIFY_API_KEY=твой_api_key_для_рабочего_магазина
SHOPIFY_API_SECRET=твой_api_secret_для_рабочего_магазина
SCOPES=write_products
SHOPIFY_APP_URL=https://shop-app.wtemu.ru

Убедимся, что в package.json скрипт start настроен на продакшен:

"start": "react-router-serve ./build/server/index.js"

Далее в папке app находим shopify.server.js и сверху вставляем:

import 'dotenv/config';

Эта строка подключит константы из .env файла.

Для удаления возможных битых кэшей Vite выполняем:

rm -rf node_modules/.vite-temp
rm -rf node_modules/.cache

Пересобираем зависимости:

npm install


7.3 Деплой и тестирование билда созданного через Shopify CLI на VPS

Чтобы убедиться, что всё настроено верно, выполняем:

shopify app deploy

Это пересоздаст и переподключит новую актуальную версию приложения. После этого запускаем билд — ошибок быть не должно.

npm run build

Теперь можно запускать процесс через менеджер PM2:

pm2 start npm --name shop-app -- run start
pm2 save
pm2 logs

Если всё прошло успешно, логи будут зелёные.

Следующим этапом мы тестируем работоспособность нашего приложения в работающем магазине. Для этого открываем браузер, вставляем в адресную строку адрес нашего приложения https://app.wtemu.ru и открываем. Если все прошло удачно, в окне браузера откроется страница, в которой будет предложено ввести домен рабочего магазина и залогиниться. Вы будете перенаправлены на страницу авторизации.

После авторизации вы попадете на страницу магазина. Но если ваше приложение не было установлено в панели разработки, то оно не отобразится в боковой панели магазина. Для того, чтобы активировать его, сделайте установку, и откройте приложение пути settings > apps > shop-app. Нажмите три точки напротив приложения в списке и выберите open app. После чего ваше приложение запуститься в рабочем магазине !