/ documentation

Networking & URLs

Every machine gets a live HTTPS URL. Repoint it, publish extra ports, attach your own domain, wire machines together privately.

Your machine's URLs

Each machine is reachable at https://<machine>-<handle>.<content-domain>: machine name, your handle, the platform's content domain. Handle alice, machine app: https://app-alice.ironwire.xyz.

The main URL is served on the standard HTTPS port (443) and forwards to one port inside your machine, 8000 by default. Run a web server on that port and it is live. TLS is handled for you.

Check the current port setup (main URL and published ports) any time:

ssh

$ ssh dashboard@ironwire.sh ports app
443:  https://app-alice.ironwire.xyz → vm port 8000
published: (none)

dashboard

Select the machine and press o (also in the Space actions popup). The ports editor lists the 443 row and every published mapping.

Changing the fronted port

Point the main URL at a different port with ports <name> main <guest-port>. Applies live, no restart. Set it to none to turn the main URL off entirely (the URL then reads unreachable rather than serving an empty page).

ssh

$ ssh dashboard@ironwire.sh ports app main 3000
443:  https://app-alice.ironwire.xyz → vm port 3000
published: (none)

dashboard

Press o on the machine, select the 443 row, press ↵ and type the new guest port, or none to turn the main URL off.

Create without a main URL from the start with create <name> --port=none, or pick the fronted port at creation with --port=<guest>.

Publishing extra ports

Beyond the main URL, publish up to 5 extra HTTPS ports. Each mapping exposes https://<machine>-<handle>.<content-domain>:<public> and forwards it into the machine. The public port must be between 8100 and 9999; the port inside the machine can be anything. TLS handled here too. All port edits apply live.

ssh

$ ssh dashboard@ironwire.sh ports app add 9443:9000
443:  https://app-alice.ironwire.xyz → vm port 3000
published:
  https://app-alice.ironwire.xyz:9443 → vm port 9000

dashboard

Press o on the machine, then a, and type the mapping as 9443:9000.

Publish at creation time with repeatable --publish=<public>:<guest> flags. Remove a mapping with its public port:

ssh

$ ssh dashboard@ironwire.sh ports app rm 9443
443:  https://app-alice.ironwire.xyz → vm port 3000
published: (none)

dashboard

Press o on the machine, select the mapping, and press x.

Both sides of a mapping must be in the range 1 to 65535. Each public port can be used once per machine. A few public ports are reserved by the platform:

Public portWhy it's reserved
443your machine's main URL
22SSH
8080, 8081, 2019platform services

Custom domains

Serve a machine on a domain you own instead of (or alongside) its platform URL. It must be a subdomain like app.example.com, since an apex domain can't be a CNAME.

Set the domain on the machine:

ssh

$ ssh dashboard@ironwire.sh domain app set app.example.com
custom domain app.example.com set for app (pending)
  create a CNAME:  app.example.com  →  app-alice.ironwire.xyz
  it goes live automatically once that resolves

dashboard

Select the machine and press m (also in the Space actions popup), then type the domain and press ↵.

Then add a CNAME record at your DNS provider pointing your domain at the machine's platform hostname shown above. The CNAME itself is the ownership proof: no verification token to copy. The platform checks the record about once a minute and flips the domain to active as soon as the CNAME resolves. Check where things stand any time:

ssh

$ ssh dashboard@ironwire.sh domain app status
custom domain: app.example.com (active)
  CNAME → app-alice.ironwire.xyz

dashboard

The machine list's URL column shows the custom domain, tagged (pending) until it goes active.

Once active, a TLS certificate is issued for your domain and it serves everything the machine exposes: the main URL and any published ports. If the CNAME later stops resolving, the domain drops back to pending until it resolves again.

Remove a custom domain:

ssh

$ ssh dashboard@ironwire.sh domain app rm
custom domain cleared for app

dashboard

Press m on a machine that has a domain; the domain is removed in place.

note Each machine can have one custom domain, and a domain can only be attached to one machine.

Machine-to-machine networking

Machines in the same account reach each other directly on their private IPs, on any port, without publishing anything. Other accounts are blocked both ways: your machines cannot reach theirs, theirs cannot reach yours.

Each machine gets a private 10.0.0.x address, shown in list and info. It is not reachable from the internet. Inside the guest, the hostname is the machine's name, so machines are easy to tell apart from a shell.

You rarely need the address itself: info and the dashboard's actions panel both show the machine's <name>.internal name beside it, and that is the one worth writing down (see below).

$ ssh dashboard@ironwire.sh info app
...
internal: app.internal (10.0.0.2) — reachable by your other machines on any port, by name or address; not reachable from the internet
...

Naming your machines

You do not have to write those addresses down. Every machine answers at <name>.internal from your other machines, using the name you already gave it. Nothing is installed or configured inside the machine to make this work; it is true from the moment one boots.

app$ psql -h db.internal
app$ curl http://api.internal:8000

Write db.internal into your config once and it keeps working. Destroy and recreate db and the name follows it to its new address, with nothing for you to update. A machine can also name itself, so the same config works whichever machine you deploy it to.

The names are private to your account. Someone else can have a machine called db too; their db.internal reaches theirs and yours reaches yours, and neither of you can resolve (or even detect) the other's.

A stopped machine still resolves, and the connection is refused. That tells you it is not running, which is usually what you needed to know; a name that simply vanished would look like a typo.

The .internal suffix is required; a bare db keeps whatever meaning it already had on your machine. These names work only between your machines: they are not on the public internet, and they are not a substitute for your machine's public URL. Everything else your machine looks up resolves exactly as it did before.

Reaching an outpost

Hardware you own and connected as an outpost is reachable the same two ways: a public URL at https://<name>-<handle>.<content-domain>, and privately from your machines at <name>.internal on the ports it published. An outpost that is asleep still resolves; the refused connection is the useful signal, and its URL says plainly that it is offline.

SSH access

Every machine has SSH login: open a shell with connect <name> from the console. See Connecting for details, Machines for the lifecycle, and the command reference for full ports and domain syntax.