There's a clever trick Laravel Forge uses when you click "Deploy" that takes your script, uploads it to a remote server, runs it in the background... and magically knows exactly when it finishes. The script phones home.
Think about it: you hit a button, a few seconds later you see "Deployment complete" with full logs. How does the tool know? It didn't wait for the script because deployments take minutes. It didn't run a daemon watching your server because that's too complex.
The answer is simple. I discovered this while building my own server management tool.
It's built on Unix primitives
Here's the secret: complex deployment tools are built on tools that have existed for decades.
- `scp` to upload files
- `bash` to run scripts
- `nohup` to run processes in the background
- A simple HTTP callback
No magic orchestration layer. No custom daemon. Just composing simple tools elegantly.
Sync execution: Wait and see
Quick operations like testing an SSH connection or adding authorized keys happen synchronously.
The tool creates a script file, uploads it with scp, runs it with bash, waits for completion, and reads the output from a log file. It gets the exit code and returns it to you.
Like ordering coffee at a counter where you wait until it's ready.
Async execution: The clever part
But what about tasks that take minutes? Initial server setup. Database provisioning. App deployments. You can't keep a connection open that long. The browser times out.
Here's where it gets clever.
The tool still creates and uploads the script. But it runs it with nohup, which detaches the process from the terminal. The script runs in the background, and the tool doesn't wait. It immediately returns "Your task is running."
So how does it know when it's done?
The script itself, after completing its work, makes an HTTP request to the tool's API. It reports back: "Hey, I'm done! Here's my exit code and the log output."
The script phones home.
This is the callback mechanism. It's brilliant because there's no process monitoring needed. The tool just sits and listens for incoming calls from scripts it dispatched earlier.
Why the dual model is perfect
Sync for quick checks. Async for long tasks.
The dual execution model solves two different user experience problems elegantly. Your UI stays responsive during long operations, but you get instant feedback for quick verifications. No complex process management. Just simple tools composed thoughtfully.
The next time you use Forge or similar tools, appreciate the cleverness or look under the hood of a tool you use daily and see what you discover.
The best tools make complex problems feel simple by composing simple primitives elegantly.