# Linux IoT and Edge Apps
Ionoid.io IoT and Edge Linux apps are archive files that bundle the application, libraries, files and other dependencies. Using some of Linux Containers Technology to implement file system isolation, devices are able to run multiple applications isolated from one another.
Installed apps are located on device storage at:
For every application, there will be a corresponding directory:
All files corresponding to an app are located under its path. This makes it easy to stop, disable, or completely remove applications.
# IoT Apps
Ionoid.io supports multiple IoT app formats:
Static binaries without libraries or other filesystem dependencies. If you are deploying Static Binaries then please keep reading this document. Static binaries will have an auto generated App YAML file.
Archive tarball or compressed
tar.gzapps. The archive files are standard files format that were released several years ago, they are well supported and the tools to process them are all Open Source tools. If you are deploying Archive apps then please keep reading this document. Archive apps must include an App YAML file that describes how the application will run.
Build archive apps with Docker
You can also use docker to build containers, then export as tarballs to produce archive apps. Please see documentation below archive apps for more details.
# App YAML Format
Each app is described using The App YAML format. The App yaml is
a simple manifest to describe how the app should work, it is fully
described in the
app.yaml file (see next section), and only works with
apps that are static binaries or archive apps.
Docker apps do not need the
app.yaml file, they already
contain their own app manifest and are auto handled withing their
Visit this link for docker apps for more information.
app.yaml file should be present in the root directory of an
archive file. Every app must have its corresponding
For static binaries with no dependencies, an
app.yaml file will be auto-generated on the fly to define how the
app should run.
App YAML file example:
# Note: lines starting with `#` are comments and have no semantics. # Name of APP must be unique on the device. # Only alphanumeric + the special "_", "." and "-" characters are allowed. # Minimum 2 characters, up to 64 characters. # Mendatory field. name: appname # Version of App to be deployed # Mendatory field. version: 1.0 # Description of App description: My App # List of Applications inside the same IoT App archive, for now we only # support one single app. Support of multiple apps inside will be added in # the future. apps: # App hello-world entry, must be Alphanumeric and may contain the # special characters "_", "." and "-". # Minimum 2 characters, up to 64 characters. # Mendatory field. hello-world: # Environment Vars for Hello World Optional environment: A: "ABC" # Semilar to environment but reads the environment variables # from a text file. The text file should contain new-line-separated # variable assignments. environmentfiles: - "/etc/hello-world-environment1" - "/etc/hello-world-environment2" # Optional command to be executed before the main executable app. # Can be used to setup environment. start-command: /bin/echo hello # Mendatory field: the full path of the main application command: /bin/hello-world # Optional command to be executed after the main app finishes # Can be used to clean up state. stop-command: /bin/echo stopped # Daemon Command type takes one of these values: # * simple: the process configured with command # is the main process of the service. # This is the default value if daemon is # not set. # * forking: it is expected that the process configured # with command will call fork() as part # of its start-up. # * oneshot: it is expected that the process configured # with command will exit or terminate. # # For more details check systemd service documentation. daemon: simple | forking | oneshot # Make the application run with root privileges if you want # to access special devices and ports on your hardware that # need special permissions. By default it is false, and the # app will run as `ionoid-app` user. privileged: true volumes: # Volumes and mounts to be made accessible inside the application. # # Volumes support two types of mount 'rbind' and 'norbind': # * rbind: perform a recursive bind mount of the volume. # * norbind: perform a non-recusive bind mount. # # Volumes support different options: # * rw: perform a regular writable bind mount (unless source is read-only). # * ro: perform a read-only bind mount. # - src=filesystem_path:dst=app_path:type=rbind:options=rw - src=filesystem_path:dst=app_path:type=norbind:options=ro # /dev, /proc and /sys are already mounted inside the app # no need to mount them again. # Mounting device host /etc configuration inside the app: - src=/etc:dst=/etc,type=rbind,options=ro # If you want to make the root-filesystem available then the # following volume mount is the safest instruction. - src=/:dst=/:type=norbind,options=ro # Health check is a special command to do health checking on # your one or multiple apps # still under development health-check: command: /bin/health-check
health-check field is a special directive that may allow you to do
health checks on your running apps. Right now it is in progress - still under
name: hello-world version: 1.0 apps: hello-world: command: /bin/hello-world
# App Persist Data
If you want to persist your data on the device and share it with other
applications and the rest of the system, then this can be easily done by
writing to the
/shared/$myappname directory volume. Every application has by
/shared/$myappname volume mounted and available inside its
From the application point of view, shared data is located at:
From the rest of the system point of view, shared data is located at:
/shared/$myappname directory is world readable and accessible
to the system. If you write secret files there, then make sure to set the
appropriate access permissions, especially if your device is used by non-trusted
/shared/$myappaname directory is owned by:
ionoid-app: meaning that all applications running with that User ID can write to it.
ionoid-app: meaning that all applications running with that Group ID can write to it and share data.
Volumes and mounts are the preferred mechanism to persist data on the device by applications and share it with others.
# Static Binaries
Static binaries are apps without libraries or other filesystem dependencies. Please visit wikipedia Static Binaries link to read more about it.
Building static binaries differs from one language and environment to another, the following documentation will try to help you get started with it.
The target OS here is of course
# Golang Static Binaries
Before we start with our steps on how to produce static binaries from Golang sources, let's see some variables and environments that we have to set, this will allows us to really produce statically linked binaries:
CGO_ENABLED=0Instruct compiler to disable CGO and statically link C bindings.
GOOS=linuxOur target Operating System is Linux.
GOARCH=$archOur target board architecure. If in doubts please visit our Supported boards Table. Current supported values for
GOARM=$versionIf the target board architecture is
armthen you have to set the
GOARMor the machine variable. Current supported values are
7. For a detailed explanation please visit the official Golang ARM Wiki.
Here is how to build Golang static binaries for each architecture:
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 \ go build -tags 'osusergo netgo' -ldflags '-extldflags "-static"' main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 \ go build -tags 'osusergo netgo' -ldflags '-extldflags "-static"' main.go
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ go build -tags 'osusergo netgo' -ldflags '-extldflags "-static"' main.go
More Static Binaries
Support for static binaries from other languages is under development and will be added soon.
# Deploy Static Binaries
When deploying static binaries with Ionoid.io, there is
no need to put it inside docker or write an
app.yaml file for it. If your
application has no external dependencies on files or other
applications, just upload it to the internet and point Ionoid.io
to its deployment URL.
app.yaml file will be auto-generated on the fly at the devices
level using the following format:
name: $myappname version: $unixtimestamp apps: $myappname: command: /bin/$myappname
# Example of a generated
Given the hello-world example app (visit this link to find
the complete source files and binaries of the app), the auto-generated
app.yaml file will be:
name: hello-world version: 1583693787 apps: hello-world: command: /bin/hello-world
hello-world is the the last resource file name from the URL path. For example that taken from the followinf URL
1583693787 is the Unix timestamp at the moment of deployment.
To deploy your static binaries, upload them to the internet, and point the deployment URL to the right one:
For more examples please visit our hosted sample apps here: Ionoid.io Sample Apps
More robust deployment methods are being developed, they will be added soon.
# Archive Apps
app.yamlfile: it encodes the basic information of the app
bin/directory: it is the binary directory where the app resides
meta/directory (Optional): it contains extra app metadata
- Other files and/or directories (Optional): it consists of the rest of app file system and other dependency files.
The content of the
app.yaml file would be (as in the
IoT App Golang Hello World
name: hello-world version: 1.0 apps: hello-world: command: /bin/hello-world
Since archive apps are archive files that contain the app and its dependencies, there are several Open Source based methods to build such archive files. The following sections details this with real examples.
# Minimal Archive Apps
The following is a minimal simple way to build archive apps, these steps describe
how to manually build the previous Hello World IoT App example for
- Create the app directory
mkdir hello-world cd hello-world
1 - Populate the app directory with
app.yaml and executable files:
hello-world ├── app.yaml └── bin └── hello-world
2 - Generate the app tar archive, in the following example, we assume we build for ARMv7 so we make it clear in the file name:
tar cvvf hello-world-armv7-v0.2.tar -C hello-world --transform='s,^./,,' .
3 - The
hello-world-armv7-v0.2.tar is our final app that can be deployed to
When generating the app archive, it can be compressed to save deployment data usage with the following command:
tar czvf hello-world-armv7-v0.2.tar.gz -C hello-world --transform='s,^./,,' .
# Docker Archive Apps
Docker offers the necessary tooling to build containers, then export them as archive apps. This laverages IoT and Edge apps to be as simple as possible using the App YAML file, while at the same time offers the unique way to run apps without including complex containers feautres that are more suited for the cloud.
Please refer to the next chaper Build IoT and Edge Apps to see how to take advantage of docker, export and build archive apps.
# Mkiot Archive Apps
Make IoT Apps is our standard method to build lightweight self contained IoT and Edge apps. For more details, please refer to the next chapter Build IoT and Edge Apps to build IoT archive apps using mkiot.
# Debian deboostrap Apps
Debian debootstrap is an Open Source tool
to bootstrap a basic Debian image. The application, its bundles and the
app.yaml file should all be added to the Debian image that will be used to
generate the artifact tarball.
# Docker containers
This will be released soon.