# I built a self-hosted deploy tool that looks like tmux (and can be driven by an AI agent)

> Source: <https://dev.to/kield01/i-built-a-self-hosted-deploy-tool-that-looks-like-tmux-and-can-be-driven-by-an-ai-agent-3ldn>
> Published: 2026-10-17 22:22:50+00:00

I deploy a handful of projects to a handful of my own servers. Not enough to justify Kubernetes, too many to keep doing `ssh`, `git pull`, `docker compose up -d` and hoping. I didn't want a PaaS, a cloud control plane, or an agent running on every server.

So I built **[deploy.me](https://github.com/KielD-01/deploy.me)**: a local, Dockerized admin app. You run it on your own laptop (macOS, Linux, or Windows with WSL2) at `https://deployme.localhost`. It reads your servers from `~/.ssh/config`, imports your projects from GitHub or a local folder, and deploys with nothing on the other end but `ssh`, `rsync` and `docker compose`.

It's MIT licensed, and I built it together with Claude. Here's what I think is worth telling about.

A deploy is a pipeline of recorded steps, each with its own log:

`releases/<timestamp>` hard-linked against the live one, shared folders and env files symlinked in, then an atomic switch of `current`.` compose config` first, so a broken file stops the deploy before anything is built. Then build or pull, `pg_dump`, migrations in a one-off container, and `up -d`.
If the gate fails after the switch, **it switches back by itself**. With blue/green on, the edge-facing services start *beside* the running ones, and the old ones are removed only once the new colour is healthy, so a bad deploy costs no downtime.

Early on I asked for a redesign, and ended up with something more committed than a dark mode: the whole app can be a **tmux session**. Panes you split with `Ctrl+b %` and `Ctrl+b "`, a status bar with windows `0:ops 1:runs 2:servers…`, F1–F6 to jump between them, and a shell pane where the real work happens:

``` bash
deploy@local:~$ status
   TARGET                 LIVE     HEALTH            LAST RUN
 ● atelier@edge-fra       94115db  ||||XX|||||||||   #19 ✓
 ● warehouse@edge-fra     9fabf06  ||||||||||||||||  #20 ✓
 4 targets · 0 running · 0 failing
deploy@local:~$ deploy warehouse edge-fra
```

`deploy` is a small wizard: pick the commit, see the plan (what changes, which strategy and why, whether a commit brings a migration), then it asks `y/N`. A flag is never taken as the yes. It's a theme, not a fork: the same Livewire components sit behind a Classic UI with cards and tables, and you switch in Settings.

The first page loads the frame and the shell immediately; the panes that need data (tail, htop, git) load right after, each in its own request.

`php artisan deployme:mcp` is an MCP server over stdio. Point Claude, Cursor or VS Code at it and the agent can look around, explain why a run failed, and plan a deploy. It's **read-only by default**. The tools that change anything (deploy, roll back, cancel) appear only with `--allow-deploys`, and your MCP client asks you before each call. Answers never carry a token, an env file's contents, or the `APP_KEY`.

`UPDATE`, and `DELETE` only inside the nightly prune. Every remote command is in it.
A good part of this was written with Claude Code, and the most useful thing I did was not asking for features. I pointed an agent at the codebase with one rule: **every suspected bug needs a failing test before it gets a fix**. It came back with dozens of fixed bugs, each one proven: a deploy that could run in two workers at once, secrets leaking into a failed step's error text, a health alert that fired on every check instead of on change. A rule that makes the agent show its work turned out to matter more than which model was running.

```
curl -fsSL https://raw.githubusercontent.com/KielD-01/deploy.me/main/install.sh | bash
```

That clones the repo, configures it for your OS, builds, and prints a one-time link to set up a passkey or password. The PHP base image is prebuilt for amd64 and arm64 on Docker Hub, so the first build takes minutes, not a coffee break. `bin/update` keeps it current (backup, rebuild, doctor, and back out if it fails), and can do the patch releases by itself at night if you switch that on.

I'd like to hear what's missing for the way you deploy. Issues and PRs are welcome.
