Skip to main content

SSH Multiplexing with ControlMaster

· 6 min read
Anton Medvedev
Deployer Maintainer

A typical Deployer run fires somewhere between twenty and a hundred SSH commands per host. Pull from git, install vendors, run migrations, swap a symlink, restart container, clean up old releases. If each of those opened a fresh SSH connection, deploys would feel painful. They do not, because of a small OpenSSH feature called ControlMaster. This post is about how it works, and how Deployer wires it up.

How Deployer talks to itself

· 6 min read
Anton Medvedev
Deployer Maintainer

When Deployer deploys to ten hosts at once, it does not run ten SSH sessions inside a single PHP process. It spawns ten subprocesses, one per host, and lets them run in parallel. Each subprocess (a "worker") needs to ask the parent (the " master") for things: the current config for its host, permission to ask the user a question, a place to push updated values back to. v8 ships a rewritten version of that master and worker plumbing. This post walks through what is in there, and why.

Problems with escapeshellarg()

· 6 min read
Anton Medvedev
Deployer Maintainer

If you ever passed a user-supplied string into a shell command from PHP, you have probably written something like this:

$cmd = 'grep ' . escapeshellarg($pattern) . ' file.log';
shell_exec($cmd);

It looks right, and most of the time it works. But escapeshellarg() has a few quirks that matter a lot when you are running commands across many hosts, with arbitrary user input, in arbitrary locales. Deployer v8 replaces every internal call to escapeshellarg() with a new quote() function. This post explains why.

Deployer v8

· 5 min read
Anton Medvedev
Deployer Maintainer

After a long road through alpha, beta, and release candidates, Deployer v8 is finally out. This release modernizes the foundations of Deployer, introduces a new recipe format, and tightens up many of the rough edges that accumulated over the v7 cycle.

MAML Recipes

· 4 min read
Anton Medvedev
Deployer Maintainer

Deployer v8 introduces MAML-based recipes as a replacement for YAML, while PHP recipes remain unchanged. This shift raises an important question: why move from YAML to MAML? In this blog post, I will explain the rationale behind this decision.

{
import: ["recipe/common.php"]

hosts: {
"deployer.org": {
remote_user: "deployer"
deploy_path: "~/deployer.org"
}
}

tasks: {
deploy: [
"deploy:prepare"
"deploy:publish"
]

build: [
{ runLocally: "npm run clear" }
{ runLocally: "npm run build" }
]

"deploy:update_code": [
{
upload: {
src: "build/"
dest: "{{release_path}}"
}
}
]
}
}

10 Years of Deployer

· One min read
Anton Medvedev
Deployer Maintainer

It's hard to believe that Deployer has been around for a decade. What started as a small tool, born out of frustration with setting up Ruby for deployment, has now grown into one of the de facto standards for deploying PHP applications. Today, millions of websites rely on Deployer, and over the past ten years, we've powered more than a 1 000 000 000 deployments.

As we look to the future, we're excited about what's coming. We've got a host of new features in the pipeline, all designed to make your deployment process even smoother and more efficient. And after ten years, it's also the perfect time to refresh our look. Here it is, fresh for the next chapter of Deployer.