Wormhole

At Fly, we've crafted a powerful companion to help you deliver your applications. Wormhole provides you with end-to-end encryption and enables seamless service discovery and power of two random choices load balancing.

It's open source!

Why Wormhole?

The Fly global network of edge servers terminates SSL as close to your users as possible; given the multiple trips required for the HTTPS handshake, this can speed up the user's initial connection. The implied danger is that after terminating SSL at the edge, your data is exposed. Wormhole is our solution to that problem.

With Wormhole, data arrives at the application encrypted and is never exposed within the datacenter or to the greater Internet. It does not bounce around a far-reaching CDN. It's true end-to-end encryption. As the Wormhole sits right next to your application, anytime you add it to a backend it will provide immediate discovery and evenly route visitor traffic.

Together with Wormhole, Fly becomes the fastest and more secure way of delivering your applications to a global user-base.

Sound good? Let's get started!

Usage

Environment Variables

You will first need to setup your environment.

Variable   Description
FLY_TOKEN required Your Fly.io backend token
FLY_LOCAL_ENDPOINT or FLY_PORT optional Local server to tunnel for. (defaults to 127.0.0.1:5000)
FLY_REMOTE_ENDPOINT optional Tunnel server endpoint (defaults to Fly.io's)
FLY_RELEASE_ID_VAR optional ENV name with current released version of your web server (inferred from git if available)
FLY_RELEASE_DESC_VAR optional ENV name with commit message of the current released version of your web server (inferred from git if available)

Running the agent

There are two ways of using the Fly agent:

  • As a Supervisor of your application processes.
  • Alongside your application processes.

Whichever way you choose, you'll need to make sure the Wormhole port is aligned to your application's listening port.

Supervisor

This mode allow you to run a single command to run both the agent and your web server. Each operation system signals will be forwarded to your web server. Logs will be outputted to STDOUT and STDERR respectively, as-is.

Note: When using the supervisor, make sure to set the $FLY_PORT environment variable.

wormhole <your server command>
Examples
Rails
wormhole bundle exec rails server -p $FLY_PORT
Node.js
wormhole npm start
Go
wormhole app

Alongside

It is also possible to run the agent alongside your web server. This requires management of multiple processes.

# In a session
PORT=5000 <your web server command>

# In another session
FLY_TOKEN=x FLY_LOCAL_ENDPOINT=127.0.0.1:5000 wormhole

Ideally, you'll want to run this with a process supervisor (like foreman, supervisord, runit, etc.) Here's how it might look with Foreman:

web: web_server
wormhole: wormhole
Examples
Rails
web: bundle exec rails server -p $FLY_PORT
wormhole: wormhole
Node.js
web: npm start
wormhole: wormhole

Heroku

Heroku runs apps inside dynos with single user-specified commands.

There are two ways of configuring a Heroku app with the Fly Agent:

  • As a Supervisor of your application processes.
  • Alongside your application processes.

Alongside

To run Fly alongside your application, add the Fly buildpack:

heroku buildpacks:add https://github.com/superfly/fly-heroku-buildpack

Then, add your backend's auth token:

heroku config:set FLY_TOKEN=<TOKEN_FOR_YOUR_BACKEND>

Finally, deploy your changes:

git push heroku master

That's it! Your Fly backend should now be proxying traffic to your Heroku app.

Once your app is set-up within Fly, you can stop the ingress traffic to your dyno by changing the process name in the Procfile from web to something else. This changes your dyno into worker dyno.

Supervisor

In case you don't want to run multiple buildpacks, you can just use the Fly Agent as the supervisor of your app process.

This mode allow you to run a single command to run both the agent and your web server. Every operation system signal will be forwarded to your web server. Logs will be outputted to STDOUT and STDERR respectively, as-is.

Add your backend's auth token:

heroku config:set FLY_TOKEN=<TOKEN_FOR_YOUR_BACKEND>

Add Fly Agent binary to your project's repo (e.g. bin/), then modify the Procfile:

web: bin/wormhole <your server command>

Done!

Docker

Docker is omnipresent in modern infrastructures, therefore it's only natural to want to run the Fly Agent within a docker container.

Given the convention of running a single process per Docker container, the solution is to use the supervisor mode of the Fly Agent.

Entrypoint

If you do not already define an ENTRYPOINT, this is the easiest way of running the Fly Agent.

Assuming the agent binary is checked in with your code under bin/wormhole:

# ...
COPY . /app

ENTRYPOINT ["/app/bin/wormhole"]

CMD ["server", "command"]

If you prefer to download the agent on the fly:

# ...
ADD https://github.com/superfly/wormhole/releases/download/0.5.36/pkg/wormhole_linux_amd64 /wormhole
RUN chmod +x /wormhole

ENTRYPOINT ["/wormhole"]
# ...

Command

Given you already use an ENTRYPOINT, it is preferrable to prepend your command with the Fly Agent binary like:

# ...
CMD ["wormhole", "server", "command"]

Separate container

Our agent is published as a lightweight (< 10 MB) container image on hub.docker.com/r/flyio/wormhole. Therefore, it can be pulled and use that way:

docker run -e FLY_TOKEN=x -e FLY_LOCAL_ENDPOINT=linked_container:5000 flyio/wormhole:0.5.36

Kubernetes

Kubernetes has a concept of pods which may run many containers. Those containers share the network interfaces amongst themselves. That means you can use a local port from one container in another container of the same port.

Configuration

To configure a pod with our agent, you'll want to do something like this:

# ...
spec:
  # ...
  containers:
    # Your web server container
    - env:
      # ...

    # Fly Agent container
    - env:
      - name: "FLY_TOKEN"
        value: "x"
      - name: "FLY_LOCAL_ENDPOINT"
        value: "127.0.0.1:5000" # Your application's port
    image: "flyio/wormhole:0.5.36"
    name: "wormhole"
  # ...