An application on SPEKTRA Edge is a container, described with a standard
Docker Compose file and deployed to devices you select by label.
The device’s droplet runtime pulls the image, starts the containers, and keeps
them running.
This section follows one application from source code to a running, observable
workload. If you have not deployed anything yet, Get started
does a shorter version of the same journey end to end.
The cuttle CLI is needed only for reaching a deployed application from your
own machine; you do not need it to deploy.
1 - Develop an application
Build a container image for SPEKTRA Edge and publish it to a registry.
This page describes how to develop applications for the SPEKTRA Edge
platform.
SPEKTRA Edge utilizes the Docker containers to package and deploy
applications for your devices. We follow the standard
docker build process for creating applications so that
you can benefit from the knowledge and experience you may already have
through the prior application development process. Once the image is
built, you publish it to one of the container registries to make devices
to retrieve and run it on the device.
What you need
To build and publish the application image to the registry, you need:
Docker Engine on your local machine
access to the container registry
Follow the Docker installation guide to install Docker
Engine on your machine. For the container registry access, please consult
your container registry documentation, e.g. Docker Hub
quickstart guide.
Dockerfile
SPEKTRA Edge application development starts with a Dockerfile.
Docker builds images by reading the instructions from a Dockerfile.
A Dockerfile is a text file containing instructions for building your
source code. The Dockerfile instruction syntax is defined by the
specification reference in the Dockerfile reference.
Those are the typical instructions used in Dockerfile:
FROM <image>
initializes a new build stage and sets the base image for subsequent
instructions.
RUN <command>
executes any commands to create a new layer on top of the current image.
WORKDIR <directory>
sets the working directory for any RUN, CMD, ENTRYPOINT, COPY,
and ADD instructions that follow it in the Dockerfile.
COPY <src> <dest>
copies new files or directories from <src> and adds them to the
filesystem of the image at the path <dest>.
CMD <command>
sets the command to be executed when running a container from an
image.
Python Flask application example
Let’s take a look at the example Dockerfile, which builds the
simple Python Flask application:
# syntax=docker/dockerfile:1FROMubuntu:22.04# Prepare the python environment on the image.RUN apt-get update && apt-get install -y python3 python3-pipRUN pip install flask==3.0.*# Copy the Flask app to the image.COPY hello.py /# Run the Flask app.ENV FLASK_APP=hello
EXPOSE8000CMD ["flask", "run", "--host", "0.0.0.0", "--port", "8000"]
then, run the following command to build your application image.
docker build --tag test:latest .
You can give any tag name here, for example awesome:v1.0.0, but
pick the one you can remember, as you will reference it when you
push it to the container registry.
The last '.' in the command
It’s called Docker build context and specifies
the location of the build environment, which in this case, composed
of Dockerfile and hello.py files shown above.
Now, your application image is ready. Let’s publish it to the container
registry next.
Push to registry
Repositories let you share container images to be downloaded by the devices.
In this section, we’ll use the Docker Hub as the container
registry, as it’s free and publicly accessible. Please consult your
container registry documentation in case you use other one.
Private container registries
You can deploy applications from the private registries on SPEKTRA Edge.
Please take a look at the private registries page
how to do it.
You can create a free account on Docker Hub. Please follow the
Docker Hub quickstart guide to create
one if you haven’t created.
Here is the simple step to publish your application to the Docker Hub:
Login to the Docker Hub:
docker login
Re-tag the image you build in the previous step to point to
the Docker Hub repository you own:
docker tag test:latest <hub-user>/<repo-name>:<tag>
Push the image to the registry:
docker push <hub-user>/<repo-name>:<tag>
Please consult the official Docker documentation if
you get error with those commands.
Next steps
Once you develop your application and publish it to the registry,
it’s time to deploy it on your device. Please move on to the deployment
document next.
2 - Deploy an application
Deploy a published container image to a device and confirm it is running.
Once you have developed and published your application image to a
container registry, it is time to deploy it to your device.
SPEKTRA Edge provides the Docker compose environment
on your device so that you can declare your application in the standard
Docker compose file format to run it on your device.
Let’s create a compose.yaml file for the application we developed
in the previous section and deploy it on your device through
the SPEKTRA Edge dashboard.
Private Container Registries
Please take a look at the private registry section
in case you use the private container registries, such as Amazon Elastic Container
Registry, Azure Container Registry, or Google Artifact Registry.
What you need
To deploy your application on your device, you need:
the Docker Compose environment on your local machine,
for local verification
a device provisioned through the SPEKTRA Edge dashboard
And also, the cuttle CLI command is necessary to complete this tutorial,
which is used to access the application from the local machine for the
verification purpose. However, it is not required for deploying applications
on SPEKTRA Edge.
Device Provisioning
Please go through the getting started guide
if you haven’t done that.
Local verification
Let’s create and verify compose.yaml file on your local machine.
compose.yaml
Here is the compose.yaml file to deploy the
application we developed in the previous section.
This is the top level element of the compose file to abstract
the definition of a computing resource within an application which
can be scaled or replaced independently from other components.
The ports is used to define the port mappings between the host machine
and the containers. This is crucial for allowing external access to
service running inside containers.
This example exposes the container application’s port 8000 to be
accessible through the local machine’s port 8000.
Please take a look at the official document for
the ports attribute definition.
SPEKTRA Edge compose conventions
Your compose file runs on the device through a managed pod driver, which behaves
slightly differently from a plain docker compose up in your project folder.
Keep these two conventions in mind when authoring compose.yaml.
Use absolute host paths for bind mounts. The driver stores each pod’s
compose file in its own state directory on the device and runs docker compose
from there, so a relative bind-mount source is resolved against that
internal directory — not a project folder you control. Docker then auto-creates
the missing path there and the agent logs a repeating
failed to read compose file ...: is a directory error. Use an absolute
host path on a persistent filesystem instead. On SPEKTRA Edge OS that is
/isodevice/data, which survives power cycles and OS upgrades (on a .deb
install, use an absolute path on your host’s own persistent storage). Better
still, mount configuration through a configuration map and
host volume:
services:
app:
volumes:
# Avoid — relative source resolves inside the driver's state directory:# - ./config:/etc/app/config## Prefer — an absolute path on the persistent data partition: - /isodevice/data/myapp/config:/etc/app/config
Do not set container_name. The driver tracks and reconciles containers
using its own naming convention (derived from the pod name). A custom
container_name no longer matches that convention, so the agent treats the
container as potentially unmanaged and falls back to re-scanning manifests to
re-associate it. Omit container_name and let the driver assign names.
docker compose up
With the compose.yaml file ready on your local machine, run
docker compose up command in the directory where the file
locates:
$ tree .
.
└── compose.yaml
1 directory, 1 file
$ docker compose up
[+] Running 2/0
✔ Network sample_default Created 0.0s
✔ Container sample-app-1 Created 0.0s
Attaching to app-1
app-1 | * Serving Flask app 'hello'app-1 | * Debug mode: off
app-1 | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
app-1 | * Running on all addresses (0.0.0.0)app-1 | * Running on http://127.0.0.1:8000
app-1 | * Running on http://172.20.0.2:8000
app-1 | Press CTRL+C to quit
Here you can see the application running and listening on the port
8000 on your local machine.
With the compose.yaml ready, let’s deploy your application on your device
through the SPEKTRA Edge dashboard.
Go to the project overview page and click Deploy pod.
Deploy pod button on the Project overview page.
Select Deploy on a single device option and provide the following
information.
Application name
Application description
Docker compose, compose.yaml file for your reference
Target device to deploy
Deploy on multiple devices
You can deploy applications on multiple devices on SPEKTRA Edge. Please
take a look at the [multiple devices][multiple-devices] page for more detail.
[multiple-devices]: ../multiple-devices/
Then, click Deploy to deploy your application.
Deploy button on the Deploy pod page.
Congratulations!
You now deployed your application on your device through the SPEKTRA Edge
dashboard.
Verify your application
You can verify your application’s health from the SPEKTRA Edge dashboard.
The application page provides the following statistics:
Application’s overall status
Each container’s status
Each container’s CPU utilization
Each container’s memory utilization
Application’s logs
CPU Utilization button on the Application page.
You can also restart the application by clicking the Restart option
of the drop down menu right next to the application’s name:
Naming a service after the pod restarts only that container, and
cuttle applications pods start|stop|restart gives you the other two actions.
Or you can edit the applications, e.g. compose.yaml, by clicking the
Edit option of the drop down menu right next to the application’s name:
Editting Docker compose file in the Update pod details pane.
Now, let’s access your application from your local machine by
utilizing the SPEKTRA Edge port-forwarding feature. Simply copy
the cuttle command provided by the dashboard located under
the Docker compose section:
Copy Port forward command option on the Application page.
Open the terminal on your local machine. Paste the command you just copied
onto your terminal and run it to enable the port-forwarding to access your
application from the local machine.
Here is the example port-forward command for your reference. It enables
your application, which is listening on device’s port 8000, reachable
through your local machine’s port 8000.
With the above port-forwarding command running, point your browser to
http://localhost:8000 to access your
application from your local machine.
You will get the same result you got during the local verification.
Successfully accessing the application running on your device.
Next steps
With the application running on your device, learn how to supply it with
configuration, so the same image can behave differently in
different places.
3 - Configure applications via configuration maps
Supply configuration to a running application with configuration maps.
Let’s learn how to configure applications via configuration maps on SPEKTRA Edge.
A configuration map allows you to decouple environment-specific configuration
from your application images, so that your applications are easily portable.
You can map the application configuration to the particular containers under
the application with the following steps:
Create an application with docker compose volumes service attribute
to describe the configuration to be mounted on the container
through the following two levels of indirection:
Host volume to mount the configuration to the host
environment so that the application can mount the configuration to
the particular container.
We’ll use the Nginx application and source the configuration file through the
configuration map to demonstrate how to use the configuration map on SPEKTRA Edge.
And also, the cuttle CLI command is necessary to complete this tutorial,
which is used to access the Nginx application from the local machine for the
verification purpose. However, it is not required for deploying applications
on SPEKTRA Edge.
Note
The getting started guide will help you to set
those requirements up. Please go through the guide in case you
miss some of those.
Application files
compose.yaml
It’s a simple Nginx application with mapping the port 8000 with the configuration
directory mounted through the volumes attributes.
We recommend to use the /isodevice/data directory as the host side of the
volume mount entry point. It’s a persistent file system and will keep the mapped
contents even through the power cycle.
nginx.conf
Here is the Nginx configuration file, which will be mapped to the application
through the SPEKTRA Edge configuration map.
It’s a simple configuration file, which make it listen on the port 8000,
instead of port 80. Since we override the default configuration, we also
sets the content root to the default Nginx content directory with root
directive.
server {
listen8000;
root/usr/share/nginx/html;
}
Nginx beginner's guide
Please take a look at the Nginx beginner’s guide if you are not
familiar with the Nginx configuration file format.
Deploy the application
Let’s deploy the application with the configuration map on SPEKTRA Edge.
the host volume to mount the configuration to the host
environment for the load balancer container to mount the configuration
file to.
Let’s do it.
Create a configuration map
Let’s create a configuration map to store the Nginx configuration file
on SPEKTRA Edge.
First, select the Config maps option of the Applications pull-down menu.
Select Config maps option from the Applications pull-down menu.
Then, create a configuration map by pasting the nginx.conf file
content in the data key value field with the default.conf as the data key name.
Create configuration map by pasting the nginx.conf content in the data key value field.
Make sure you set:
nginx-conf as the configuration map name
default.conf as the configuration data key name
Those names are important because it’s referenced by the other object in
the later steps.
Create the application
With the Nginx configuration map ready, let’s deploy the application.
Here is what we’ll do:
Paste the docker compose file content to the
Docker Compose field
Create a volume config map for the Nginx configuration file mapping
Create a host volume to mount the above configuration map to the device
We’ll go over those points step-by-step below but first, let’s have
a Deploy pod page ready by clicking the Deploy pod button
on the Project overview page.
Click Deploy pod button on the Project overview page to deploy application.
Docker compose file
Let’s paste the docker compose file to the
Docker Compose field of the Deploy pod page.
Docker compose section of the Deploy pod page.
Volume configuration map
The next is the volume configuration map, which maps the Nginx configuration
file we created before to the application as a volume.
Volume config map section of the Deploy pod page.
Here is the key points to highlight:
Select the correct configuration map
projects/your-project/regions/us-west2/configMaps/nginx-conf for this example
Specify the correct select key of the configuration map item
default.conf in this example, as we specified as the key value name for
the Nginx configuration file when we created the configuration map.
Use default.conf for the path name of the select key
This is the file name which will be shown in the container. Nginx expects
this file name as the default Nginx configuration file.
Host volume
This is the last item to configure on the Deploy pod page.
It mounts the volume configuration map we create above to the host environment
of the device. This file will be mounted to the Nginx load-balancer container
through the docker compose file we explained before.
Host volume section of the Deploy pod page.
Again, there are a couple of things to make it right.
the volume name should match the name of the volume configuration map we
created above
nginx-conf in this example
the Volume mount path should be matched to the one specified in the
docker compose
/isodevice/data/nginx/conf.d in this example
Click to deploy
With all those configuration set, click the Deploy button on the Deploy pod
page to deploy the application on your device.
Click Deploy button on Deploy pod page to deploy the application.
With a minute or so, you should be able to see the application running on your
device, as below.
Running status shown on the application overview page.
Verify the application
Let’s verify the application by accessing it through the port forwarding.
Other ways to access your app
Port forwarding is great for reaching a remote device from your workstation.
If your clients are on the device’s local network, or you want containers to
talk to each other, see Access your deployed application.
Go to the application overview page by clicking the name of the app,
Three tier web app in this example, on the Project overview page.
Click the name of the application on the Project overview page to go to the application overview page.
From there, copy the port forward command by clicking the
Copy port forward as Cuttle command button on the application overview page.
Copy the port forward command to access the Nginx service on the application overview page.
Run the command on your local terminal window to make your application accessible
from your browser.
Please note that the device name above will be different for your case.
Device name
The first argument of the port forward command above, which starts with
projects/, is the device name on which the application is running. It
contains both the project and the region name to differentiate from other
devices.
Point your browser to http://localhost:8000 and you should be able
to see the page below.
The Nginx application accessed through http://localhost:8000.
Next steps
Congratulations on configuring the Nginx application with the configuration
map on SPEKTRA Edge.
If your application needs a credential, such as an API token or a password,
continue with credentials. If your image lives in a registry
that needs credentials, see private registry.
4 - Provide credentials to applications with secret volumes
Deliver API tokens, passwords, and certificates to a running application as files with secrets and secret volumes.
Applications often need a credential, such as an API token, a password, or a
certificate. This page shows how to deliver a credential to a container as a
file, without putting it in the container image or in compose.yaml.
You connect a secret to a container with four settings:
A secret stores the value in your project.
A Volume Secrets entry on the pod selects the secret and names a file
for each key.
A Host Volume Mounts entry with the same volume name sets the directory
on the device that receives the files.
A bind mount in compose.yaml mounts that directory into the container.
a role that can create secrets and deploy pods, such as Owner, Admin
operator, Device operator, or Application operator
Every device in the project can read every secret
The platform stores secrets encrypted, but it does not limit a secret to the
devices that use it. Any device in the project can read any secret in the
project. Keep a credential that a device must not see in a different project.
Create the secret
The device base64-decodes every secret value before it writes the file. Enter
each value in base64. Convert to Base64 encodes the text in the value box
for you. The file on the device then holds your original text. If the value is
already base64, Convert to Base64 leaves it unchanged.
In the left navigation menu, click Applications, then click Secrets.
Select Secrets under Applications in the left navigation menu.
Click Add Secret.
In Secret display name, enter Demo API token. The page shows the
generated secret ID, demo-api-token.
If the page shows Region, select the region of your device. The
platform does not copy secrets between regions, and a device reads secrets
only from its own region.
In Secret data key name, enter token. You select this key name later
when you deploy the pod.
In Secret data key value, enter demo-token-1234. The box does not hide
what you type.
Click Convert to Base64. The value changes to ZGVtby10b2tlbi0xMjM0.
Fill in the Add Secret page and click Convert to Base64.
To add another key, such as the private key for a certificate, click
Add another data key.
Click Create. The Dashboard shows “Successfully created secret.”
Write the compose file
The example container only sleeps. You look at its files from a terminal in
Verify the application.
The volumes entry bind-mounts the host directory
/isodevice/data/credentials/api into the container at /etc/credentials. The
device writes the secret files to the host directory, and the container reads
them at /etc/credentials. The :ro suffix makes the mount read-only inside
the container. The device writes each file as root with mode 0644, so any
user in the container can read it.
Files under /isodevice/data persist across reboots. They are encrypted on
disk only when disk encryption is enabled on the device.
Use a dedicated directory
Deleting the pod deletes the host directory that receives the secret files,
with everything in it. Give each application its own directory, such as
/isodevice/data/credentials/api. Never use /isodevice/data itself or a
directory that holds other data.
Deploy the application
On the Project overview page, click Deploy pod.
Choose the Pod card. It deploys to a single device.
In Pod display name, enter Credentials demo.
In Docker Compose, paste the content of compose.yaml.
In Target device to deploy, select your device.
Paste the compose file and select the target device on the Deploy pod page.
In the Volume Secrets card, click Add volume secret. Fill in the new
entry as follows:
In Volume Name, enter api-credentials.
In Select Secret, select
projects/<your-project>/regions/<your-region>/secrets/demo-api-token.
The page accepts an empty selection, but the application then fails on
the device.
Leave Enter Mode bits for Secret and Specify whether the Secret or
its keys must be defined at their defaults, because the device ignores
both.
Under Select Secret Items, in Select Key, select token.
In Enter Path, enter token. The device writes the value to a file
with this name in the host directory. Use a plain file name, not a path
such as a/b.
Fill in both Select Key and Enter Path. The page accepts an empty
row, but the application then fails on the device.
Select the secret, its key, and the file name in the Volume Secrets card.
In the Host Volume Mounts card, click Add Host volume. Fill in the
new entry as follows:
In Volume Name, enter api-credentials. This name must match the
Volume Name in Volume Secrets. The page does not check it.
In Volume Mount Path, enter /isodevice/data/credentials/api. This is
the host directory that receives the files. It must match the left side
of the bind mount in compose.yaml. The on-screen hint describes a path
within the container, but here you enter the host directory.
Leave Volume Sub Path and Volume Read Only at their defaults. The
device ignores both, so :ro in compose.yaml sets read-only instead.
Enter the same volume name and the host directory in the Host Volume Mounts card.
Click Deploy. The Dashboard shows “Successfully deployed pod” and opens
the application overview page.
Verify the application
On the application overview page, wait for the status to change from
Pending to Running.
Click the device name next to Running on to open the Device overview
page.
In the Terminal window, click Connect. To use your own terminal
instead, see Access devices.
Find the container of your application.
docker ps --format '{{.ID}} {{.Names}}'
The container name is the pod name followed by _app_1. It spells each
hyphen as -2d and each slash as -2f. Copy the ID of the row that ends
with credentials-2ddemo_app_1.
Run the docker commands in the Terminal window of the Device overview page.
The size 15 is the length of demo-token-1234, not of the 20-character base64
text, so the device decoded the value before it wrote the file. This sample
prints the credential to show that it arrived. Do not print credentials in a
real application.
Pass a credential as an environment variable
Some programs read a credential from an environment variable. Docker Compose
can load variables from a file with env_file, so a secret volume works for
this case too. You do not need a bind mount.
Create a secret with the data key name .env. In the value, write one
NAME=value line for each variable, for example
API_TOKEN=demo-token-1234, and click Convert to Base64.
Enter .env as the data key name, and convert the NAME=value lines to base64.
In the Volume Secrets card, select the .env key, and enter .env in
Enter Path.
In the Host Volume Mounts card, enter the same volume name and a
dedicated host directory, such as /isodevice/data/credentials/env.
In Docker Compose, replace the volumes entry with an env_file entry
that names the file on the host.
The application logs show demo-token-1234 every 30 seconds. This
sample prints the credential to show that it arrived. A real application must
not write its credentials to a log.
Docker Compose expands $name in an env file, so write $$ for a literal
dollar sign. The line SAMPLE=pa$$word gives SAMPLE the value pa$word.
An environment variable is less private than a file. Anyone with root access on
the device can read it with docker inspect, and every process in the
container inherits it. Use a file, as in the first example, when the program can
read one. To deliver a new value, follow Update a secret.
Update a secret
Editing a secret does not change the files of a running application. The device
reads a secret only when it creates the application or when you change the
application’s settings. Restart and Save without a change do not read
the secret again.
To deliver a new value:
In the Secrets list, click the name of the secret.
Click the vertical three-dots next to the secret name, and select Edit.
Click Show Secret to see the stored value. It is the base64 text.
Replace the value with the new text, and click Convert to Base64.
Click Update. The Dashboard shows “Successfully updated secret.”
On the application overview page, click the vertical three-dots next to the
application name, and select Edit Details.
In Docker Compose, change any setting, and click Save. For example,
add an environment variable that holds a version number, such as
CREDENTIALS_VERSION=2, and raise the number each time you rotate the
secret.
The device writes every secret file again and recreates the container.
The device does not remove files for keys that you delete from the secret or
from Select Secret Items. To remove them, delete the application.
Deleting the application also removes the host directory.
Troubleshoot
If the device cannot prepare the volumes, the application status becomes
Initialization failed. The Error row and the red banner on the
application overview page show the device’s message. Some messages say
ConfigMap even when the volume is a secret.
The application is in Initialization failed because the secret value is not valid base64.
Error message contains
Cause
Fix
base64 decode error at
The secret value is not valid base64.
Edit the secret, enter the value again, and click Convert to Base64.
key `<key>` not defined
Select Key names a key that the secret does not have, or the row under Select Secret Items is empty.
Select a key in Select Key, and enter a path in Enter Path.
unable to get Secret
The secret does not exist, is in another region than the device, or the device cannot read it.
Create the secret in the region of the device, and select it in Select Secret.
could not write to
Enter Path contains a subdirectory, such as a/b.
Enter a plain file name.
volume `<name>` referenced by container
The Volume Name in Host Volume Mounts matches no Volume Name in Volume Secrets.
Enter the same name in both cards.
Two problems show no error message.
If the container runs but ls shows total 0, the bind mount in
compose.yaml uses a different host directory than Volume Mount Path.
The container sees an empty directory. Use the same host directory in both
places.
If Select Key has no options, your role cannot read secret values. Ask for
a role listed in What you need.
The device does not retry an application in Initialization failed on its
own. After you fix the secret or a setting, click Edit Details, change a
setting in Docker Compose, and click Save.
To run the application on many devices at once, continue with
multiple devices. To learn how the platform stores and
scopes secrets, read Secrets.
5 - Deploy with private container registries
Pull application images from a private registry using image secrets.
Let’s learn how to deploy applications from the private container registries.
SPEKTRA Edge supports private container registries, such as Amazon Elastic Container
Registry, Azure Container Registry, or Google Artifact Registry, as the application
container registries.
In this document, we’ll learn how to configure the application on SPEKTRA Edge
to run the container image hosted on the Azure container registry, a private
container registry offered by Microsoft Azure.
Under that directory, run the following docker build command to create
the application image tagged with the Azure container registry and repository
name for the publication in the following step.
Please replace the registry and the repository name, spektraedge.azurecr.io
and awesome part above, to match your setup.
Refer to the official document for the private registry
creation on Azure.
Publish the image to the Azure container registry with docker push command.
docker push spektraedge.azurecr.io/awesome:latest
Once it’s pushed, go to the Azure portal and double check if the application
image correctly published on Azure container registry.
The application image on Azure container registry.
Great. You’ve successfully published the application image to the private
container registry.
Now, you’re ready to configure the application to pull the image from the
Azure container registry. But before that, let’s talk about the image
secrets next.
Image secrets
The image secrets is a special secret resource maintained by the SPEKTRA Edge
platform. It’s meant to be used for storing the credentials to access the private
container registries. Hence, we’ll configure the image secrets next before
configuring the applications.
Kubernetes private registry support
The SPEKTRA Edge image secret follows the convention used by the Kubernetes.
Please take a look at their documentation about how to pull an image
from a private registry for more information.
Let’s create one here.
Go to the Secrets page by selecting the Secrets from the Applications
pull-down option from the left navigation menu.
Select Secrets option of Applications pull-down menu.
Click Add Secret button on the Secrets page to create a new secret.
Click Add Secret to create the image secret.
There are three mandatory fields to create a secret. We’ll go over those
in detail in the following sections.
This is a case-insensitive alpha-numeric secret name referenced later by
the application configuration. Give it a descriptive name for the better
secret management.
Secret data key name
This field should be .dockerconfigjson. This follows the
Kubernetes convention.
.dockerconfigjson
Please don’t miss the first dot, the period, in the .dockerconfigjson
key name, or it would cause the image download error.
Secret data key value
This field contains the base64 encoded private registry credential with
the following JSON format.
where you set $REGISTRY_NAME environment variable to your Azure container
registry name, e.g. spektraedge in this example.
Convert to base64
Once you have those three values ready, you paste those in the respective fields
and click Convert to Base64 button of the Add secret page.
Convert Data key value to base64.
Create the image secret
Click Create to create the image secret for the Azure container registry.
Create Image Secret with base64 encoded Data key value.
Please remember the Secret Name (ID), spektraedge-azurecr-io in this example,
for the later reference to deploy your application.
Deploy the application
For the application deployment, we’ll follow the standard application deployment
explained in the previous section except one field, the image secrets.
On the Deploy pod page, select the image secret you created in the previous
step and just click Deploy as usual.
Click Deploy button to deploy the application with the image secrets set.
Next steps
Congratulations on mastering the deployment with the private container registry
on SPEKTRA Edge!
So far you have deployed to one device at a time. Next, learn how to deploy to
multiple devices at once.
6 - Deploy to multiple devices
Use label selectors to roll one application out across a fleet.
Let’s learn how to deploy the application on multiple devices on SPEKTRA Edge.
Please do the same for other devices as well before moving on to the deployment
step next.
Deploy with pod templates
Once you set the device labels on your target devices, now is the time to deploy
applications on all those devices in one-shot with a pod template.
The pod template is a template to apply application deployment against multiple
devices, similar to the template field of the deployments manifest
in Kubernetes.
Let’s create one to see it in action. We’ll use the same application we used
for the single device deployment to demonstrate how easy and similar
deploying applications on multiple devices.
Go to the Project overview page and click Deploy pod button.
Click Deploy pod button on the Project overview page.
Use the Pod template option in Deploy pod page this time and select
the target devices by providing the device label, task:multi-devices in
this example, in the Target device labels to deploy field, in addition
to the other application information similar to one for the single device
deployment.
Select the target device labels to deploy on Deploy pod page.
Click Deploy to deploy it on multiple devices.
Once it’s done, you should be able to see applications all running
on the target devices, five devices in this example, from the Project overview
page.
awesome application running on all five target devices.
Next steps
Congratulations on successfully deploying the application on multiple devices
in a single-shot on SPEKTRA Edge.
Reach an application running on a device, including through port forwarding.
Let’s learn the ways to reach an application running on your device with
SPEKTRA Edge.
Once you deploy an application, its containers run on the device and
publish ports according to your Docker compose file. How you reach those ports
depends on where you are relative to the device. This page covers the three
common cases:
The left side (8000) is the device host port; the right side (8000) is
the container port.
From your workstation (port forwarding)
This is the recommended way to reach an application on a remote device. It
works from anywhere, over the device’s existing outbound connection to the
platform, so no inbound ports need to be open on the device or its network.
You need the cuttle CLI installed for this method.
Open the application’s Application overview page in the dashboard (see
Monitor & control).
Click Copy port forward as Cuttle command to copy a ready-made command.
This forwards the device’s port 8000 to 127.0.0.1:8000 on your machine.
Point your browser at http://localhost:8000
and you’ll reach the application as if it were running locally.
The first argument is the full device name (it includes the project and region);
the dashboard fills this in for you when you copy the command.
Why use port forwarding?
It works wherever you are, not just on the device’s network.
It is tunneled through the platform’s authenticated connection, so you don’t
expose the application to the public internet or open firewall ports.
It’s ideal for administration, debugging, and one-off access.
From the device’s local network
If your client (a browser, another machine, a PLC, etc.) is on the same local
network as the device, you can reach a published port directly using the
device’s IP address:
http://<device-ip>:<published-port>
For the Nginx example above, that would be http://<device-ip>:8000.
This is the natural choice when the application is meant to serve other equipment
on-site — for example, a local dashboard, an API consumed by nearby machines, or
a gateway service.
A few things to keep in mind:
The port must be published in the compose file (the ports entry). A
container port that isn’t published is only reachable from inside the device.
By default a published port is reachable on all of the device’s network
interfaces. If you only want it on a specific interface, bind it explicitly
in the compose file, for example 127.0.0.1:8000:8000 to keep it on the
device itself.
Make sure the chosen host port doesn’t collide with another application or a
system service on the device.
From another container
Containers within the same application can talk to each other over the
application’s internal network using their service name as the hostname —
they don’t need to publish ports for this. For example, an app service can
reach a redis service at redis:6379.
Only publish a port (with ports) when something outside the application
needs to reach the container. Internal service-to-service traffic should stay
on the internal network.
Persisting data behind your application
If your application stores data (uploads, a database, configuration), mount it
under the device’s persistent data area so it survives restarts and power
cycles:
It also offers the cuttle port forward command, which you can
copy and run on your local machine to access your application through
the SPEKTRA Edge port forwarding capability.
Accessing your application
For all the ways to reach a running application — platform port forwarding,
access from the device’s local network, and container-to-container — see
Access your deployed application.
Copy port forward command option in the Application overview page.
Application statuses
Here is the list of application statuses monitored on SPEKTRA Edge.
Status
Description
Pending
The application is accepted by the system and it’s under processing to be launched. It’s the PENDING state of the Pod.Status.Phase enumeration type.
Running
The application is running, which is that its all containers supposed to be running are up and running. It’s the RUNNING state of the Pod.Status.Phase enumeration type.
Succeeded
The application is terminated with the success exit code. It’s the SUCCEEDED state of the Pod.Status.Phase enumeration type.
Failed
The application encountered an issue and some or all of the containers are not running. This phase happens after the containers are initially created successfully. It’s the FAILED state of the Pod.Status.Phase enumeration type.
Offline
The application does not respond anymore. This phase happens after the containers were initially created successfully. It’s the UNKNOWN state of the Pod.Status.Phase enumeration type.
Image download failed
The application failed to download the container image. It’s the IMAGE_DOWNLOAD_FAILED state of the Pod.Status.Phase enumeration type.
Initialization failed
The application failed to initialize or the validation of the application definition had some errors, typically caused by the Docker compose file syntax errors or the system errors on devices such as disk full. It’s the INIT_FAILED state of the Pod.Status.Phase enumeration type.
Pod create failed
The application could not be created, because of either a docker runtime error or an invalid keyword in the compose file. It’s the POD_CREATE_FAILED state of the Pod.Status.Phase enumeration type.
Container states
Here is the list of Container’s state, which is the composition of
the application status explained above. The Containers section
of the Application overview page shows the container states.
State
Description
Waiting
The container is waiting to start. It’s the WAITING state of the Pod.Status.Container.State enumeration type.
The container is terminated. It’s the TERMINATED state of the Pod.Status.Container.State enumeration type.
Application metrics
You can monitor the container’s resource usage on the dashboard.
Go to the Containers usage section of the Application overview page
and select the type of resource you want to monitor. Click the right side
of the time range section to specify the duration of the time-series to be
shown on the graph.
Specifying the duration of the time to show the application CPU usage.
Application logs
You can retrieve each container’s logs on the dashboard.
Specify the name of the container you want to show the logs by clicking the
pull down menu of the Logs section on the Application overview page.
Click Start to retrieve the live logs of the container.
You can also download the logs by clicking the Download icon on the
Logs menu bar.
Observing the redis container’s logs.
Control applications
You can control applications from the dashboard.
Here is the list of operations you can perform:
delete
restart
Click the vertical three-dots right next to the application’s name
in the Application overview page to show the pull-down menu and select
the operation you want to perform.
Restarting the application by clicking the Restart option of the pull-down menu on the Application overview page.
Next steps
That completes the application lifecycle: you can build an image, deploy it,
configure it, reach it, and watch it run.
Next, turn to the hardware underneath. Devices covers setting up
and operating the machines your applications run on.