New

Just launched: Vueblocks, a brand-new search engine for Vue packages! Explore Vueblocks →

tombroucke/otomaties-deployer

Deploy roots/bedrock & roots/sage to Combell, Runcloud.
1,764 6
dev
Install
composer require tombroucke/otomaties-deployer
Latest Version:3.4.1
PHP:^8.0
Laravel:4 – 13
Last Updated:Oct 30, 2026
Links: GitHub  ·  Packagist
Maintainer: tombroucke

Otomaties Deployer

Installation

composer require tombroucke/otomaties-deployer --dev

Options

Use dep deploy production --skip-ssl-verify to deploy a website without a SSL certificate

Example deploy.php file

<?php

namespace Deployer;

use function Otomaties\Deployer\runWpQuery;

require_once __DIR__ . '/vendor/autoload.php';
require_once 'contrib/cachetool.php';
require_once 'recipe/composer.php';

(\Dotenv\Dotenv::createImmutable(__DIR__))
    ->load();

collect([
    'functions.php',
    'recipes/auth.php',
    'recipes/bedrock.php',
    'recipes/combell.php',
    'recipes/composer.php',
    'recipes/database.php',
    'recipes/htaccess.php',
    'recipes/opcode.php',
    'recipes/otomaties.php',
    'recipes/sage.php',
    'recipes/wordfence.php',
    'recipes/wp.php',
])
    ->map(fn ($file) => __DIR__ . '/vendor/tombroucke/otomaties-deployer/' . $file)
    ->filter(fn ($file) => file_exists($file))
    ->each(fn ($file) => require_once $file);

/** Config */
set('application', 'example.com');
set('repository', 'git@github.com:username/example.com.git');

/** Sage */
set('sage/build_command', 'build'); // build:production for mix
set('sage/theme_path', 'app/themes/example');

/** WP */
set('wp/languages', [
    'nl_NL',
]);

/** Hosts */
host('production')
    ->set('hostname', 'ssh###.webhosting.be')
    ->set('url', 'https://example.com')
    ->set('remote_user', 'examplecom')
    ->set('branch', 'main')
    ->set('deploy_path', '/data/sites/web/examplecom/app/main');

host('staging')
    ->set('hostname', 'ssh###.webhosting.be')
    ->set('url', 'https://staging.example.com')
    ->set('basic_auth_user', env('BASIC_AUTH_USER'))
    ->set('basic_auth_pass', env('BASIC_AUTH_PASS'))
    ->set('remote_user', 'examplecom')
    ->set('branch', 'staging')
    ->set('deploy_path', '/data/sites/web/examplecom/app/staging');

/** Check if everything is set for sage */
before('deploy:prepare', 'sage:check');

/** Install theme dependencies */
before('deploy:vendors', 'sage:vendors');

/** Upload auth.json */
before('deploy:vendors', 'composer:upload_auth_json');

/** Remove auth.json */
after('deploy:vendors', 'composer:remove_auth_json');

/** Push theme assets */
after('deploy:update_code', 'sage:compile_and_upload_assets');

/** Write revision to file */
after('deploy:update_code', 'otomaties:write_revision_to_file');

/** Reload Combell */
after('deploy:symlink', 'combell:reloadPHP');

/** Clear OPcode cache */
after('deploy:symlink', 'combell:reset_opcode_cache');

/** Install languages */
after('deploy:symlink', 'wp:install_languages');

/** Optimize the site */
after('deploy:symlink', 'otomaties:custom:optimize');

/** Remove unused themes */
after('deploy:cleanup', 'wp:remove_unused_themes');

/** Unlock deploy */
after('deploy:failed', 'deploy:unlock');

/** Optimize the site */
desc('Optimize the site');
task('otomaties:custom:optimize', function () {
    runWpQuery([
        'wp core update-db',
        // 'wp wc update',
        'wp acorn optimize',
        'wp cfcache purge_cache',
    ]);
});

Languages

Languages should be excluded from your git repo and installed during deploy with wp:install_languages.

Runcloud Hub

/** Update dropin */
after('deploy:symlink', 'wp:runcloud-hub:update-dropin');

task('wp:runcloud-hub:update-dropin', function () {
    runWpQuery('wp runcloud-hub update-dropin');
});
/** Purge all caches */
after('deploy:symlink', 'wp:runcloud-hub:purgeall');

task('wp:runcloud-hub:purgeall', function () {
    runWpQuery('wp runcloud-hub purgeall');
});

To clear the opcode cache on a runcloud server, you need to add cachetool_args. E.g.:

set('cachetool_args', '--web=SymfonyHttpClient --web-path={{deploy_path}}/current/web --web-url={{url}}');

WordPress

/** Flush object cache */
after('deploy:symlink', 'wp:cache:flush');

task('wp:cache:flush', function () {
    runWpQuery('wp cache flush');
});

WooCommerce

/** Update WooCommerce tables */
after('deploy:symlink', 'wp:wc:update');

task('wp:wc:update', function () {
    runWpQuery('wp wc update');
});

Extra commands

Initial setup

dep combell:host_symlink production
Create bedrock .env file
dep bedrock:create_env staging
Enable basic auth on host:
dep auth:password_protect staging
Add repository authentication to remote server
dep composer:add_remote_repository_authentication

GitHub Actions

Full setup in one command

Runs all steps below in order: deploy key, composer auth, Dependabot secrets, and basic auth (prompted if not in .env).

dep github:setup production
Set up deploy key and store as GitHub Actions secrets
dep github:deploy-key production

If SSH keys on the host are managed in a hosting control panel (e.g. Combell) instead of ~/.ssh/authorized_keys, enable manual mode. The public key is printed so you can add it in the control panel, and the command waits for your confirmation before testing it. When you rotate the key, remove the old one from the control panel yourself.

host('production')
    ->set('github_deploy_key_manual', true);

Or for a single run:

dep github:deploy-key production -o github_deploy_key_manual=true
Store composer auth.json as the COMPOSER_AUTH Actions secret
dep github:composer-auth
Store composer registry credentials as Dependabot secrets

Reads auth.json and sets <HOSTNAME>_USERNAME / <HOSTNAME>_PASSWORD as Dependabot secrets for each http-basic registry entry. Required for Dependabot to access private Composer registries.

dep github:dependabot-composer-auth
Store basic auth credentials as the DEPLOY_BASIC_AUTH Actions secret
dep github:basic-auth production

Security

Setup Wordfence firewall for Bedrock / deployer
dep wordfence:firewall_setup
Set default Wordfence configuration

You can overwrite the default config

/** Wordfence */
set('wordfence/config', get('wordfence/config')
    ->merge([
        'alertEmails' => 'info@example.com',
        'max_login_failures' => '3',
        'max_forgot_password' => '3',
    ])
);
dep wordfence:default_configuration
Add .htaccess rules for security
dep htaccess:add_all_rules

Database handling

Pull database from production
dep wp:db:pull production
Download database
dep wp:db:download production
Push database to staging
dep wp:db:push staging

WordPress

WP CLI
dep wp:cli
Install packages
dep wp:cli --cmd="wp package install {package_name}"
dep wp:cli --cmd="wp package install tombroucke/wp-rocket-cli" # Install WP Rocket CLI package
dep wp:cli --cmd="wp package install aaemnnosttv/wp-cli-login-command" # Install login package
Flush Object Cache
dep wp:cli --cmd="wp cache flush" # Flush cache
Capabilities
dep wp:cli --cmd="wp user add-cap {login} edit_theme_options" # Allow user to update theme options
dep wp:cli --cmd="wp cap add editor edit_theme_options" # Allow editor to update theme options
dep wp:cli --cmd="wp cap add editor manage_instagram_feed_options" # Allow editor to manage smash balloon instagram feed
dep wp:cli --cmd="wp cap add editor gform_full_access" # Allow editor access to Gravity Forms
Login
dep wp:cli --cmd="wp login create {login}" # Create login
Set admin email
dep wp:cli --cmd="wp option update admin_email {emailaddress} --autoload=yes" # Create login

Upgrading

From v1.x to v2.x

There is a script included to automatically update from v1.x to v2.x. Require this script in your old deploy.php script, and we will try to fix the file automatically. Run dep after adding this line.

require 'vendor/tombroucke/otomaties-deployer/update/2.x.php';

Related Packages

soloterm/solo

A Laravel package to run multiple commands at once, to aid in local development.

580,667 1,288
dev
googee/laravel-builder

Laravel Builder

4,151 6
dev
maarheeze/boost-guidelines

laravel boost integration for .ai guidelines

2,369 3
dev
carloeusebi/php-artisan-make-action

A Package that adds the php artisan make:action command

1,241 1
dev
laravel/roster

Detect packages & approaches in use within a Laravel project

47,687,206 167

Version History

Version Released PHP Laravel License
3.4.1 ^8.0 *
3.4.0 ^8.0 *
3.3.0 ^8.0 *
3.2.0 ^8.0 *
3.1.0 ^8.0 *