Хостинг для веб-студии

Пару лет назад, я пришел в местную веб-студию, которая специализировалась на разработке сайтов. У неё был свой небольшой парк дедик серверов, никто ими особенно не занимался. Тогда один менеджер по продажам поинтересовался: “Можем ли мы каким либо образом автоматизировать оплату за хостинг своим клиента, а то получается, что компания забывает выслать счёт клиенту и его сайт годами размещается у нас без оплаты?”

Тут, я конечно же немного “орнул”, компания которая обещала своим клиентам автоматизацию их бизнеса не могла автоматизировать свой.

Под впечатлением, начал размышлять, почти на все сервера поставил хорошо знакомую VestaCP, отличную панель управления хостингом. Тогда начал смотреть её API и реализовывать собственно приложение поверх неё. Очень сильно не понравилась её веб-версия, хаотичный код, который расположен по логической структуре проекта без всякого фреймворка или известных библиотек. Но к моему удивлению API был очень обширный и не документированный, в репозитории просто лежало куча bash файлов который делали только одно действие и назывались соответствующее.

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


Остался клиент.

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

Благодаря клиенту каждый метод контроллера был очень мал:

public function show($name){
return view('user/ftp/index', [
'ftpList' => Vesta::listEditWebDomain($name)
]);
}

Каждый сотрудник мог посмотреть состояние любого сервера или создать домен для конкретного пользователя. (Не знаю, почему разработчики оригинальной панели не пошли по такой модели, но это заметно упрощает поддержку)


Но даже предоставление стандартных возможностей панели казались недостаточными.

В голову пришла идея автоматического развёртывания различных систем правления. Для реализации соединение по SSH отлично пригодилась библиотека поддерживаемая Laravel Collective. Сама установка происходила невидимо для глазу, пользователь ставил задачу установки в очередь, происходило подключение под нужным пользователем и “ВЖУХ” наш сайт уже готов для работы.

/**
* Install WordPress
*/
public function WordPress()
{
SSH::into('Dynamic')->run([
'cd /home/' . $this->user->nickname .
'/web/' . $this->path . '/public_html',
'rm -rf ./*',
'wget ' . $this->cms->last_version,
'unzip master.zip',
'rm master.zip',
'mv WordPress-master/* /home/'
. $this->user->nickname . '/web/'
. $this->path . '/public_html',
'rm -rf WordPress-master',
]);
}

/**
* Install OpenCart
*/
public function OpenCart()
{
SSH::into('Dynamic')->run([
'cd /home/' . $this->user->nickname .
'/web/' . $this->path . '/public_html',
'rm -rf ./*',
'wget ' . $this->cms->last_version,
'unzip master.zip',
'rm master.zip',
'mv opencart-master/upload/* /home/'
. $this->user->nickname . '/web/'
. $this->path . '/public_html',
'rm -rf opencart-master',
]);
}

/**
* Install October
*/
public function October()
{
SSH::into('Dynamic')->run([
'cd /home/' . $this->user->nickname .
'/web/' . $this->path . '/public_html',
'rm -rf ./*',
'wget ' . $this->cms->last_version,
'unzip master.zip',
'rm master.zip',
'mv install-master/* /home/'
. $this->user->nickname . '/web/'
. $this->path . '/public_html',
'rm -rf install-master',
]);
}

Оставалось только соединить написанное приложение с используемой CRM, но перестройка в компании надолго оставила последний этап не завершённым.

Разбирая старые репозитории на GitHub решил выложить написанный клиент для панели управления хостингом в открытый доступ.