Search by

tombroucke / otomaties-deployer

tombroucke

There is no license information available for the latest version (3.4.0) of this package.

Deploy roots/bedrock & roots/sage to Combell, Runcloud.

Package info

github.com/tombroucke/otomaties-deployer

pkg:composer/tombroucke/otomaties-deployer

Statistics

Installs: 1 718

Dependents: 1

Suggesters: 0

Stars: 6

Open Issues: 1

3.4.0 2026-10-13 07:54 UTC

README

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

Symlink hosts on Combell

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

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

GitHub Actions

The recipes/github.php recipe provides tasks for wiring up GitHub Actions deployments.

Deploy key

Generates a fresh ed25519 key, authorises it on the target host(s), stores it as the DEPLOY_SSH_KEY and SSH_KNOWN_HOSTS Actions secrets, and registers it as a read-only deploy key on the repo. Safe to re-run — re-running rotates the key.

Requirement: gh CLI logged in (gh auth login) with admin access to the repo.

dep github:deploy-key production

Settings

// Default: derived from the `repository` setting
set('github_deploy_key_repo', 'owner/repo');

// Set to true when SSH keys are managed in a hosting control panel (e.g. Combell)
host('production')->set('github_deploy_key_manual', true);

Or pass it as a one-off option:

dep github:deploy-key production -o github_deploy_key_manual=true

Composer auth

Stores the project-level auth.json as the COMPOSER_AUTH Actions secret. The global ~/.composer/auth.json is intentionally ignored.

dep github:composer-auth

Basic auth

Reads BASIC_AUTH_USER and BASIC_AUTH_PASS from your local .env and stores them as the DEPLOY_BASIC_AUTH Actions secret (user:pass format). Used so the deploy workflow can make authenticated HTTP requests to a password-protected staging site.

dep github:basic-auth

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';