Improve this doc
I want to get started with a using

Get started on developing with Intel NUC and Node.js

In this guide we'll cover:

  • Setting up your Intel NUC device and bringing it online on the balenaCloud dashboard
  • Deploying a Node.js hello-world project on the device
  • Developing the sample project: making changes and testing them on the device in real-time

Once you've completed this guide you'll be equipped with the fundamentals needed to continue developing your application using balenaCloud and be on the path to deploying fleets of devices to production.

What you'll need

  • An Intel NUC mini PC from Intel.
  • A 4GB or larger USB thumb drive.
  • A HDMI enabled LCD screen and HDMI cable.
  • A simple USB keyboard.
  • A power supply unit for the NUC.
  • An ethernet cable or WiFi adapter to connect your device to the internet.
  • A balena account.

Create a fleet

If you don't already have a balena account, make sure to sign up before continuing.

A fleet is a group of devices that share the same architecture and run the same code. Devices are added to fleets and can be moved between fleets at any time.

To create your first fleet, log into your balenaCloud dashboard and click the Create fleet button.

Create a fleet

Enter a fleet name, select the Intel NUC device type, choose the Starter fleet type, and click Create new fleet:

You'll then be redirected to the summary of the newly created fleet, where you can add your first Intel NUC.

Add a device and download OS

Add a device

To connect with balenaCloud, your Intel NUC needs a balenaOS image configured for your device type, fleet, and network. Start by clicking Add device in your fleet dashboard:

Add new device

Select an OS type of balenaOS, and you will see a list of available balenaOS versions with the latest preselected. Choose a Development version of the OS. The production OS does not facilitate the development workflow we'll be using. Find out more about the differences between Development and Production images.

Network configuration

Select the type of network connection you'll be using: Ethernet Only or Wifi + Ethernet. A network connection is required to allow the device to connect to balenaCloud. Selecting Wifi + Ethernet allows you to enter a Wifi SSID and Wifi Passphrase which is then built into the image.

Download Image

Finally, click the Download balenaOS button. When the download completes, you should have a zipped image file with a name like balena-First-Fleet-intel-nuc-2.80.3+rev1-v12.7.0.img.zip.

Provision device

Locate the image file you downloaded and flash it to the USB key using Etcher. Etcher will prepare a bootable USB key and safely eject it when complete.

Put the USB drive into your device and connect either the ethernet cable or WiFi adapter. Ensure that the HDMI screen and keyboard are connected up.

Warning: BalenaOS will completely overwrite the internal media of your NUC, so if you have important data on the device, we recommend that you make a backup before you attempt provisioning the NUC on balena.

Now connect up the power supply and turn the device on. The power button may be a small round button on the top of the device or a square button on the front.

Press the F10 key while the BIOS is loading in order to enter the boot menu. Next, select the UEFI : USB (or resinOS) option from the boot menu so that the device will boot from your USB drive.

Once the device boots, you should see it pop up on your balena dashboard. It will immediately go into a flashing internal media state. This means that the device is flashing the balenaOS onto your internal flash media.

Note: You might encounter an error message when the device boots with the text, "Image Authorization Fail". This message appears when Secure Boot is enabled. Follow the steps present in the Intel support document to access the BIOS setup screen and disable secure boot. After saving, press the F10 key once again when the NUC reboots to enter the boot menu and select to boot from USB/resinOS.

After a few minutes, the OS will be fully flashed to the internal media and the device will shut itself down. At this point, you will see on the dashboard that the device is in a Post-provisioning state. You can now remove the USB drive and press the power button once again.

Your NUC should now automatically boot into the balena OS and you should see the device online and in an Idle state on your dashboard, ready and waiting for some code to be deployed.

Note: If for some reason your device does not boot into balenaOS, you may need to go back into the BIOS and make sure the boot order correctly selects to boot from the internal SATA drive and not from USB.

Install the balena CLI

Now that a device online in your fleet, it's time to deploy some code. We will use the balena CLI for this. Follow the instructions below to install balenaCLI for the operating system available on your system.

  1. Download the CLI installer.
  2. Double click the downloaded file to run the installer and follow the installer's instructions.
  3. To run balena CLI commands, open the Terminal app (Terminal User Guide).

  1. Download the CLI installer.
  2. Double click the downloaded file to run the installer and follow the installer's instructions.
  3. To run balena CLI commands, open a command prompt: Click on the Windows Start Menu, type PowerShell, and then click on Windows PowerShell.

  1. Download the standalone CLI.
  2. Extract the contents of the zip file to any folder you choose, for example /home/james. The extracted contents will include a balena-cli folder.
  3. Add that folder (e.g. /home/james/balena-cli) to the PATH environment variable. Check this StackOverflow post for instructions. Close and re-open the terminal window so that the changes to PATH can take effect.

For more detailed information, visit the detailed Linux installation instructions.


After balena CLI is installed, login to your balena account using the balena login command on the terminal:

$ balena login
 _            _
| |__   __ _ | |  ____  _ __    __ _
| '_ \ / _` || | / __ \| '_ \  / _` |
| |_) | (_) || ||  ___/| | | || (_) |
|_.__/ \__,_||_| \____/|_| |_| \__,_|


Logging in to cloud.com
? How would you like to login? (Use arrow keys)
❯ Web authorization (recommended)
  Credentials
  Authentication token
  I don't have a balena account!

You will be asked to choose an authentication method, choose Web authorization which will bring up a web browser window that allows you to login to your balenaCloud account. Click the Authorize button, and head back to the terminal after the login ssuccessful message appears.

Web authorization

Create a release

After login, test the balena CLI by running the balena fleets command, which should return information about the fleet you created in the previous step. Take a note of the FLEET NAME as you'll need this in the next step to push the code to your device(s) in that fleet.

$ balena fleets
ID    FLEET NAME   DEVICE TYPE          ONLINE DEVICES DEVICE COUNT
98264 First-Fleet  Intel NUC   0              0

A nice project to try is the balena-nodejs-hello-world project. It's a Node.js web server that serves a static page on port 80. To get started, download the project as a zipped file from GitHub, unzip it and open a terminal in the root of the extracted project directory.

To create a release, use the balena push First-Fleet command replacing First-Fleet with the name of your fleet. Ensure you are working from the root of the extracted project directory.

$ balena push First-Fleet

This command pushes the code to the balena builders, where it will be compiled, built, turned into a release, and applied to every device in the fleet.

You'll know your code has been successfully compiled and built when our friendly unicorn mascot appears in your terminal:

[hello-world]  Successfully built 51bd190f7530
[Info]       Generating image deltas from release 8acfdc579f7cb0fe424d1b800588b6f5 (id: 2186018)
[Success]    Successfully generated image deltas
[Info]       Uploading images
[Success]    Successfully uploaded images
[Info]       Built on builder05
[Success]    Release successfully created!
[Info]       Release: c0c593803588a304c173124827d96b99 (id: 2186339)
[Info]       ┌────────────────────┬────────────┬────────────┐
[Info]       │ Service            │ Image Size │ Build Time │
[Info]       ├────────────────────┼────────────┼────────────┤
[Info]       │ hello-world        │ 190.04 MB  │ 50 seconds │
[Info]       └────────────────────┴────────────┴────────────┘
[Info]       Build finished in 1 minutes, 4 seconds
                            \
                             \
                              \\
                               \\
                                >\/7
                            _.-(6'  \
                           (=___._/` \
                                )  \ |
                               /   / |
                              /    > /
                             j    < _\
                         _.-' :      ``.
                         \ r=._\        `.
                        <`\\_  \         .`-.
                         \ r-7  `-. ._  ' .  `\
                          \`,      `-.`7  7)   )
                           \/         \|  \'  / `-._
                                      ||    .'
                                       \\  (
                                        >\  >
                                    ,.-' >.'
                                   <.'_.''
                                     <'

The release will then be downloaded and started by all the devices in the fleet. You can see the progress of the device code updates on the device dashboard:

Service download progress

After the download, you should now have a Node.js web server running on your device and see some logs on your dashboard.

To give your device a public URL, click the Public Device URL toggle on the device dashboard. Public device URL allow you to serve content from the device to the world easily without configuration as long as the server is running on port 80.

Enable public URLs

Follow the URL to view the welcome page with additional resources. Alternatively, you can point your browser to your device's local IP address to access the server running on your device. You can find the device's IP address on the device dashboard page. This is what you should be seeing.

Success screen 1

Developing your project

Now, let's try making some changes to this project and testing them right on the device. The project can be modified and pushed again using the same method as above, but since we are using a development version of the OS, we can enable Local mode and push directly to the device for a faster development cycle.

Activate local mode on the device via the dashboard.

Enable Local Mode

Once enabled, you can now use balena push again, but this time we will push directly to the local IP address of the device obtained via the dashboard.

Local IP address
$ balena push 10.19.0.153

The same build process as before is carried out, but this time instead of using the balena builders, the build takes place locally on the device itself.

[Info]    Streaming device logs...
[Live]    Watching for file changes...
[Live]    Waiting for device state to settle...
[Logs]    [8/26/2021, 11:58:18 AM] Creating network 'default'
[Logs]    [8/26/2021, 11:58:19 AM] Installing service 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:58:20 AM] Installed service 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:58:20 AM] Starting service 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:58:23 AM] Started service 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:58:24 AM] [hello-world] Starting server on port 80
[Live]    Device state settled

The balena CLI will now watch for changes to all the files within the project, and automatically push changes to the device when detected. Let's try making a change to title of our balena welcome page. Navigate to the index.html file present in the static directory of the project. Open the file and change the title from Welcome to balena! to Hello balena! and save the file. After saving the changes, you can observe balena CLI automatically start rebuilding only the parts of the Dockerfile that has been changed.

[Live]    Detected changes for container hello-world, updating...

...

[Live]    [hello-world] Restarting service...
[Logs]    [8/26/2021, 11:59:01 AM, 2:42:32 AM] Service exited 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:59:04 AM, 2:42:35 AM] Restarting service 'hello-world sha256:...'
[Logs]    [8/26/2021, 11:59:05 AM, 2:42:36 AM] [hello-world] Starting server on port 80

When the rebuild is complete, take a look at the public device URL again to see your changes. The welcome page should have been updated with the new title.

Success screen 2

Next steps

Once you've finished making your changes, disable local mode and the device will revert back to running the latest release that's on your fleet. To update your fleet with the latest changes you've just worked on, use balena push <fleet name> once more to create a new release with those changes.

When it's finished building the device(s) will update as before. Remember anything pushed to the fleet in this way can be applied to 10+ or 1000+ devices with no extra effort! To continue learning, explore parts of the guide in more detail:

Enjoy balenafying all the things!