Как сделать автоматический деплой веб-сервиса на поддомен?
Есть веб-приложение, написанное на Laravel, использующее типичный стек: PHP, Apache, Nginx, MariaDB.
Сейчас работает одна копия, все правки загружаются через FTP.
Я хочу начать его масштабировать. Каждую копию веб-приложения делать доступной на поддомене.
Можно пойти по стандартному пути - в панели управления хостинга создавать вручную хост и через FTP выгружать копию туда, создавать вручную БД, сделать импорт дампа и т. д.
Но когда будет условно 100 копий, это будет непросто. Плюс постоянно потребуются обновления кода с копированием измененных файлов сразу на 100 хостов.
Условно, хочу настроить систему так, чтобы нажать одну кнопку, вести имя поддомена и сразу создавалась копия приложения. Так же с кодом. Чтобы по нажатию одной кнопки измененные файлы копировались на все хосты.
Какие посоветуете технологии, которые упростят и автоматизируют этот процесс? Что почитать на эту тему?
Дополнительно:
1. Вы уверены, что вам нужна именно полная копия для каждого поддомена? И по отдельному хостингу для каждой копии?
2. Миграции на БД вы как накатываете?
3. Вы используете шаред-хостинг?
Миграции на данный момент делаю экспортомимпортом дампа через phpmyadmin
Использую VPS, на который установлена панель управления сервером
Вместе со 100500 загруженного файла, которое из-за мультиаккаунта размазано ровным слоем по storage, например.
Заложить такую архитектуру, чтобы при необходимости отпочковать 1 клиента на отдельных сервер - возможно. Стоит ли это делать - вопрос к автору.
Потому что пока их можно по пальцам пересчитать - будет и кастомизация под каждого, и разброд по своим сайтам, и большой процент пустышек, которые пришли-не понравилось-ушли, а все их добро можно уверенно удалять с концами.
Если же клиенты десятками - тут уже не до пляски перед каждым, все стандартизуется и оптимизируется под быстрое обновление, если что.
В принципе разные задачи.
Просто я предполагал, что уже существуют готовые решения, которые в пару кликов создают копии хостов и позволяют легко их обновлять. Но судя по ответам, ничего такого нет. Видимо придется по старинке писать bash скрипты под линукс, которые всю эту магию будут делать.
Просто я предполагал, что уже существуют готовые решения, которые в пару кликов создают копии хостов и позволяют легко их обновлять.
1. application.tgz
2. образ виртуальной машины
3. docker-image
выбирай на свой вкус.
Кастомизация под каждого и разброд - не самый лучший подход. Лучше кастомизацию делать таким образом, чтобы код везде был одинаковым, и только конфигурация, которая хранится отдельно, включала/выключала фичи - упрощает обновление.
По тому, что написал ТС, вообще непонятно, зачем ему разделять единый сайт.
Ответы:
Если нормально сформулировать вопрос, то речь идет о банальном деплое
И автору бы сначала поучиться разворачивать свое единственное приложение, а потом уже начинать мечтать про междупланетный шахматный центр на тыщу инстансов.
При том что задача в общем случае решается элементарно. Добавлением еще одной секции в плейбук того же 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
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для автоматического деплоя веб-сервиса на поддомен, вы можете использовать различные инструменты и сервисы, такие как 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"
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. Не забудьте настроить ваш сервер и веб-сервер соответственно, чтобы он мог обрабатывать запросы на ваш поддомен.