Advent 2023 banner

Your First FoundriesFactory AI-Powered Christmas Tree

Photo of Raul Muñoz

Posted on Dec 1, 2023 by Raul Muñoz

9 min read

Welcome to part 1 of our AI Powered Machine Learning Christmas Tree Series!

The goal of this series is to equip your Christmas Tree with the capability to control its own lighting. To do this, a webcam will be connected to an Arduino Portenta X8 running a ML algorithm powered by the Edge Impulse AI Platform.

To begin, the first thing to do is to launch your own Factory.

Introducing FoundriesFactory - All-Encompassing Cloud Software Package

The FoundriesFactory® platform is an all-encompassing cloud software package which simplifies and reduces the cost of developing, deploying, and maintaining your secure IoT and Edge Linux-based devices. This page illustrates some of the core features available in FoundriesFactory.

Start Your Free Trial

To begin using FoundriesFactory, start with creating an account with us.

Signup page:

A screenshot of the sign-up page with a Start Free Trial button highlighted

Complete sign up and create your first Factory with a unique name!

A screenshot of the FoundriesFactory dashboard with the platform field highlighted red and factory name field below

When creating your Factory, you will be presented with the above menu. The Platform dropdown box will enable you to select which platform you would like to create an image for.

Select whichever device you have available.

The project outlined in this series was conducted on an Ardunio Portenta X8 and all device specific instructions will pertain to that device. It is possible to follow along with any device, but we will not cover specific details for anything other than the Arduino Portenta X8. Most of the content in this series is device-agnostic however, and you will be able to follow along with only small modifications.

Name your Factory and click the Create Factory button!

You will be redirected over to where you will meet the Factory Overview page:

A screenshot of the Factory Overview Page with the target tab highlighted

Click on the Targets tab highlighted in the image above to see your First Target being generated. The Arduino Portenta X8 is based on our Arduino’s partner image, meaning it will build the image from scratch and should take around 15 to 20 minutes.

However, most other evaluation kits use the Fast First Target, meaning no wait time!

What is a Target?

Let’s examine what exactly a FoundriesFactory Target is. A Target is a description of the software a device should run. This includes two main parts that can be updated:

  • Root File System (rootfs): This is the core operating system of the device. Together with the Linux Kernel and Bootloader (OStree), which allows for atomic updates.
  • Docker Compose Apps: These typically comprise additional software applications or components that are part of your Factory build. They are also included in the Target, and can be updated separately from the rootfs.

The Linux microPlatform™ (LmP) is based on the OpenEmbedded / Yocto Project, and adds a select set of board support package layers to enable popular development boards.

For more information on FoundriesFactory Targets, see our What is a Target blog post.

While you are waiting for the build to complete, this would be an excellent time to install Fioctl™. Fioctl is a tool for interacting with the Foundries.​io REST API.

Don’t forget to add your application credentials and configure Git!

Flashing and Connecting to Arduino Portenta X8

After the build is complete, and you have Fioctl™ installed and configured, the next step is to flash your Arduino Portenta X8 with the Target that was just created. We have detailed instructions to do just that over on our docs page. Once the board is booted and running your first Target, it is time to connect to the board. We will log into the board via SSH, but in order to do this, we first need to connect it to the Internet.

Consulting the user manual for your particular device for the best method to do this.

For the Arduino Portenta X8, our recommended method to connect to the Internet is with a USB-C Ethernet.

Once your device is connected to your network, you will be able to log into it via SSH.

To login via SSH on your host machine, run:

ssh fio@<machine-name>.local

Where fio is the username and machine-name is the hostname of your device. The default password is fio.

By default, your device hostname is set to a unique string that specifies the platform chosen during Factory creation (machine). Check Supported Machines for a list of supported platforms and their machine values.

Once you have access to your device’s terminal, you will be able to register it to your Factory.

With all that done, you can now build and deploy our first hello-word Docker app with FoundriesFactory.

Deploying Your First Application

It’s time to harness the power of FoundriesFactory to show how easy it is to deploy an app onto your device (or thousands of devices all at once).

FoundriesFactory gives you the ability to build the Docker Image for ARM32, ARM64, and x86 in the cloud and, by using docker-compose.yml, make it available for any device connected to your Factory. Below is a diagram explaining the architecture:

Architecture overview diagram

Devices registered to a Factory communicate with the device gateway via the aktualizr-lite daemon. This manages all the configured applications and - based on your preferences - enables and disables them. These modifications are enabled through Fioctl and managed on the device with fioconfig.

But let's see a practical example of this in action, and deploy a hello-world application using FoundriesFactory.


To begin; clone your containers.git from

host:~$ git clone<factory>/containers.git
Replace factory> with your factory name.

Go ahead and enter your containers directory. If you have not made any personal modifications, it should look like this:

├── shellhttpd
└── shellhttpd.disabled
    ├── docker-build.conf
    ├── docker-compose.yml
    ├── Dockerfile

Shellhttpd is a demonstration app to illustrate containers on LmP; if you've worked with Docker before the structure should be familiar to you.

Within this directory, we are going to create a hello-world app. Create a folder named helloworld with the files below inside it:

host:~$ mkdir helloworld
host:~$ cd helloworld
host:~$ vim helloworld.c

#include <stdio.h>
#include <unistd.h>
int main()
        printf("Hello World\n");
    return 0;
host:~$ vim Dockerfile

FROM alpine:3.18
RUN apk add build-base
COPY helloworld.c .
RUN gcc helloworld.c -o helloworld
CMD ["./helloworld"]
host:~$ vim docker-compose.yml

version: '3.2'

    stdin_open: true
    tty: true

With the files in place, commit your changes and push:

host:~$ cd .. # back to containers
host:~$ git add helloworld/
host:~$ git commit -m "Adding HelloWorld App"
host:~$ git push

Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 16 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 774 bytes | 774.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Trigger CI job...
remote: CI job started:<factory>/targets/2/
   ae2fe99..d8b67ac  main -> main

This will launch the CI build for your Factory’s containers. You may follow your build on on the Target page:

A screenshot of the tab where you can register your device to the factory

If you have not already done so, now register your device to the Factory.

Using Fioctl to Configure Your Device

By default, a device will run all apps associated with the latest Target which it upgrades to. This behavior can be changed by enabling only specific applications. Read Enabling/Disabling Apps to learn how. Briefly, if you wish to enable only our helloworld app and not shellhttpd:

host:~$ fioctl devices config updates --apps helloworld <device-name> -f <factory>
Changing apps from: [] -> [helloworld]

At this time, the aktualizr-lite daemon on your device will recognize the available update and begin downloading and applying it. On your device you may follow the update logs with:

device:~$ sudo journalctl -f -u aktualizr-lite

Once the update is complete, you will be able to see view the status of your device and its associated app on the Devices tab on your Factory page on

A screenshot of the Device tab where you can see its associated app

Testing HelloWorld

On your device terminal, use docker ps to find all applications running on your device:

device:~$ docker ps

CONTAINER ID   IMAGE                                 COMMAND          CREATED         STATUS         PORTS     NAMES
880811d552e3   "./helloworld"   3 minutes ago   Up 3 minutes             helloworld-httpd-1

Next, use Docker logs to check the hello-world output:

device:~$ docker logs helloworld-httpd-1

Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World

You have now successfully built and deployed your first container application with FoundriesFactory!

Recap and Conclusion

In this tutorial, you have:

  • Created your Factory and first Target
  • Flashed your device and registered it to the Factory
  • Installed Fioctl and setup credentials to interact with Factory repositories
  • Built and deployed your first container app

Understanding these concepts should help you grasp the power of FoundriesFactory and is the first step in building your own AI powered Machine Learning Christmas Tree.

Join us for the next step in the series as we discuss network configuration.

Continue Building Ai-Powered Christmas Tree

If you are interested in our entire 14-part series on how to build an AI powdered Christmas tree, browse through each section below. Each part brings you closer to mastering your build:

Related posts