Skip to Content
Remote AccessConfiguring Ports

Configuring Ports

Define which services your app exposes for remote access by creating a port-template.yml file in the .ironflock/ directory.

Basic Example

ports: - name: Web Interface port: 5000 main: true protocol: https

This makes port 5000 available for remote access. Installing the app on a production device switches its tunnel on; users with the network privilege can switch it off and on from the app settings on their device.

Full Example

ports: - name: Web Interface port: 1100 main: true protocol: http - name: Video Stream port: 1200 protocol: http - name: Remote Desktop port: 5900 protocol: tcp - name: LoRaWAN Gateway port: 1700 protocol: udp

Field Reference

FieldRequiredDescription
nameYesLabel shown in the device’s app settings
portYesLocal port number the service listens on
mainNoIf true, this port is used for the quick-access icon on the device’s app list
protocolNohttp (default), https, tcp, or udp
remote_port_environmentNoTCP and UDP only: an additional variable name under which the device agent announces the tunnel’s remote port, alongside REMOTE_PORT_FOR_<port>. Device agents before 0.19.8 announce it only under this name

Injected Environment Variables

For every port you declare, the platform injects environment variables into your app’s containers so your code can discover where the service is actually reachable — without hardcoding addresses:

VariableDescription
DEVICE_LAN_IPThe device’s IP address on the local network
DEVICE_PORT_FOR_<port>The port on the device where your declared port is published on the local network
REMOTE_PORT_FOR_<port>The public port allocated by the tunnel server while the tunnel is active (TCP and UDP; device agent 0.19.8 and later). 0 means not assigned yet
REMOTE_PORT_FOR_<port>_CLOUDThe internet-facing port when the device runs on an IronFlock instance that forwards tunnels through the cloud (TCP and UDP)
TUNNEL_DOMAINThe domain the device’s tunnel URLs are composed on: app.ironflock.com in the cloud, the appliance’s domain on an on-premises appliance, and localhost on an edge device of an appliance installed without a domain (plain mode)
INSTANCE_KEYSet only on a device that belongs to an on-premises appliance (instance): the key its cloud-forwarded tunnel URLs carry

<port> is the port number you declared in port-template.yml. For the Remote Desktop example above, the app would receive DEVICE_PORT_FOR_5900 and — while its tunnel is active — REMOTE_PORT_FOR_5900. The IronFlock SDKs compose a port’s remote access URL from these variables with getRemoteAccessUrlForPort. The platform does not set CLOUD_TUNNEL_DOMAIN: cloud-forwarded URLs use app.ironflock.com unless your app sets that variable itself.

Tunnels exist for production installs only. A development (DEV) container gets no tunnel and no remote port of its own — reach it on the device’s local network instead (DEVICE_LAN_IP, DEVICE_PORT_FOR_<port>).

Apps may run concurrently on the same device, so declared ports are mapped to a free port on the device automatically. Always compose local-network addresses from the injected values instead of assuming the declared port:

import os lan_ip = os.environ.get("DEVICE_LAN_IP") lan_port = os.environ.get("DEVICE_PORT_FOR_5900") # service is reachable on the local network at {lan_ip}:{lan_port}

The variables are set when the container starts. Tunnel ports can change while the app is running (for example when a tunnel reconnects), so the tunnel port variables (REMOTE_PORT_FOR_<port>, its _CLOUD companion and a custom remote_port_environment name) are additionally kept up to date as files under /data/env/<VARIABLE_NAME>.txt — the IronFlock SDKs read these automatically. The other variables change only when the container restarts.

The device agent removes a _CLOUD file when the cloud port goes away (cloud forwarding turned off). While the agent’s files are present, a missing or empty _CLOUD file therefore means there is no cloud port, and the SDKs do not fall back to the stale value the container started with.

The agent makes /data/env readable by root only. A container that runs as another user cannot read these files: it sees only the values it started with — no tunnel port that changed since — and the SDKs log a warning once.

How Protocols Work

HTTP / HTTPS

For web-based services. IronFlock creates a URL on the tunnel domain that proxies traffic to the device’s local port. Users open the URL in their browser. It is private: only users signed in to IronFlock with access to the device can open it, unless the port is switched Public.

TCP

For protocols like VNC (Remote Desktop) or direct socket connections. IronFlock allocates a remote port on the tunnel server and exposes it to your app as REMOTE_PORT_FOR_<port>; the service is then reachable at tcp://<TUNNEL_DOMAIN>:<remote port>.

UDP

For protocols like LoRaWAN communication or VPN tunnels. Similar to TCP — a remote port is allocated and exposed as REMOTE_PORT_FOR_<port>.

Embedding in Boards

You can embed a device’s remote access tunnel directly into a board using the Embed Widget. This creates a seamless experience where users can:

  • Monitor global data from all devices
  • Interact with individual devices through embedded web UIs

All within the same dashboard.

Installing an app on a production device switches the tunnel of every port in its port-template.yml on. HTTP and HTTPS tunnels stay private - only users signed in to IronFlock with access to the device can open them - unless a port is switched Public. TCP and UDP tunnels are raw ports on the tunnel server with no login in front, so the app must authenticate its clients itself. Users with the network privilege on the device can switch tunnels off and on again; see Managing Tunnels.

Last updated on