Runway
Runway is built and operated in the EU!

Network / LAN

Application’s that are created by the same user can talk to each other using private DNS hosts. An example where this may come in handy is if you decided to go another way and have a frontend NodeJS-based application, that needs to talk to a (private) backend service written in Golang.

App to app

Create the two applications on Runway:

cd my-frontend/
runway app create -a my-frontend
cd my-backend
runway app create -a my-backend
runway app route off

Now you have two applications — each coming from their own repository. Configure the deployment (if you must) and runway app deploy in each repository.

How does it work?

In your frontend application, you want to talk to the my-backend application, so let’s do this. For this example, we are going to use a framework that supports fetch on the server, so let’s go with SvelteKit:

// src/routes/backend/+page.server.js.ts
const url = 'http://my-backend.my-backend.svc.cluster.local'
export const load = async ({ params }) => {
	return {
		data: await fetch(`${url}/something`)
	}
}

To test:

curl https://my-frontend.pqapp.dev/backend/

Now, the backend service is not exposed and all requests to /something must be proxied through the NodeJS application.

Aside from proxying requests through other applications, this also enables network related fun, if you think of e.g. running a Tinyauth or an OAuth-Proxy to secure all your applications in private.

Tailscale

Another option is to use Tailscale, especially if you plan to integrate your Runway application with other servers that could be running in your homelab or anyway on the planet!

We have an entire guide for Tailscale, so check it out!