elpd

elpd

Fusion - run Elixir code on remote servers via SSH, no deployment needed

Ten years ago I got curious: what would a Chef/Ansible-like tool look like built entirely in Elixir? One that uses Erlang distribution instead of agents installed on remote machines.

I got most of it working — SSH tunnels, remote BEAM bootstrap, transparent clustering. But in the last piece, full code loading I run out of time. Life happened. The project sat.

A few weeks ago I picked it back up. Finished the bytecode pushing and dependency resolution with some AI assist, cleaned it up to newer utilities and shipped it in a day.

What it does

Connect to a remote server over SSH, push your modules, run them. No deployment. No pre-installed app on the remote. Just SSH access and Elixir.

target = %Fusion.Target{
  host: "10.0.1.5",
  port: 22,
  username: "deploy",
  auth: {:key, "~/.ssh/id_ed25519"}
}

{:ok, manager} = Fusion.NodeManager.start_link(target)
{:ok, remote_node} = Fusion.NodeManager.connect(manager)

# Run your own modules remotely — dependencies are pushed automatically
{:ok, result} = Fusion.run(remote_node, MyApp.Worker, :process, [data])

When you call MyApp.Worker remotely, Fusion reads the BEAM bytecode, walks the dependency tree, and pushes everything the module needs. No manual tracking.

Why build this

Back then it was mainly for curiosity. The idea was that instead of python or ruby, you can run Elixir on remote machines without a full deployment pipeline. Ad-hoc tasks across a fleet. Provisioning. One-off diagnostics. Interactive remote exploration.

Fusion gives you that without leaving Elixir.

How it works (the short version)

  • 3 SSH tunnels bridge Erlang distribution through firewalls — two reverse, one forward
  • Remote BEAM bootstrap starts Elixir on the remote with flags that route all traffic through the tunnels
  • Bytecode pushing transfers compiled .beam binaries (not source) with automatic dependency resolution

Zero runtime dependencies. ~700 lines of Elixir.

Deep dive articles

I wrote a three-part series covering the internals:

  1. Running Elixir on Remote Servers with Fusion — hands-on tutorial
  2. How Fusion Works: Tunnels and Distribution — SSH tunnel architecture
  3. How Fusion Works: Bytecode Pushing — dependency resolution and code loading

Links

https://github.com/elpddev/fusion

Feedback welcome

This is a POC. I do not plan using it in prod anytime soon. If someone find this interesting I’d love to hear your thoughts. API design, use cases I haven’t considered, rough edges. Maybe someone will find this useful.

Most Liked

AndyL

AndyL

I dislike Ansible but have not been able to find a better replacement. So I’m rooting for you!

For design inspiration, you might like to review the work done on JetPorch, a deploy tool by Michael DeHaan, the original Ansible developer. DeHaan worked on this project for a year-ish, then abandoned the project. But IMO his design was very good! You can find the archived JetPorch repo here: ~mpdehaan/jetporch - the Jet Enterprise Professional Orchestrator - sourcehut git

adam12

adam12

This looks great!

I rewrote one of my older applications just recently which is an IaaS platform similar to Linode/DO/etc. I originally had it as Ruby orchestrator + a Go sidecar deployed to each hypervisor, but when I brought it over to Elixir/Phoenix I ended up using SSH as the transport for simplicity, with nothing running on the hypervisor.

I looked at doing something similar to Fusion but I couldn’t completely crack the problem. I wanted to keep things simple, but I definitely made a few compromises in the journey.

I’m going to check this out in depth once I get a free moment.

Where Next?

Popular in Announcing Top

alisinabh
Hey everyone i’ve developed a library for Jalaali calendar for elixir which supports converting Gregorian dates to Jalaali and vice vers...
New
danschultzer
In short Plug n’ play OAuth 2.0 provider library. Just set up a resource owner schema with Ecto (your user schema), install the dependen...
New
treble37
Just looking for a little feedback on a tiny helper library I built - Sometimes I find the need to convert maps with atom keys to maps w...
New
josevalim
Hi everyone, We would like to announce that Plataformatec is working on a new MySQL driver called MyXQL. Our goal is to eventually integ...
New
maltoe
Hello! Came here to announce ChromicPDF, a pet project PDF generator I’ve been working on for the past few months. Why another PDF gener...
New
oltarasenko
Dear Elixir community, After a year of development, bug fixes, and improvements, we are proudly ready to share the release of Crawly 0.1...
New
restlessronin
The repo is at GitHub - cyberchitta/openai_ex: Community maintained Elixir library for OpenAI API · GitHub. Docs are at OpenaiEx User Gu...
152 10796 134
New

Other popular topics Top

vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49266 226
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New

We're in Beta

About us Mission Statement