Build An Edge App
What Are Edge Apps?
Section titled “What Are Edge Apps?”Edge apps are a type of application that runs on PhyStack-connected devices without a graphical user interface. These apps execute locally in the field as fully managed PhyStack containers, providing compute power and logic right where it’s needed, at the edge.
Edge apps run on PhyOS-enabled devices. Just like screen apps, edge apps are:
- Published and managed via your PhyStack tenant
- Deployed and configured using the Console
- Integrated with platform features, including:
- App versioning
- Settings schemas
- Centralized configuration and content management
- Real-time event collection via Signals
Common Use Cases for Edge Apps
Section titled “Common Use Cases for Edge Apps”Edge apps are ideal for tasks that require local processing or interaction with hardware. Typical scenarios include:
- Running AI/ML models at the edge (e.g., object detection, people counting)
- Managing peripheral hardware not directly connected to the platform (e.g., doors, printers, sensors)
- Performing real-time data processing before syncing with the cloud
How Edge Apps Work
Section titled “How Edge Apps Work”- Runtime: Powered by Docker, each edge app runs inside an isolated container on the device.
- Language Flexibility: You can build edge apps in any language that runs in a Docker container.
Whether you’re building hardware integrations, deploying AI workloads, or processing data locally, edge apps give you full control at the device level, all while being securely managed by the PhyStack platform.
Prerequisites
Section titled “Prerequisites”Official PhyStack templates use TypeScript on the Bun runtime, offering modern tooling, strong typing, and native SDK support. This is the stack we’ll be working with throughout this tutorial. (A Python template is also available — scaffold it with --lang python.) For AI workloads on GPU devices, a CUDA-enabled Python variant is scaffolded from its own template with --lang python-cuda.
Before you begin, make sure the following are set up and ready to go:
A PhyStack Tenant
Section titled “A PhyStack Tenant”You’ll need access to a PhyStack tenant. If you don’t yet have one, please refer to the Tenant Setup guide.
Local Development Environment with the PhyStack CLI Installed and Configured
Section titled “Local Development Environment with the PhyStack CLI Installed and Configured”If you haven’t set up the CLI on your machine yet, refer to the Dev Environment Setup guide.
A Docker Hub Account
Section titled “A Docker Hub Account”For the purpose of this tutorial, you’ll need a Docker.io account (any OCI container registry works the same way). Create two Personal Access Tokens (PATs):
- One with Read & Write access. The CLI uses it locally to push your app image.
- One with Read-only access. The CLI attaches it to your builds so devices can pull the image.
The CLI keeps the two strictly separate: a token with push access never leaves your machine.
Docker Installed & Configured
Section titled “Docker Installed & Configured”Ensure you have Docker Desktop installed and configured for PhyStack.
You must enable the containerd image store, a requirement for proper edge apps image handling with PhyStack.
If you haven’t set this up yet, refer to the Docker configuration section in the Dev Environment Setup guide.
PhyStack Simulator
Section titled “PhyStack Simulator”The simulator is required to run your app locally during development. See the Simulator reference for setup and usage.
Step-by-Step: Creating and Publishing an Edge App
Section titled “Step-by-Step: Creating and Publishing an Edge App”Once your environment is ready, you can create and publish your first edge app. The flow is: scaffold a project, run it locally in the simulator, register the app in your tenant, log in to your container registry, then build and publish.
1. Scaffold the Edge App Project
Section titled “1. Scaffold the Edge App Project”phy app init my-edge-app --type edgeThis clones the official edge template and patches it with your app’s name — a complete, buildable project, not an empty shell.
Variants:
--lang pythonscaffolds the Python edge template instead of TypeScript.--minimalwrites a tiny dependency-free starter without the template tooling.
Explore your newly created project. You will find a containerized TypeScript application, including:
- Dockerfile for building the app container
- src/ directory with:
schema.ts– settings schema for your application with example settings (learn more in the Settings Schemas guide)app.ts– application entry point with simple example code that performs basic logging to standard output
- settings.json – Docker container configuration (network mode, restart policy, resource limits, port bindings, etc.)
- package.json with the scripts used throughout this tutorial (
dev,build,pub) - scripts/init-settings.js – generates local dev settings from your schema defaults
The app.ts file demonstrates the usage of the @phystack/hub-client package for platform integration. The example code retrieves app settings through the Hub Client and logs them to the console.
Install the dependencies:
cd my-edge-appbun install2. Run Locally with the Simulator
Section titled “2. Run Locally with the Simulator”Before touching any cloud resources, you can already run your app on a simulated device. Start the simulator server in a separate terminal:
phy-simulator startThen launch your app against it:
bun run devThis runs phy-simulator run . --dev-command 'bun src/app.ts', which creates a local twin on the simulated device and launches your app connected to it. Your local settings come from src/settings/index.json — generated from the defaults in schema.ts on first run (delete the file to regenerate it). You should see your app’s console output with those settings applied.
For full details on simulator commands and options, see the Simulator reference.
3. Register the App in Your Tenant
Section titled “3. Register the App in Your Tenant”phy app create my-edge-app --type edgeThis registers the app definition in your tenant — a one-time step. The command is non-interactive and prints the app’s identifiers when it completes.
4. Log In to Your Container Registry
Section titled “4. Log In to Your Container Registry”phy registry login docker.ioThe command prompts for two credentials in turn:
- Push credential: your Docker Hub username and the Read & Write PAT. Used locally to build and push your app image.
- Pull credential: your Docker Hub username and the Read-only PAT. Attached to each build so devices can pull the image.
The CLI verifies that the pull credential is read-only and rejects a token with push access, so don’t reuse the Read & Write PAT at the second prompt. Both credentials are stored in your OS keychain. The push credential never leaves your machine; the pull credential is attached to builds. The login also sets your default registry, which the CLI uses to derive the image reference on publish.
5. Build & Publish
Section titled “5. Build & Publish”bun run pubThe pub script runs your local build and then:
phy app build create my-edge-app --dir . --push --publishwhich packages the app, builds the Docker image, pushes it to your registry (--push; optional if the image already exists in your registry, in which case the CLI verifies the tag instead), submits the build, and publishes it as soon as it processes (--publish). The pull credential devices need is attached to the build automatically. When you don’t pass an explicit --version, the CLI auto-bumps the minor version for each new build.
Checkpoint
Section titled “Checkpoint”After completing this process, you’ll have:
- An edge app project on your local machine that runs in the simulator
- A Docker image published to your registry
- A new app available in your tenant for installation
Deploying the App to a PhyOS Device
Section titled “Deploying the App to a PhyOS Device”Now that your app is ready, the next step is to create an installation and deploy it to a physical PhyOS device.
Create an Installation
Section titled “Create an Installation”- Log in to console.phystack.com
- Navigate to Apps > Developer and locate your app in the list
- Press the Install button and provide a name for your new installation
- After confirmation, you will be redirected to the Installation page
- A build of your app will be created automatically as part of the installation
Connect a PhyOS Device
Section titled “Connect a PhyOS Device”In this step, you can connect an edge-compatible PhyOS device to your installation.
For an overview of supported device types, refer to our Device Setup guide.
No physical device? Install PhyOS in a virtual machine instead. Guides are available for VMware, Hyper-V, and QEMU/KVM. Once it’s running and connected to your Tenant, the VM behaves like any other Device, so you can follow the rest of this section unchanged.
- Navigate to the Devices tab on your Installation page
- Press the Connect a device button
- In the modal that appears, click Setup a new device
- Choose your device type from the available options
- Follow the setup instructions displayed on the right side of the modal
- Enter:
- A name for the device
- The serial number or provisioning code shown on your PhyOS device’s screen
- Confirm by pressing the Connect device button
For additional details on connecting devices to installations, check out this guide.
Once the device is successfully connected, you should see:
- The device name appear on the device screen
- The connection status update on the screen of the device
- Your app will be automatically downloaded and started
To verify deployment from your computer, run:
phy device shell <device-name>Replace <device-name> with the name used during setup (also shown on the device screen).
This opens a direct shell session to the device.
Run the following to check if your app is running:
docker psYou should see a container running, with a name matching your app’s image.
To inspect logs, use:
docker logs <container-id> -fThe <container-id> is displayed as the first column in the docker ps output.
If everything is working correctly, you’ll see output similar to:
Hello, world! 10Settings: { "testSetting": "Default value"}If you run into issues at this stage, refer to the Troubleshoot & Debug article of the documentation.
Make Code Changes
Section titled “Make Code Changes”Let’s make some changes to see the development workflow in action.
Open src/app.ts and update the code by adding an additional console.log statement:
setInterval(() => { counter += 1; console.log('Hello, world!', counter); console.log('This is a test'); // <-- added console.log('Settings:', JSON.stringify(settings, null, 2));}, 3000);Verify the change locally first — the simulator gives you the fastest feedback loop:
bun run devPublish an Updated Version
Section titled “Publish an Updated Version”Once your app is updated and working as expected, publish a new version and deploy it via the Console:
bun run pubThis rebuilds the app, pushes a fresh image, and submits a new build — the build version is bumped automatically (pass --version to phy app build create if you want to control it explicitly).
Test the New Version in Console
Section titled “Test the New Version in Console”- Go back to your installation in the PhyStack Console
- Open the Settings tab and press Edit settings
- Change the value of “A test setting” to “New setting value”
- In the Version dropdown, select the new version
- Press Save all changes
When you access the Settings tab of your installation, you’ll see that the settings defined in your app’s schema.ts appear in the Console as an editable form.
After a few moments, your app will be redeployed with the new version to all connected devices.
You can connect to one of your devices using the same steps as before and verify your app’s updated output by checking the container logs.
Success!
Section titled “Success!”Your app is now running the updated version with modified code and updated settings.
You’ve successfully gone from creation to deployment, iteration, and production publishing, all with full integration into the PhyStack platform.
Checkpoint
Section titled “Checkpoint”After completing this part of the tutorial, you should have:
- A fully functional edge app deployed and running on your device
- An installation in your tenant
Next Steps
Section titled “Next Steps”Now that your app is setup, you can: