
Build a self-hosted Kubernetes application platform, verify the deployment, and connect to it remotely
Akamai App Platform, maintained in the apl-core project, combines a developer portal, GitOps workflows, identity management, networking, observability, CI/CD, and other cloud-native capabilities on Kubernetes. In this guide, we focus on installing the platform with Helm on a conformant Kubernetes cluster rather than using the automatic LKE workflow. We cover the infrastructure requirements, storage, load balancing, DNS, networking, installation, verification, post-installation responsibilities, and common failures. After the platform works locally, we show how to expose a verified HTTP endpoint through Localtonet without configuring inbound router port forwarding, firewall rules, a VPN, or a public IP address.
π What's in this guide
What Akamai App Platform and apl-core provide
Akamai App Platform is a pre-built Kubernetes developer platform designed to help teams deploy, manage, expose, observe, and secure containerized workloads. The open-source implementation is maintained in the linode/apl-core repository under the Apache 2.0 license. It is optimized for Linode Kubernetes Engine, but its documented custom provider supports installation on another conformant Kubernetes cluster.
This is not a single web application installed as one isolated pod. It is an integrated platform made from multiple Kubernetes projects and controllers. The platform uses Kubernetes Operators and GitOps principles to manage desired state through configuration. Its browser-based self-service experience gives developers a central place to work with application templates, workloads, images, secrets, repositories, networking, and operational data.
Platform administrators receive a multi-tenant foundation for onboarding development teams, applying governance, managing users, implementing network policies, and operating shared platform capabilities. Developers can build OCI-compliant images from source, deploy containerized workloads through GitOps, expose applications, access logs and metrics, create secrets, and use private Git repositories and CI/CD pipelines.
The instructions below target a conformant Kubernetes cluster and follow the documented Helm installation path. LKE has separate automatic and manual installation workflows with different infrastructure requirements. Do not apply LKE sizing or provisioning instructions to a custom cluster without checking the documentation for the path you selected.
Choose the correct installation path
The project documents three installation paths. The correct choice depends on whether you are creating a new LKE cluster, adding the platform to an existing LKE cluster, or operating Kubernetes through another provider.
| Installation path | Best for | Important distinction |
|---|---|---|
| Automatic installation on LKE | A new LKE cluster created through Akamai Cloud | App Platform is enabled while creating the cluster. The documented LKE workflow automatically enables the required highly available control plane. |
| Manual installation on LKE | An LKE cluster that already exists | Use the dedicated LKE manual installation instructions rather than assuming that custom-provider values apply unchanged. |
| Custom installation | Another conformant Kubernetes service or an appropriately prepared on-premises cluster | Set provider: custom and satisfy the custom prerequisites for compute, storage, an externally addressable LoadBalancer, DNS, and network policies. |
The automatic LKE path documents a node pool with at least three workers, at least 16 GB of total memory, and 12 total CPUs. It also requires an HA control plane. The custom-provider documentation gives a different minimum: Kubernetes 1.33 or higher and a node pool with at least 6 vCPU and 12 GB RAM. These requirements belong to different installation paths and should not be combined into a new, unofficial sizing formula.
Minimum resources are also not the same as production capacity. Workloads, optional platform applications, retention policies, build activity, database usage, and observability volume can increase resource requirements. Plan capacity around the applications and traffic that will actually run on the cluster.
Prerequisites for a custom Kubernetes installation
Before adding the Helm repository or creating the platform values file, confirm that the underlying cluster satisfies every dependency. A successful Helm submission does not prove that the platform will become operational. Controllers can remain pending when storage, load balancing, DNS, resources, or networking are incomplete.
| Requirement | Documented expectation | What to confirm |
|---|---|---|
| Kubernetes | Version 1.33 or higher | The API server and worker nodes are running a supported version and are healthy. |
| Compute | A node pool with at least 6 vCPU and 12 GB RAM | Allocatable capacity is available after accounting for Kubernetes system workloads and existing applications. |
| Persistent storage | A default StorageClass, or app-specific storage configured through _rawValues |
Dynamic volume provisioning works and the intended class is marked as default when relying on the default behavior. |
| External IP | The installer creates a Kubernetes LoadBalancer Service | The assigned external IP can be reached from inside the cluster. On-premises environments may require MetalLB. |
| Ingress | An NGINX Ingress Controller is installed by the platform | Provider-specific LoadBalancer annotations are known if the infrastructure requires them. |
| CNI | A CNI that supports Kubernetes NetworkPolicy is required for network policy features | Calico or another compatible implementation is installed and functioning. |
| Metrics Server | Installed by the platform unless explicitly disabled | Disable the platform copy when the managed Kubernetes service already supplies Metrics Server. |
| DNS | Access to a DNS zone is required | You control the intended domain and possess the credentials required by the selected DNS provider. |
| Autoscaling | A Cluster Autoscaler is not installed by App Platform | Install and manage one separately if the environment requires automatic node scaling. |
| Administrative tools | Working Kubernetes and Helm access | Your current context targets the intended cluster and your identity can create the required resources. |
Begin with read-only checks. These commands show the active cluster, node versions, node health, and available storage classes:
kubectl cluster-info
kubectl get nodes -o wide
kubectl get storageclass
Confirm that every intended worker reports Ready. In the StorageClass output, identify whether one class is marked as the default. Also confirm that your current Kubernetes context is the correct environment before running any installation command:
kubectl config current-context
DNS API tokens and other provider credentials are secrets. Do not commit a populated values.yaml file to source control, paste it into support tickets, or include it in screenshots. Use narrowly scoped credentials where the provider supports them, restrict access to the workstation performing the installation, and rotate any token that may have been exposed.
Prepare storage, load balancing, networking, and DNS

Configure a default StorageClass
The custom installation uses the cluster's default StorageClass unless an application receives a different class through its raw values. If a suitable StorageClass already exists but is not the default, the documented command is:
kubectl patch storageclass <your-storage-class> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
Replace <your-storage-class> with the exact StorageClass name returned by Kubernetes. Before changing the default, verify that the class has the performance, availability, expansion, reclaim, and topology behavior expected for this cluster. Changing the default affects other workloads that create PersistentVolumeClaims without naming a class.
The platform also supports selecting another StorageClass per application through _rawValues. The documented Harbor example is:
app:
harbor:
_rawValues:
persistence:
persistentVolumeClaim:
registry:
storageClass: <your-storage-class>
size: 5Gi
This example applies specifically to the shown Harbor value structure. Do not assume that every integrated application exposes the same nesting or storage fields. Use the schema and documentation for the application being customized.
Provide an external IP for the LoadBalancer Service
During installation, App Platform creates a Kubernetes Service of type LoadBalancer. The resulting external IP must be accessible from within the cluster. Managed cloud platforms commonly provide an implementation for this service type. Bare-metal and on-premises clusters often do not, which can leave the external address pending indefinitely.
The custom-installation documentation suggests MetalLB for on-premises environments. Its documented example is:
kubectl create namespace mlb
helm repo add metallb https://metallb.github.io/metallb
helm repo update
helm install metallb metallb/metallb -n mlb
sleep 60
cat <<EOF | kubectl apply -f -
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: default-pool
namespace: mlb
spec:
addresses:
- <start-ip>-<end-ip>
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default-pool
namespace: mlb
EOF
Replace the address placeholders with a range reserved for load-balancer allocation on your network. Do not select arbitrary DHCP addresses or addresses already assigned to other devices. The correct range, L2 reachability, and routing rules depend on your network design. Coordinate this change with the network administrator when the cluster is not an isolated lab.
App Platform installs an NGINX Ingress Controller. If the Kubernetes provider requires annotations on the LoadBalancer Service, add those annotations to the chart values. The documentation provides this example:
ingress:
platformClass:
entrypoint: ''
annotations:
- key: service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol
value: true
That annotation is provider-specific. It is an example, not a universal requirement. Use only the annotations documented by the infrastructure provider operating your load balancer.
Install a NetworkPolicy-capable CNI when needed
Network policies require enforcement by the cluster's CNI. The documentation identifies Calico or another CNI that supports Kubernetes NetworkPolicy. If your cluster already has a compatible CNI, do not layer another implementation on top without confirming that the combination is supported.
The documented Tigera Operator installation is:
helm repo add projectcalico https://docs.tigera.io/calico/charts
helm repo update
kubectl create namespace tigera-operator
helm install calico projectcalico/tigera-operator --version v3.26.3 --namespace tigera-operator
The documented minimal Calico alternative is:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/calico.yaml
CNI changes affect pod networking and may interrupt the entire cluster. First identify the CNI already installed by your Kubernetes provider and verify whether it enforces NetworkPolicy. Treat the Calico commands as options for an environment that needs them, not as mandatory commands for every cluster.
Handle Metrics Server correctly
App Platform installs Metrics Server by default. If the Kubernetes provider already includes it, disable the platform-managed copy in values.yaml:
apps:
metrics-server:
enabled: false
For clusters whose kubelet endpoints use certificates that Metrics Server does not trust, the documented setting is:
apps:
metrics-server:
extraArgs:
- --kubelet-insecure-tls=true
This relaxes certificate validation for Metrics Server's kubelet connection. Use it only when required by the cluster's certificate configuration and after understanding the trust implications. A properly trusted certificate configuration is preferable where it is practical.
Prepare DNS and optional autoscaling
A DNS zone is required by the custom provider. The provider can be used with different DNS services, but the exact values and credentials depend on that service. The installation sample supplied by the project uses a Linode DNS token. Do not copy that provider block unchanged when using another DNS provider.
App Platform does not install Cluster Autoscaler. If dynamic worker scaling is required, install and configure the implementation supported by your infrastructure provider separately. The appropriate autoscaler command, identity permissions, and node-group configuration are provider-specific, so there is no safe universal command to include.
Install apl-core with Helm
Once the cluster prerequisites are satisfied, the custom installation itself has three documented Helm steps: create values.yaml, add and update the App Platform Helm repository, and install the chart. Keep this sequence intact so that configuration is reviewed before resources are created.
Create the custom-provider values file
Set a cluster name, select the custom provider, include Metrics Server adjustments only when required, and configure the DNS domain and provider credentials. Replace every placeholder and make sure required shell variables are populated before creating the file.
Add and update the App Platform Helm repository
Add the official apl chart repository and update local repository metadata so Helm can resolve the chart.
Install the chart
Install the apl/apl chart as the Helm release named apl, using the reviewed values file.
Step 1: Create values.yaml
The documented sample is:
tee values.yaml<<EOF
cluster:
name: $CLUSTER_NAME
provider: custom
# optionally configure metrics-server for kubelet-insecure-tls
apps:
metrics-server:
extraArgs: ["--kubelet-insecure-tls=true"]
# dns is required!
dns:
domainFilters:
- <your-domain>
provider:
linode:
apiToken: $LINODE_TOKEN
EOF
Set CLUSTER_NAME and, for this Linode DNS example, LINODE_TOKEN in the current shell before running the command. Replace <your-domain> with the DNS zone intended for the platform. Because the heredoc is not quoted, shell variables are expanded into the resulting file. Inspect the file carefully without exposing its contents in shared logs or terminal recordings.
Remove the metrics-server insecure TLS override if the cluster does not require it. If the provider already operates Metrics Server, replace that section with the documented enabled: false setting. If you use a DNS service other than the one shown, obtain its exact supported provider schema from the current App Platform documentation. The evidence for this guide does not establish those provider-specific field names, so guessing them would risk a failed installation or leaked credentials.
Step 2: Add the Helm repository
helm repo add apl https://linode.github.io/apl-core
helm repo update
If Helm reports that the repository name already exists, inspect the currently configured URL before deciding whether to reuse or replace it:
helm repo list
Step 3: Install the chart
helm install -f values.yaml apl apl/apl
This creates a Helm release named apl. The command submitting successfully means Kubernetes accepted the release resources. It does not by itself prove that every controller, database, ingress, certificate, identity component, and optional dependency is ready.
The supplied project evidence identifies v6.3.0 as the latest release at verification time, but the documented installation command does not pin a chart version. Before a production installation, review the currently available chart and release notes, then apply your organization's version-pinning and change-control policy. Do not assume that a release label remains current indefinitely.
Verify the installation before using it

Verification should proceed from the Helm release to Kubernetes resources, storage, ingress, DNS, and finally the browser-based platform. Avoid debugging through the public hostname first. Lower-level status normally reveals whether the issue is scheduling, storage, networking, load balancing, DNS, certificates, or authentication.
Check the Helm release
helm status apl
helm list -A
Confirm that the release appears in Helm and note the namespace reported by helm status. Do not assume a namespace name that was not explicitly selected in your installation.
Inspect pods and recent events
kubectl get pods -A
kubectl get events -A --sort-by=.lastTimestamp
Look for pods that remain Pending, repeatedly restart, or report image, mount, scheduling, readiness, or permission errors. Events often explain conditions that a simple pod list cannot, including insufficient CPU or memory, unbound PersistentVolumeClaims, failed mounts, unavailable external addresses, and admission-policy failures.
App Platform includes many interconnected applications, so readiness may not be instantaneous. Persistent failures should be investigated rather than hidden by repeatedly reinstalling the release.
Verify persistent storage
kubectl get pvc -A
kubectl get pv
Claims expected by the platform should progress to Bound. A claim remaining Pending commonly indicates that no usable default StorageClass exists, dynamic provisioning is failing, topology constraints cannot be satisfied, or the requested storage settings are incompatible with the provider.
Verify the LoadBalancer and ingress resources
kubectl get svc -A
kubectl get ingress -A
Identify the service of type LoadBalancer and check whether an external address has been assigned. For an on-premises cluster, a persistent Pending address usually means there is no working load-balancer implementation or its address pool is invalid. Confirm that any assigned address is reachable from inside the cluster, as required by the custom installation.
Review the ingress hostnames generated from your DNS configuration. Then check the corresponding DNS records through your normal DNS tooling. DNS propagation alone cannot repair an incorrect zone, rejected API credentials, an inaccessible load-balancer address, or a failed certificate workflow.
Complete post-installation configuration
The project explicitly requires a post-installation phase. That phase may include locating the initial username and password and completing other setup. The supplied evidence does not establish the exact command, secret name, namespace, hostname, or credential retrieval procedure, so this guide does not invent one.
Use the post-installation instructions matching the exact App Platform release you installed. Before remote access, verify all of the following:
- The platform's documented console hostname resolves to the intended address.
- The browser can reach the console from an authorized network location.
- The expected login page appears rather than a generic ingress error.
- The documented administrator credential procedure succeeds.
- Default or bootstrap credentials are changed when the platform workflow permits or requires it.
- Only intended users and teams have platform access.
The project evidence confirms a web-based console but does not provide one universal local hostname, Kubernetes Service, ingress URL, or port for every custom installation. Obtain the actual endpoint from your deployed ingress and the release-matched post-installation instructions. A guessed service or port can expose the wrong component or create an unsafe access path.
Operate the platform after installation
A successful installation is the beginning of platform operations, not the end. App Platform coordinates multiple applications with different responsibilities and release stages. Administrators should treat platform configuration, application activation, upgrades, backups, access controls, and capacity as controlled operational changes.
Understand included and optional applications
The current application documentation separates always-installed applications from optional ones. Always-installed applications include Argo CD, External Secrets Operator, Istio, Keycloak, OpenTelemetry, Prometheus, and Sealed Secrets Operator. Optional applications include Alertmanager, CloudNativePG, Gitea, Grafana, Harbor, Knative, Kserve, Kubeflow Pipelines, Kyverno, Loki, RabbitMQ, Tekton, Trivy, and Valkey.
Exact availability and lifecycle can change by App Platform release. For example, the supplied v6.3.0 release evidence marks Kubeflow Pipelines as deprecated and introduces an add-ons capability for platform administrators to deploy custom Argo CD applications. Review the release notes before enabling a component or planning a dependency around it.
| Release stage | Intended use | Integration expectation |
|---|---|---|
| Alpha | Preview and testing | Experimental, subject to significant change, and only minimally compliant with the platform's integration criteria. |
| Beta | Pre-production evaluation | More stable than alpha and partially compliant with the integration criteria. |
| GA | Stable platform use | Fully compliant with the stated integration criteria and intended to remain unchanged within a major version. |
The integration criteria cover backup and restore, database upgrades, lifecycle management, authentication and authorization, graceful termination, continuity, Kubernetes version support, monitoring, and resource management. A component's release stage therefore matters operationally, not just cosmetically.
Use the platform for application workflows
After administrators finish post-installation setup and onboard teams, developers can use quickstarts or organization-specific templates to build images and deploy workloads. Applications can be exposed publicly through the platform's Kubernetes and ingress-oriented workflow. Teams can also configure network policies, response headers, CNAMEs, secrets, logs, metrics, traces, and automated image updates where those capabilities are enabled.
Localtonet is not a replacement for those native application-delivery workflows. If an application is intended to be a durable public production service, use the platform's supported ingress, DNS, certificate, identity, policy, and observability design. Localtonet is most relevant when an administrator needs controlled remote reachability to a private HTTP endpoint, a temporary review environment, or a service that should not require inbound network changes.
Plan upgrades and backups
Do not assume that a generic helm upgrade command is the complete upgrade procedure. App Platform releases can update core applications, schemas, operators, and platform behavior. Review the release-specific upgrade instructions, deprecations, and compatibility information before changing versions.
Back up the data and configuration required by your recovery objectives before upgrades. Also test restoration rather than treating the existence of a backup as proof of recoverability. The platform documentation defines backup and restore as an application integration criterion, but each environment still needs an operational recovery plan for cluster infrastructure, DNS, credentials, configuration, persistent data, and external dependencies.
Access a private App Platform HTTP endpoint with Localtonet

Complete this section only after the platform endpoint works from the device or network where the Localtonet client will run. Localtonet exposes a reachable local HTTP service through an outbound connection to one of our relay servers. This means you do not need inbound router port forwarding, firewall changes, a VPN, or a public IP address for the Localtonet access path.
The client device must be able to reach the selected App Platform endpoint. Depending on your deployment, that endpoint might be an internal ingress address or another HTTP address established by your Kubernetes and post-installation configuration. The supplied App Platform evidence does not define a universal console address or port, so discover and verify the real endpoint before creating the tunnel.
Identify the correct HTTP target
From the machine that will run our client, open the App Platform endpoint or test it with an HTTP client. Verify that it returns the intended platform login or application response. Do not target the Kubernetes API server, a database, an identity backchannel, an administrative metrics port, or an arbitrary service discovered in the cluster.
If the endpoint is accessible only inside the Kubernetes network, choose an approved method to make it reachable from the Localtonet client device. The correct design depends on cluster networking. This guide does not provide a fabricated kubectl port-forward command because the required namespace, resource name, address, and port are installation-specific and are not established by the supplied evidence.
Create and start the Localtonet HTTP tunnel
Install and run the Localtonet client
Run our client on the device that can already reach the verified App Platform HTTP endpoint. Use the current installation guidance for that device's operating system rather than copying an unverified command.
Authenticate and select the device
Use the device-specific authentication token created for that client. Keep the token private and select the corresponding connected device when configuring the tunnel.
Select an available relay server
Choose a currently available server or region from the Localtonet dashboard. Available server codes and regions can vary, so they should not be hardcoded from an article.
Create an HTTP tunnel to the verified local target
Enter the local IP address and port that the client device uses to reach the intended App Platform HTTP endpoint. Select the appropriate process type: Random Sub Domain, Custom Sub Domain where supported, or Custom Domain.
Start the tunnel
Press Start after reviewing the configuration. Creating the tunnel alone does not make it active.
Test the public URL and manage its lifecycle
Open the assigned public HTTPS address and confirm that it reaches the expected authenticated platform page. Stop the tunnel when access is no longer needed, or delete it when the configuration should not be retained.
For the current dashboard workflow, consult our Localtonet HTTP tunnel documentation. Custom-domain DNS requirements can change, so verify the current documentation before adding or modifying DNS records.
Confirm that App Platform authentication is working before starting the tunnel. Apply least privilege, restrict administrator accounts, review platform authorization, and avoid exposing internal components that were not designed for browser access. A tunnel does not replace application authentication or Kubernetes network policy. Stop the tunnel promptly when temporary access is complete.
Troubleshoot installation and remote access
| Symptom | Likely area | What to check |
|---|---|---|
| Pods remain Pending | Compute or storage | Inspect events for insufficient CPU or memory, scheduling constraints, missing volumes, or unbound claims. Confirm the custom cluster minimum and available allocatable capacity. |
| PersistentVolumeClaims remain Pending | StorageClass | Check that a suitable default StorageClass exists, dynamic provisioning works, and app-specific storage values refer to a real class. |
| LoadBalancer external address remains Pending | Load-balancer implementation | Verify the cloud integration or MetalLB installation, address pool, L2 advertisement, address availability, and provider-required annotations. |
| Ingress hostname does not resolve | DNS | Confirm the domain filter, zone ownership, provider configuration, token permissions, generated DNS record, and authoritative name servers. |
| Metrics components fail | Metrics Server duplication or certificate trust | Determine whether the provider already installed Metrics Server. Disable the platform copy when appropriate and use the insecure kubelet TLS option only when required. |
| Network policies do not appear effective | CNI | Verify that the active CNI supports and enforces Kubernetes NetworkPolicy. Installing policy resources alone does not guarantee enforcement. |
| Helm install succeeds but the console is unavailable | Platform readiness or post-installation setup | Review Helm status, pods, events, services, ingress, storage, DNS, certificates, and the release-matched post-installation procedure. |
| Local endpoint works but the Localtonet URL does not | Tunnel configuration | Confirm that the selected device is connected, the tunnel is started, the relay selection is valid, and the local IP and port match the endpoint tested from that device. |
| Localtonet reaches the wrong page | Incorrect local target or ingress routing | Retest the exact local address from the client device. Verify the intended hostname and HTTP routing instead of selecting an arbitrary Kubernetes service. |
| The public URL stops working unexpectedly | Tunnel lifecycle | Check whether the selected Localtonet client is still connected and whether the tunnel is running. The tunnel is available only while both conditions remain true. |
Work from the lowest dependable layer upward. First verify cluster health, then storage and scheduling, followed by the LoadBalancer, ingress, DNS, platform login, local HTTP reachability, and finally the Localtonet tunnel. This order prevents a public access symptom from obscuring an underlying Kubernetes failure.
Frequently asked questions
Can apl-core run outside Linode Kubernetes Engine?
Yes. App Platform is optimized for LKE, but the project documents a custom provider for another conformant Kubernetes cluster. The custom environment must meet the documented Kubernetes, compute, storage, external IP, networking, DNS, and related infrastructure requirements.
What Kubernetes version and resources does the custom installation require?
The custom-provider documentation requires Kubernetes 1.33 or higher and a node pool with at least 6 vCPU and 12 GB RAM. These are custom-provider minimums. Actual production capacity depends on enabled platform applications, user workloads, build activity, storage, and observability requirements.
Does App Platform require a default StorageClass?
The platform uses the default StorageClass unless another class is configured for a specific application through _rawValues. Confirm that dynamic provisioning works before installation. Changing the cluster default can affect other workloads, so review the storage class behavior first.
Is MetalLB required?
Not universally. A managed Kubernetes service may already implement Services of type LoadBalancer. MetalLB is the documented option for on-premises environments that need such an implementation. Do not install it on top of an existing load-balancer integration without checking compatibility.
What is the default App Platform console URL or port?
The supplied project evidence does not establish one universal hostname, service address, ingress URL, or port for custom installations. Discover the actual endpoint from the deployed ingress and complete the post-installation procedure for your installed release. Do not guess a port or expose an arbitrary internal service.
Does Localtonet replace App Platform authentication?
No. Localtonet provides connectivity between a public tunnel address and the selected local target. App Platform identity, authentication, authorization, network policy, user management, and workload security remain in effect and must be configured independently.
Should Localtonet be used instead of the platform's public application exposure?
Not generally. App Platform includes native ingress-oriented capabilities for publicly exposing applications, DNS integration, certificates, CNAMEs, response headers, identity, policy, and observability. Use those supported platform workflows for durable production publication. Localtonet is useful when a verified private HTTP endpoint needs controlled or temporary remote reachability without inbound network changes.
Why does the Localtonet URL stop when the client disconnects?
Our tunnel depends on the selected device maintaining its outbound connection to the relay. The tunnel must also be running. If the client disconnects, the device shuts down, or the tunnel is stopped, its public endpoint is no longer available.
Connect your verified Kubernetes endpoint with Localtonet
After apl-core is healthy, post-installation configuration is complete, and the intended HTTP endpoint works from your client device, create a Localtonet HTTP tunnel for controlled remote access without inbound router port forwarding.
Get Started Free β