В этой заметке хотел показать как можно реализовать метод деплоя vue.js - проекта на обычный shared-хостинг.

Сама схема достаточно примитивная, и работает в полуавтоматическом режиме. С кодом работаем и храним через гитлаб. Редактируем и собираем проект непосредственно на своем ноуте, собираем в виртуальном окружении. Билд заливаем с виртуалки на shared хостинг по ftp (большинство хостингов позволяют это сделать).

vue-schemes (Схема реализации)

Virtualbox, vagrant

В этом проекте, я буду использовать vagrant в связке с virtualbox, чтобы быстро готовить рабочее виртуальное окружение.

Для установки virtualbox, достаточно добавить репозиторий с ключем, и запустить установку пакета.

Листинг команд:

# Добавляем репозиторий
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/oracle-virtualbox-2016.gpg] https://download.virtualbox.org/virtualbox/debian $(lsb_release -cs) contrib" >> /etc/apt/sources.list
# Добавляем ключ
$ wget -O- https://www.virtualbox.org/download/oracle_vbox_2016.asc | sudo gpg --dearmor --yes --output /usr/share/keyrings/oracle-virtualbox-2016.gpg
# Обновляем список репозиториев и ставим virtualbox. 
$ apt-get update && apt-get install virtualbox-6.1

Для установки вагранта в ubuntu используется одна команда.:

$ sudo apt-get install vagrant -y && vagrant plugin install vagrant-env

Софт для работы с виртуалками готов. Теперь стоит задача, подготовить виртульную машину которая будет собирать наше приложение и выкладывать его на хостинг. Для этого напишем Vagrantfile - это некий манифест, где мы описываем состояние нашей виртуалки, которое хотим видить после запуска.

В вагрантфайле, через shell-провижининг укажем команды, которые будут выполняться процедурно при запуске виртуалки. В корне нашего проекта создаем Vagrantfile:

Vagrant.configure("2") do |config|
    config.env.enable
    config.vm.box = "generic/ubuntu2004"
    #config.vm.synced_folder "./", "/var/www/vuejs-onshared/"

    config.vm.provision "shell", inline: <<-SHELL
       apt-get update && apt-get updgrade -y
       apt install nodejs npm git lftp -y

       # install gitlab runner
       curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
       apt-get install gitlab-runner

       echo ${git_token}
       # register gitlab runner
       gitlab-runner register \
            --non-interactive \
            --url #{ENV['GITLAB_URL']} \
            --registration-token #{ENV['GITLAB_TOKEN']} \
            --executor #{ENV['GITLAB_EXEC']} \
            --description "vagrant vm shell executer" \
            --tag-list #{ENV['GITLAB_TAG']}
    SHELL
  end

В описании вагрантфайла, мы берем ubuntu 20.04, и через шелл провижинг ставим зависимости, устанавливаем gitlab-runner и регистрируем его в нашем проекте.

Создаем файлик .env, который будет содержать переменные с настройками подключения гитлаб-раннера к проекту:

# Vagrant vars:
GITLAB_URL = "https://gitlab.com/"
GITLAB_TOKEN = "<TOKEN>"
GITLAB_EXEC = "shell"
GITLAB_TAG = "vagrant-vm"

Приготовления завершены, запускаем vagrant и идем пить чай, пока накатываются изменения.

$ vagrant up            

По завершению, можем проверить зареганный раннер в гитлабе: vuejs-gitlabrunner.png

Сборка и Deploy

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

Итак, идем на наш хостинг и создаем новый домен: vuejs-shared.png

Во вкладке - FTP users, добавляем пользователя для подключения к хостингу: vuejs-shared-ftp.png

В течении некоторого времени доменное имя уже будет доступно. А пока идем в гитлаб и создадим несколько секретов, в значении которых укажем настройки ftp-подключения. В Gitlab на странице проекта проваливаемся в Settings > CI/CD, находим раздел - Variables и создаем переменные: vuejs-gitlab-vars.png

В корне проекта создаем .gitlab-ci.yml файл, в котором опишем инструкции для сборки, и выгрузки проекта. Наш CI, будет состоять из двух этапов (stages): build, deploy.

stages:
  - build
  - deploy

Далее описываем джоб (job), для сборки проекта:

build-job:      
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    when: on_success
    expire_in: 2 days
    paths:
      - "dist/"
  tags:
    - vagrant-vm

В контексте script - выполняется два действия:

  • npm install - Установка зависимостей;
  • npm run build - Сборка проекта.

Блок artifacts сохраняет в артифакты, всю собранную статику в каталоге - dist/. В тегах (tags) указывается тег раннера.

Описываем второй джобу для второго этапа, выкладки проекта:

deploy-job:
  stage: deploy
  script:
    - lftp -u $FTP_USER,$FTP_PASSWD $FTP_SERVER -e "set ftp:ssl-allow no; mirror -R dist/ /; quit"
  tags:
    - vagrant-vm
  needs:
    - build-job

Здесь мы выполяем одно действие в script, через улититу lftp синхронизируем локальный каталог dist/ c каталогом на сервере (по умолчанию, это каталог с сайтом). $FTP_USER,$FTP_PASSWD, $FTP_SERVER - переменные, которые мы создавали на раннем этапе. Далее также указываем тег с раннером. И в поле needs, включаем зависимость текущей джобы от джобы build-job. То есть джоба деплоя не запуститься, при проваленной джобе по сборки.

Полный листинг файла - .gitlab-ci.yml:

stages:
  - build
  - deploy

build-job:      
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    when: on_success
    expire_in: 2 days
    paths:
      - "dist/"
  tags:
    - vagrant-vm

deploy-job:
  stage: deploy
  script:
    - lftp -u $FTP_USER,$FTP_PASSWD $FTP_SERVER -e "set ftp:ssl-allow no; mirror -R dist/ /; quit"
  tags:
    - vagrant-vm
  needs:
    - build-job

В данном CI у нас нет тестов, что не есть хорошо. В любом более серьезном проекте важно прописывать различные тесты и линт кода.

Сохраняем файл, и проваливаемся в раздел - CI/CD -> Pipelines. vuejs-gitlab-ci.png

Как видно из статуса джоба, все выполнилось. Теперь мы можем проверить, рабоспособность сайта: vuejs-website.png

Применение на практике

В этом разделе продемонстрируем процесс работы всего конвейера. Представьте, что бы работаем над сайтом и нам потребовалось внести какие либо измения на сайте. Например мы хоти поменять главную кнопку в хедере: vuejs-website-exam1.png

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

$ git pull

Через vagrant запускаем виртуальное окружение для сборки проекта:

$ vagrant up --provider=libvirt      

Дожидаемся завершения прошлого процесса, и приступаем работать с кодом. Отредактируем файл - info.js, поменяем строку: vuejs-website-exam2.png

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

$ git add info.js 
$ git commit -m "Change logo name in info.js"
$ git push

Через пару минут можем прочекать гитлаб, задачи по последнему коммиту были выполнены: vuejs-website-exam3.png

Теперь смотрим сайт, изменения также были применены. vuejs-website-exam4.png

Дополнительные ссылки