Как сделать автоматический деплой веб-сервиса на поддомен?

Ссылка скопирована
1 ответ

Есть веб-приложение, написанное на Laravel, использующее типичный стек: PHP, Apache, Nginx, MariaDB.
Сейчас работает одна копия, все правки загружаются через FTP.

Я хочу начать его масштабировать. Каждую копию веб-приложения делать доступной на поддомене.

Можно пойти по стандартному пути - в панели управления хостинга создавать вручную хост и через FTP выгружать копию туда, создавать вручную БД, сделать импорт дампа и т. д.

Но когда будет условно 100 копий, это будет непросто. Плюс постоянно потребуются обновления кода с копированием измененных файлов сразу на 100 хостов.

Условно, хочу настроить систему так, чтобы нажать одну кнопку, вести имя поддомена и сразу создавалась копия приложения. Так же с кодом. Чтобы по нажатию одной кнопки измененные файлы копировались на все хосты.

Какие посоветуете технологии, которые упростят и автоматизируют этот процесс? Что почитать на эту тему?

Дополнительно:

1. Вы уверены, что вам нужна именно полная копия для каждого поддомена? И по отдельному хостингу для каждой копии?
2. Миграции на БД вы как накатываете?
3. Вы используете шаред-хостинг?

  • smilingcheater, были мысли доработать приложение для мультиаккаунтов. На данный момент в приложении заложена архитектура одна компания - одна копия приложения. Возможно, по трудозатратам будет проще настроить развертывание копий, чем дорабатывать архитектуру.

    Миграции на данный момент делаю экспортомимпортом дампа через phpmyadmin

    Использую VPS, на который установлена панель управления сервером

  • alexzen, на мой взгляд, не зная вашей специфики, было бы правильнее доработать приложение, чтобы оно работало с мультиаккаунтами.
  • smilingcheater, а ваш взгляд учитывает пожелание клиента "окей, я у вас распробовал эту систему, а теперь хочу, чтобы вы вынесли мой аккаунт на мой сервер"?
    Вместе со 100500 загруженного файла, которое из-за мультиаккаунта размазано ровным слоем по storage, например.
  • а как же уникальные клиентские хотелки?
  • Adamos, поэтому я и написал "не зная вашей специфики". Целесообразность надо оценивать только зная все особенности, и закладывая риски на такие потенциальные хотелки. И оценивая вероятность таких хотелок. И никто кроме автора вопроса этого не знает.
    Заложить такую архитектуру, чтобы при необходимости отпочковать 1 клиента на отдельных сервер - возможно. Стоит ли это делать - вопрос к автору.
  • Тут даже не какая-то абстрактная специфика, а банальное количество клиентов.
    Потому что пока их можно по пальцам пересчитать - будет и кастомизация под каждого, и разброд по своим сайтам, и большой процент пустышек, которые пришли-не понравилось-ушли, а все их добро можно уверенно удалять с концами.
    Если же клиенты десятками - тут уже не до пляски перед каждым, все стандартизуется и оптимизируется под быстрое обновление, если что.
    В принципе разные задачи.
  • В общем я согласен, пока клиентов мало, можно делать индивидуальный подход и не заморачиваться. Веб-приложение сделано для проведения оффлайн игр в мафию.

    Просто я предполагал, что уже существуют готовые решения, которые в пару кликов создают копии хостов и позволяют легко их обновлять. Но судя по ответам, ничего такого нет. Видимо придется по старинке писать bash скрипты под линукс, которые всю эту магию будут делать.

  • Просто я предполагал, что уже существуют готовые решения, которые в пару кликов создают копии хостов и позволяют легко их обновлять.

    1. application.tgz

    2. образ виртуальной машины

    3. docker-image

    выбирай на свой вкус.

    Кастомизация под каждого и разброд - не самый лучший подход. Лучше кастомизацию делать таким образом, чтобы код везде был одинаковым, и только конфигурация, которая хранится отдельно, включала/выключала фичи - упрощает обновление.

  • У вас кстати не масштабирование как таковое, а клонирование инстанса, если исходный к тому же пустой, то де-факто это называется новая установка. Приложения-то на разных поддоменах независимы!
  • Кто бы ещё автору объяснил, что к масштабированию его вопрос не имеет ни малейшего отношения...
  • Saboteur, кастомизация может быть настолько глубокой, что у разных клиентов общей будет только база.
  • Adamos, Кастомизация может быть какой угодно, если это компенсируется деньгами. В данном конкретном случае я в этом сомневаюсь, поэтому моя рекомендация - не делать кодовую кастомизацию, а реализовать через конфиги, чтобы было легче саппортить
  • Saboteur, в данном - да.
    По тому, что написал ТС, вообще непонятно, зачем ему разделять единый сайт.
  • Ответы:

    Если нормально сформулировать вопрос, то речь идет о банальном деплое
    И автору бы сначала поучиться разворачивать свое единственное приложение, а потом уже начинать мечтать про междупланетный шахматный центр на тыщу инстансов.

    При том что задача в общем случае решается элементарно. Добавлением еще одной секции в плейбук того же Ansible. Что даст автору ту самую заветную "одну кнопку". А точнее две - развернуть новый инстанс и обновить все существующие.

    А если еще внимательнее посмотреть на проблему, то возникает закономерный вопрос - а зачем автору вообще миллион виртуальных хостов, если речь идет о банальных поддоменах? Которые прекрасно реализуются в рамках единственного виртуального хоста. То есть можно либо добавить поддержку субдомена в текущее приложение, либо, на худой конец, сделать multi-tenant приложение, где у каждого поддомена будет своя БД.
    При этом вся кнопка будет заключаться в добавлении имени субдомена в базу данных

    • междупланетный

      межпланетный?

    • Иерокопус Таманский, литературу в школе прогуливал? :)
    • Ипатьев, на тех уроках что я присутствовал, мне рассказывали о другом.

    Технология автоматизации развертывания и доставки контента клиенту в разработке называется CI/CD (Continuous Integration, Continuous Delivery — непрерывная интеграция и доставка).

    На коленке сделанное, но рабочее решение для OctoberCMS - это та же Ларавель, только обернутая админкой.
    Скрипт запускается с двумя аргументами - поддоменом и тем плагином, который добавляется к системе, помимо базового плагина, общего для всех клиентов.
    Проверяется, корректный ли поддомен и не занят ли он, копируется основной код Октября и нужные плагины, создается новая БД под этот конкретный поддомен, ее параметры прописываются в настройки сайта, голым SQL вносится пара поправок, чтобы не лезть за этим в админку, а все остальное выполняет запуск artisan.
    Nginx настроен так, что любая папка внутри /var/www, кроме начинающихся на подчеркивание, отображается на поддомен.
    Добавляем сайт-одностраничник, работающий с сохраненными данными по поддоменам и запускающий на бэке этот скрипт с нужными ключами - и продажник может за минуту соорудить пробник проекта для потенциального клиента, не дергая программиста вообще.

    #!/bin/bash SUB=$1 PLUGIN=$2  if [[ "${SUB}" =~ ^[-0-9a-z]{2,12}$ ]]; then 	FOLDER="/var/www/${SUB}"     if [ ! -d "${FOLDER}" ]; then 		cp -a /var/www/_fish/October "${FOLDER}" 		DB_PASSWORD=`date | md5sum | cut -c1-32` 		DB_NAME=prefix_`echo "$SUB"|sed s/-/_/g` 		DB_USER="${DB_NAME}" 		sed -i "s/#DB_NAME#/${DB_NAME}/g;s/#DB_USER#/${DB_USER}/g;s/#DB_PASSWORD#/${DB_PASSWORD}/g" "${FOLDER}/public/config/database.php" 		ROOT_USER=mysqladmin 		ROOT_PASSWORD=123456 		mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "CREATE DATABASE ${DB_NAME} CHARACTER SET utf8mb4;" 		mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "CREATE USER ${DB_USER}@localhost IDENTIFIED BY '${DB_PASSWORD}';" 		mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';" 		mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "FLUSH PRIVILEGES;" 		cd "${FOLDER}"/public 		php artisan october:up 		ADMIN_PASSWORD=`echo ${DB_PASSWORD} | cut -c1-10` 		ADMIN_HASH=`php -r "echo password_hash('${ADMIN_PASSWORD}', PASSWORD_BCRYPT);"` 		mysql --database=${DB_NAME} -u${DB_USER} -p${DB_PASSWORD} <<-SQL 			UPDATE `backend_users` SET `password` = '${ADMIN_HASH}' WHERE `id` = 1; 			INSERT INTO `system_parameters` SET `namespace` = 'cms', `group` = 'theme', `item` = 'active', `value` = '"theme"'; 			SQL 		/bin/cp -a /var/www/_fish/Plugins/base/public "${FOLDER}" 		/bin/cp -a /var/www/_fish/Plugins/"${PLUGIN}"/public "${FOLDER}" 		php artisan october:up 	else 		echo "Error: Subdomain already used or invalid" 	fi else     echo "Error: Invalid subdomain: " $SUB fi

    #!/bin/bash SUB=$1 PLUGIN=$2 if [[ "${SUB}" =~ ^[-0-9a-z]{2,12}$ ]]; then FOLDER="/var/www/${SUB}" if [ ! -d "${FOLDER}" ]; then cp -a /var/www/_fish/October "${FOLDER}" DB_PASSWORD=`date | md5sum | cut -c1-32` DB_NAME=prefix_`echo "$SUB"|sed s/-/_/g` DB_USER="${DB_NAME}" sed -i "s/#DB_NAME#/${DB_NAME}/g;s/#DB_USER#/${DB_USER}/g;s/#DB_PASSWORD#/${DB_PASSWORD}/g" "${FOLDER}/public/config/database.php" ROOT_USER=mysqladmin ROOT_PASSWORD=123456 mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "CREATE DATABASE ${DB_NAME} CHARACTER SET utf8mb4;" mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "CREATE USER ${DB_USER}@localhost IDENTIFIED BY '${DB_PASSWORD}';" mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';" mysql -u${ROOT_USER} -p${ROOT_PASSWORD} -e "FLUSH PRIVILEGES;" cd "${FOLDER}"/public php artisan october:up ADMIN_PASSWORD=`echo ${DB_PASSWORD} | cut -c1-10` ADMIN_HASH=`php -r "echo password_hash('${ADMIN_PASSWORD}', PASSWORD_BCRYPT);"` mysql --database=${DB_NAME} -u${DB_USER} -p${DB_PASSWORD} <<-SQL UPDATE `backend_users` SET `password` = '${ADMIN_HASH}' WHERE `id` = 1; INSERT INTO `system_parameters` SET `namespace` = 'cms', `group` = 'theme', `item` = 'active', `value` = '"theme"'; SQL /bin/cp -a /var/www/_fish/Plugins/base/public "${FOLDER}" /bin/cp -a /var/www/_fish/Plugins/"${PLUGIN}"/public "${FOLDER}" php artisan october:up else echo "Error: Subdomain already used or invalid" fi else echo "Error: Invalid subdomain: " $SUB fi

    • Очень полезный скрипт, спасибо. Еще с Гитом надо подружить, чтобы все правки автоматом выгружались на хосты.
    • _fish

      что за рыба?

    • Иерокопус Таманский,

      РЫБА, -ы; ж. 3. Разг. То, что подготовлено для кого-л. в качестве предварительного или необходимого материала; заготовка. Доклад ещё не готов, но р. уже есть.

    • Adamos, а, в этом смысле! Ясно.

    Автоматизация с Chef, Ansible, Puppet, Terraform
    Масштабирование - это обычно когда нужно больше машин (горизонтальное) или больше (одинаковых) сервисов на одной машине.

    Есть такая прикольная штука под названием Kubernets. Она все ваши задачи решает в несколько команд. Но, скорее всего, вы не сможете её просто взять и начать использовать.

    • Зачем для таких простых задач брать такого монстра, как Kubernetes?
    • Иерокопус Таманский, потому что:

      Она все ваши задачи решает в несколько команд.

      Что ещё сможет так просто и удобно заменить devops инженера?

    • Ради одного только K8s придётся держать штат таких инженеров. Хотя автору хватило бы и чего-то из Chef, Ansible, Puppet, Terraform. Специалист нужен по-любому. Тогда, возможно, лишь разово работу сделать, а потом только поддержку давать.
    • Griboks, вы хотели сказать, "что еще может послужить основанием нанять команду девопс инженеров?" ;)
    • Иерокопус Таманский, не согласен с вами. Держать кубер не проще обычного докера. А если всё это дело уже в каком-нибудь стандартном облаке, то там вообще одним конфигов всё разворачивается и масштабируется.
    • не согласен с вами. Держать кубер не проще обычного докера.

      я не нигде утверждал, что K8s проще Docker. Как раз, наоборот.

    • Иерокопус Таманский, *не сложнее.
    • Griboks,

      *не сложнее.

      это спорное утверждение.
      https://benchmarks.llmonitor.com/k8s

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Павел Админов Ответ

    Для автоматического деплоя веб-сервиса на поддомен, вы можете использовать различные инструменты и сервисы, такие как GitLab CI/CD, GitHub Actions, Jenkins и другие. В данном примере, я расскажу как настроить автоматический деплой на поддомен с использованием GitLab CI/CD.

    1. Создайте файл .gitlab-ci.yml в корне вашего репозитория. В этом файле опишите шаги, которые необходимо выполнить для деплоя вашего веб-сервиса. Пример файла .gitlab-ci.yml:

    stages:
      - deploy
    
    deploy:
      stage: deploy
      script:
        - echo "Deploying to subdomain"
        - ssh user@your-server "cd /path/to/your/web/service && git pull origin master"

    stages: - deploy deploy: stage: deploy script: - echo "Deploying to subdomain" - ssh user@your-server "cd /path/to/your/web/service && git pull origin master"

    2. Настройте доступ к вашему серверу по SSH. Для этого добавьте открытый ключ вашего GitLab CI/CD в список авторизованных ключей на сервере.

    3. Создайте скрипт на вашем сервере, который будет заниматься деплоем вашего веб-сервиса. В приведенном выше примере, это команда git pull origin master.

    4. Добавьте переменные окружения в настройках проекта GitLab. Например, переменные для доступа к вашему серверу (SSH_USER, SSH_HOST) и путь до вашего веб-сервиса (WEB_SERVICE_PATH).

    5. Запустите пайплайн CI/CD в GitLab. Это можно сделать либо автоматически при каждом коммите в ветку master, либо вручную через веб-интерфейс GitLab.

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

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно