Продолжаю продвигать свою реферальную ссылку на IaaS-провайдера Exostate и запиливаю вторую статью своей рекламной кампании. В первой статье я развернул и запустил приложение 'vue-storefront' как отдельный сервер, без привязки к каким-либо данным, маскируя таким нелепым образом свой коммерческий интерес в продажах сервисов Exoscale. Мои жалкие потуги были успешно вскрыты коллегой aol-nnov и я был выведен на чистую воду. Что ж, второй этап моей рекламной кампании по результату не отличается от первого — такая же страница с ошибкой:
Фронт теперь привязан к backend'у ('vue-storefront-api'), но в браузере клиента то же самое безрадостное сообщение "Something went wrong ...". Поэтому я, отбросив ложную скромность, вынес свою реферальную ссылку до ката, а всю маскировку поместил под кат — детали того, каким образом я совмещал "Vue Storefront" с "Vue Storefront API".
Цель
На этом этапе я поставил себе задачу поднять минимально работоспособный backend и замкнуть на него фронт.
Схемка
Чтобы было немного понятнее, привожу картинку, которая у меня сложилась по результатам анализа конфигов приложений:
Последовательность развёртывания vue-storefront
я приводил в предыдущей статье. Таким образом, нужно поднять ещё vue-storefront-api
, Elasticsearch и Redis. Судя по адресу/порту в конфигах за GraphQL отвечает само vue-storefront-api
.
Рабочее окружение
Для этого этапа мне также хватило small-версии сервера Linux Ubuntu 18.04 LTS 64-bit (2x 2198 MHz CPU, 2 GB RAM, 10GB disk). Что приятно в IaaS, так это возможность раз за разом начинать с чистого листа, выкидывая предыдущие неудачные эксперименты в корзину.
Первый этап
Вот скрипт для повторения действий первого этапа:
#!/usr/bin/env/bash
set -e
sudo apt update
sleep 2 # wait 2 second before upgrade to prevent en error
sudo apt upgrade -y
sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install -y nodejs
sudo curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
sudo echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
sudo npm install pm2@latest -g
sudo npm install @vue-storefront/cli@latest -g
# interactive command below: use 'Stable versions' / 'v1.10.4' (or latest) / 'Manual installation'
vsf init
Нужно будет глянуть в сторону автоматического развёртывания vue-storefront
, без участия человека. Но пока вот так, с vsf
.
Установка Elasticsearch
# apt install openjdk-11-jre-headless -y
# java -version
openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)
# apt-get install apt-transport-https
# wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
# add-apt-repository "deb https://artifacts.elastic.co/packages/7.x/apt stable main"
# apt update
# apt install elasticsearch -y
Прежде, чем запускать сервис нужно изменить конфигурацию Elasticsearch'а, чтобы можно было достучаться до сервиса снаружи (это не обязательно, но мне так удобнее):
$ sudo nano /etc/elasticsearch/elasticsearch.yml
cluster.name: habr_demo
node.name: exo01
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
discovery.seed_hosts: []
Запуск сервиса:
# service elasticsearch restart
И проверка его работоспособности:
$ curl -X GET "http://localhost:9200/?pretty"
{
"name" : "exo01",
"cluster_name" : "habr_demo",
"cluster_uuid" : "_na_",
"version" : {
"number" : "7.4.2",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96",
"build_date" : "2019-10-28T20:40:44.881551Z",
"build_snapshot" : false,
"lucene_version" : "8.2.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
Установка Redis
# apt install redis-server -y
Так же, как и Elasticsearch, настраиваю Redis на доступность снаружи:
# nano /etc/redis/redis.conf
bind 0.0.0.0
# service redis-server start
Запускаю сервис и проверяю его работоспособность:
# service redis-server start
# redis-cli
> set test "It's working!"
> get test
> exit
Установка vue-storefront-api
$ cd ~
$ git clone https://github.com/DivanteLtd/vue-storefront-api.git
Связывание фронта с backend'ом
Конфигурация фронта
Доступные параметры конфигурации фронта можно посмотреть в ~/vue-storefront/config/default.json
. Я переопределил некоторые параметры в ~/vue-storefront/config/local.json
:
{
"server": {
"host": "0.0.0.0",
"port": 3000
},
"redis": {
"host": "194.182.181.149",
"port": 6379,
"db": 0
},
"graphql": {
"host": "194.182.181.149",
"port": 8080
},
"api": {
"url": "http://194.182.181.149:8080"
},
"elasticsearch": {}
}
server.host|.port
— привязываю nodejs-сервер, который будет выдавать контент для фронта, ко всем доступным ip-адресам на соответствующий порт.
redis
и graphql
— привязываю на внешний ip-адрес своего тестового сервера. Я не знаю, использует ли эти настройки nodejs-сервер, выдающий контент, или эти настройки используются на стороне клиента в браузере, поэтому ставлю внешний адрес.
api.uri
— здесь точно нужно прописывать внешний ip-адрес сервера, т.к. на предыдущем этапе я видел обращения к API из браузера (PWA-приложения) в логах запросов (вкладка Network
в панели инструментов). Это тот адрес-порт, на котором будет висеть nodejs-сервер из приложения vue-storefront-api
.
Конфигурация backend'а
Доступные параметры конфигурации также можно посмотреть в ~/vue-storefront-api/config/default.json
. Вот переопределённые параметры в ~/vue-storefront-api/config/local.json
:
{
"server": {
"host": "0.0.0.0",
"port": 8080
},
"elasticsearch": {
"host": "localhost",
"port": 9200
},
"redis": {
"host": "localhost",
"port": 6379
}
}
server.host|.port
— привязываю nodejs-сервер, который будет выдавать контент для API, ко всем доступным ip-адресам на соответствующий порт.
elasticsearch
и redis
располагаются на том же хосте, что и API-сервер, поэтому я просто повторяю default-параметры.
Сборка приложений
Фронт
$ cd ~/vue-storefront
$ yarn install
$ yarn build
Backend
$ cd ~/vue-storefront-api
$ yarn install
$ yarn build
Запуск и остановка приложений
$ cd ~/vue-storefront-api
$ yarn start
...
$ cd ~/vue-storefront
$ yarn start
...
[PM2][WARN] Applications server not running, starting...
[PM2] App [server] launched (4 instances)
┌──────────┬────┬─────────┬──────┬────────┬─────────┬────────┬───────┬───────────┬────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├──────────┼────┼─────────┼──────┼────────┼─────────┼────────┼───────┼───────────┼────────┼──────────┤
│ api │ 0 │ fork │ 3690 │ online │ 0 │ 11s │ 0% │ 85.2 MB │ ubuntu │ disabled │
│ o2m │ 1 │ fork │ 3696 │ online │ 0 │ 11s │ 0% │ 48.4 MB │ ubuntu │ disabled │
│ server │ 2 │ cluster │ 3763 │ online │ 0 │ 0s │ 26.7% │ 66.9 MB │ ubuntu │ disabled │
│ server │ 3 │ cluster │ 3770 │ online │ 0 │ 0s │ 0% │ 68.1 MB │ ubuntu │ disabled │
│ server │ 4 │ cluster │ 3785 │ online │ 0 │ 0s │ 0% │ 40.9 MB │ ubuntu │ disabled │
│ server │ 5 │ cluster │ 3796 │ online │ 0 │ 0s │ 0% │ 40.9 MB │ ubuntu │ disabled │
└──────────┴────┴─────────┴──────┴────────┴─────────┴────────┴───────┴───────────┴────────┴──────────┘
Use `pm2 show <id|name>` to get more details about an app
Done in 1.49s.
Останов:
$ pm2 stop all
Просмотр логов:
$ pm2 log
Подключение к приложению
Адрес приложения: http://194.182.181.149:3000/ В результате в браузере имеем сообщение об ошибке, приведённое в самом начале, но зато в логах API-сервера можем фиксировать обращения браузера к API:
$ pm2 log
3|server | 2019-11-16 07:44:33: Error during render : /
3|server | 2019-11-16 07:44:33: Error: FetchError in request to ES: FetchError: invalid json response body at http://194.182.181.149:8080/api/catalog/vue_storefront_catalog/product/_search?_source_exclude=%2A.msrp_display_actual_price_type%2Crequired_options%2Cupdated_at%2Ccreated_at%2Cattribute_set_id%2Coptions_container%2Cmsrp_display_actual_price_type%2Chas_options%2Cstock.manage_stock%2Cstock.use_config_min_qty%2Cstock.use_config_notify_stock_qty%2Cstock.stock_id%2Cstock.use_config_backorders%2Cstock.use_config_enable_qty_inc%2Cstock.enable_qty_increments%2Cstock.use_config_manage_stock%2Cstock.use_config_min_sale_qty%2Cstock.notify_stock_qty%2Cstock.use_config_max_sale_qty%2Cstock.use_config_max_sale_qty%2Cstock.qty_increments%2Csmall_image%2Csgn%2C%2A.sgn&from=0&request=%7B%22query%22%3A%7B%22bool%22%3A%7B%22filter%22%3A%7B%22bool%22%3A%7B%22must%22%3A%5B%7B%22terms%22%3A%7B%22category.name.keyword%22%3A%5B%22Tees%22%5D%7D%7D%2C%7B%22terms%22%3A%7B%22visibility%22%3A%5B2%2C3%2C4%5D%7D%7D%2C%7B%22terms%22%3A%7B%22status%22%3A%5B0%2C1%5D%7D%7D%5D%7D%7D%7D%7D%7D&size=8&sort=created_at%3Adesc reason: Unexpected end of JSON input
3|server | at w (core/server-entry.ts:23:25)
3|server | at server-bundle.js:1:468554
3|server | at processTicksAndRejections (internal/process/task_queues.js:93:5)
3|server | 2019-11-16 07:44:33: whole request [/error]: 56ms
0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/create?token= 204 1.320 ms - 0
0|api | 2019-11-16 07:44:34: POST /api/cart/create?token= 200 465.416 ms - 56
0|api | 2019-11-16 07:44:34: OPTIONS /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 204 0.239 ms - 0
0|api | 2019-11-16 07:44:34: GET /api/cart/pull?token=&cartId=35bea3b7dcf8fb841187d69489fe8c51 200 103.949 ms - 24
Заключение
Удалось продвинуться ещё на шаг вперёд — Vue Storefront PWA общается с Vue Storefront API. Далее нужно разбираться с наполнением backend'а. Какие данные индексируются в Elasticsearch, как они туда попадают и как извлекаются.
Спасибо за прочтение и кликайте по моей реферальной ссылке. Я ж, блин, ради неё тут всё это наворотил.