Plugins
Introduction
Vito supports plugins to extend its functionality and integrate with various services.
Plugins can be used to add new features or change the behavior of existing ones.
What can Plugins Do?
Plugins can change or extend the following features:
- Server Providers: Add support for new server providers or modify existing ones.
- Storage Providers: Integrate with new storage providers or modify existing storage functionalities.
- Source Controls: Integrate with new source control systems or modify existing source control functionalities.
- Notification Channels: Integrate with new notification channels or modify existing ones.
- Services: Add new services or modify existing ones.
- Site Types: Add new site types or modify existing ones.
- Site Features: Add new site features or modify existing ones.
Installing and Managing Plugins
Vito offers official and community plugins. Official plugins are developed and maintained by the Vito team, while community plugins are developed by the community.
Install
Official and Community tabs to browse and install plugins.Enable
Installed tab in the Admin > Plugins section. Click on the three dots on the right side of the plugin and then click on Enable.Disable
Disabling a plugin will stop it from being booted by Vito. However the plugin's code will still live in your Vito instance and you can enable it again.
Uninstall
If you don't need a plugin anymore, you can uninstall it. Uninstalling a plugin will remove its code from your Vito instance.
Plugin Development
Creating a Plugin
Plugins are basically code extensions that are installed via Vito's plugin management system.
app/Vito/Plugins directory and will be a part of the Vito application.Local Setup
app/Vito/Plugins/YourGithubUsername/YourRepoName and Vito will discover your plugin.my-username/my-vito-plugin, the directory must be app/Vito/Plugins/MyUsername/MyVitoPlugin and the namespace of your plugin must be App\Vito\Plugins\MyUsername\MyVitoPlugin.Plugin.php
Plugin.php file in its root directory which extends the App\Plugins\AbstractPlugin class.Plugin.php must implement the boot method where you can register your plugin's features.Example:
<?php
namespace App\Vito\Plugins\RichardAnderson\LaravelOctanePlugin;
use App\Plugins\AbstractPlugin;
use App\Plugins\RegisterSiteFeature;
use App\Plugins\RegisterSiteFeatureAction;
use App\Vito\Plugins\RichardAnderson\LaravelOctanePlugin\Actions\Disable;
use App\Vito\Plugins\RichardAnderson\LaravelOctanePlugin\Actions\Enable;
class Plugin extends AbstractPlugin
{
protected string $name = 'Laravel Octane Plugin';
protected string $description = 'Laravel Octane plugin for VitoDeploy';
public function boot(): void
{
RegisterSiteFeature::make('laravel', 'laravel-octane')
->label('Laravel Octane')
->description('Enable Laravel Octane for this site')
->register();
RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'enable')
->label('Enable')
->handler(Enable::class)
->register();
RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'disable')
->label('Disable')
->handler(Disable::class)
->register();
}
}Discover Plugins
Admin > Plugins section in the Vito web interface and then Discover tab.Your new plugin should be listed there and you can install it from there.
Error Handling
Admin > Plugins section.You can also see the stack trace of the error by viewing the error logs of a plugin to debug it.
Register site types
By registering a site type, you can add a new type of site that can be created in Vito.
App\Plugins\RegisterSiteType to register a new site type using the boot method of your Plugin.php file.\App\Plugins\RegisterSiteType::make('symfony')
->label('Symfony')
->handler(SymfonyHandler::class)
->form(\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('php_version')
->component()
->label('PHP Version'),
\App\DTOs\DynamicField::make('web_directory')
->text()
->label('Web Directory')
->placeholder('For / leave empty')
->description('The relative path of your website from /home/vito/your-domain/'),
]))
->register();handler method should point to a class that extends App\SiteTypes\AbstractSiteType or implements
App\SiteTypes\SiteType.Register site features and actions
Every site can have multiple features and every feature can have multiple actions.
Laravel Octane which has actions like Enable and Disable.App\Plugins\RegisterSiteFeature in the boot method of your Plugin.php file.Vito allows you to register a feature to a site with actions or register actions to an already existing feature.
// register feature
\App\Plugins\RegisterSiteFeature::make('laravel', 'laravel-octane')
->label('Laravel Octane')
->description('Enable Laravel Octane for this site')
->register();
// register actions for the feature
\App\Plugins\RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'enable')
->label('Enable')
->form(\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('alert')
->alert()
->label('Alert')
->description('Make sure you have already set the `OCTANE_SERVER` in your `.env` file'),
\App\DTOs\DynamicField::make('port')
->text()
->label('Octane Port')
->default(8000)
->description('The port on which Laravel Octane will run.'),
]))
->handler(Enable::class)
->register();
\App\Plugins\RegisterSiteFeatureAction::make('laravel', 'laravel-octane', 'disable')
->label('Disable')
->handler(Disable::class)
->register();You can define forms when you're registering a site feature or inside the site feature action. It is recommended to use the action form as you will have access to the site object.
App\SiteFeatures\FeatureInterface interface.App\SiteFeatures\Action class or implement the App\SiteFeatures\ActionInterface
interface.Register server features and actions
Servers can also have features and feature actions.
App\Plugins\RegisterServerFeature in the boot method of your Plugin.php file.Vito allows you to register a feature to a server with actions or register actions to an already existing feature.
// register feature
\App\Plugins\RegisterServerFeature::make('opcache')
->label('OPCache')
->description('Enable OPCache for PHP')
->register();
// register actions for the feature
\App\Plugins\RegisterServerFeatureAction::make('opcache', 'enable')
->label('Enable')
->form(\App\DTOs\DynamicForm::make([
...
]))
->handler(Enable::class)
->register();
\App\Plugins\RegisterServerFeatureAction::make('opcache', 'disable')
->label('Disable')
->handler(Disable::class)
->register();App\ServerFeatures\FeatureInterface interface.App\ServerFeatures\Action class or implement the App\ServerFeatures\ActionInterface
interface.Register services
Vito is a service-oriented server management system. By default, it comes with some built-in services like Nginx, MySQL, Redis, etc.
App\Plugins\RegisterService in the boot method of your Plugin.php file.RegisterServiceType::make(Nginx::id())
->type(Nginx::type())
->label('Nginx')
->handler(Nginx::class)
->configPaths([
[
'name' => 'nginx.conf',
'path' => '/etc/nginx/nginx.conf',
'sudo' => true,
],
])
->register();
\App\Plugins\RegisterServiceType::make('php')
->type('php')
->label('PHP')
->handler(PHP::class)
->versions([
'8.4',
'8.3',
'8.2',
'8.1',
'8.0',
'7.4',
'7.3',
'7.2',
'7.1',
'7.0',
'5.6',
])
->data([
'extensions' => [
'imagick',
'exif',
'gmagick',
'gmp',
'intl',
'sqlite3',
'opcache',
],
])
->register();Service Types:
Vito already supports multiple service types, and you can create alternatives for them.
For example, You can create an alternative web server service like Apache. or another database service like SQL server.
Supported service types are:
webserver: Will be used for sitesdatabase: Will be used for databasesmonitoring: Will be used to monitor the servermemory_database: Will be used for in-memory databases like Redis or Memcachedphp: Will be used for PHP versionsnodejs: Will be used for Node.js versionsprocess_manager: Will be used for Workers like Supervisorfirewall: Will be used for firewall services like UFW or CSF
These were the services Vito has built-in web interface for them. You are not limited to these service types, and you can create your own.
Service Handlers:
Depending on your service type, You will need to implement a handler for your service which implements the interface of that service type.
App\Services\Webserver\Webserver
interface or extend the App\Services\Webserver\AbstractWebserver class.Service Config Files
configPaths method. Vito will allow you to modify these files in the Services page.App\Services\ServiceInterface interface or extend the
App\Services\AbstractService class.Register server providers
Vito already covers the most popular server providers like DigitalOcean, AWS, Vultr, Hetzner etc.
boot method in your Plugin.php file.\App\Plugins\RegisterServerProvider::make('hetzner')
->label('Hetzner')
->handler(Hetzner::class)
->form(
\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('token')
->text()
->label('API Token'),
])
)
->defaultUser('root') // The default ssh user of the server that the provider will create
->register();App\ServerProviders\ServerProvider interface or extend the
App\ServerProviders\AbstractServerProvider class.Register storage providers
Vito supports multiple storage providers like S3 compatible, FTP, etc.
App\Plugins\RegisterStorageProvider in the boot method of your Plugin.php file.\App\Plugins\RegisterStorageProvider::make('local')
->label('Local')
->handler(Local::class)
->form(
\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('path')
->text()
->label('Path'),
])
)
->register();App\StorageProviders\StorageProvider interface or extend the
App\StorageProviders\AbstractStorageProvider class.Register source controls
Vito supports multiple source control providers like GitHub, GitLab, etc.
App\Plugins\RegisterSourceControl in the boot method of your Plugin.php file.\App\Plugins\RegisterSourceControl::make('github')
->label('GitHub')
->handler(GitHub::class)
->form(
\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('token')
->text()
->label('Personal Access Token'),
])
)
->register();App\SourceControls\SourceControl interface or extend the
App\SourceControls\AbstractSourceControl class.Register notification channels
Vito supports multiple notification channels like Email, Slack, etc.
App\Plugins\RegisterNotificationChannel in the boot method of your Plugin.php file.\App\Plugins\RegisterNotificationChannel::make('slack')
->label('Slack')
->handler(Slack::class)
->form(
\App\DTOs\DynamicForm::make([
\App\DTOs\DynamicField::make('webhook_url')
->text()
->label('Webhook URL'),
])
)
->register();App\NotificationChannels\NotificationChannel interface or extend the
App\NotificationChannels\AbstractNotificationChannel class.Register Workflow Actions
App\Plugins\RegisterWorkflowAction in the boot method of your Plugin.php file.Events
Service installation and uninstallation this way you can tweak/extend the installation process, for example by modifying configuration files or setting up database tables/records.boot method of your Plugin.php file:use App\Events\ServiceInstalled;
use App\Events\ServiceUninstalled;
class Plugin extends AbstractPlugin
{
public function boot()
{
Event::listen('service.installed', function (Service $service) {
// Do something when the service is installed
Log::info("Service installed: {$service->id}");
});
Event::listen('service.uninstalled', function (Service $service) {
// Do something when the service is uninstalled
Log::info("Service uninstalled: {$service->id}");
});
}
}Store Service Data
type_data property to store any additional data you need, don't forget to honor other's properties when mutating it.Dynamic Fields
Dynamic fields are a set of input fields designed to collect inputs from the action forms. They can be used in site creation, site feature actions, and every other part that Vito enables you to extend.
Here are the list of supported fields:
- Label
- Text field
- Checkbox
- Select field
- Alert (with types: info, warning, error, success)
- Link
App\DTOs\DynamicField::classHooks
install, uninstall, enable and disable of plugins. This means, if you implement these methods in your Plugin.php, they will be called when the respective action is performed.Example:
<?php
class Plugin extends AbstractPlugin
{
protected string $name = 'Name';
protected string $description = 'Description';
public function boot(): void
{
//
}
public function enable(): void
{
//
}
public function disable(): void
{
//
}
public function install(): void
{
//
}
public function uninstall(): void
{
//
}
}Register Commands
If your plugin wants to register any console commands, you need to register them via the RegisterCommand helper, as per below;
RegisterCommand::make(FetchCommand::class)->register();Register Views
If your plugin needs to register any views to use within it's implementations, you will need to register these views with a unique name via the RegisterViews helper;
RegisterViews::make('vitodeploy-reverb')
->path(__DIR__.'/views')
->register();Publishing a Plugin
vitodeploy-plugin topic to it.Versioning
Plugins are using Github tags and releases for versioning.
Updating Plugins
Admin > Plugins section in the Vito web interface and then click on the Check for updates button. If there was an available update, you will be able to click on Update on every plugin's dropdown to update it.