This guide will walk you through the steps of deploying an openBalena server, that together with balena CLI will enable you to create and manage your device fleet running on your own infrastructure, on any VPS such as AWS, Google Cloud, Digital Ocean or any other VPS provider.
For this we are going to setup a bare Ubuntu 18.04 x64 server.
Before we get started setting up our balena environment, first we need to install a few tools and make sure our machine is up to date.
Log into your new server:
$ ssh root@your_server_ip
Update all initial software:
$ apt-get update && apt-get install -y build-essential git
Create a balena user:
$ adduser balena
Add user admin permission:
$ usermod -aG sudo balena
$ apt-get install docker.io
balena user to
$ usermod -aG docker balena
$ curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose $ chmod +x /usr/local/bin/docker-compose
Test your docker-compose installation with
$ docker-compose --version.
Install OpenSSL, nodejs and NPM
$ apt-get install libssl-dev nodejs npm
With all the required software installed, we can go ahead and install openBalena.
Clone openBalena project to your home folder with:
$ git clone https://github.com/balena-io/open-balena.git ~/open-balena $ cd open-balena/
open-balena directory, run the
quickstart script with the command mentioned below. This will create a new directory,
config, and generate appropriate SSL certificates and configuration for the instance. The email and password provided will be used to create the superuser account, which you will use to authenticate against the system.
$ ./scripts/quickstart -U <email@address> -P <password>
You may optionally configure the instance to run under a custom domain name. The default is
openbalena.local. In this guide we will setup using the domain
mydomain.com, so in this case we will use:
$ ./scripts/quickstart -U <email@address> -P <password> -d mydomain.com
For more available options, see the script's help:
$ ./scripts/quickstart -h
At this point we are ready to start our openBalena instance with:
$ systemctl start docker $ ./scripts/compose up -d
-d argument run the docker containers as a background process.
You can stop the instance with:
$ ./scripts/compose stop
In order to be able to reach your openBalena instance, a few CNAME addresses must to be configured and pointing to your server.
api.mydomain.com registry.mydomain.com vpn.mydomain.com s3.mydomain.com
After getting the openBalena server up and running, we need to install in our local machine the balena CLI, a command-line interface that will be used to manage all the devices and be the link between you and the server.
Point balena CLI to your server by setting
balenaUrl to the server domain name
in the CLI configuration file. If this file doesn't exist, then create it e.g.:
Linux or macOS:
When we create the openBalena instance, it generated a few self-signed certificates that we will need to use in order for our local machine and devices to connect to the server.
On the computer you installed balena CLI (the local machine), download the
from the server and install it. In our current example, the openBalena instance is installed on
~/open-balena/ so the certificate will be in
$ sudo cp ca.crt /usr/local/share/ca-certificates/ca.crt $ sudo update-ca-certificates $ sudo systemctl restart docker
$ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/ca.crt $ osascript -e 'quit app "Docker"' && open -a Docker
$ certutil -addstore -f "ROOT" ca.crt
IMPORTANT: You must restart the Docker daemon for it to pick up your newly trusted CA certificate. Without restarting Docker you will not be able to push images to the openBalena registry.
Additionally, instruct the balena CLI to use the new certificate by setting an environment
variable that points to the downloaded copy of the
ca.crt file on the local machine:
At this point, we can log in to our server and create our first application.
balena login, select
Credentials and use the super user information generated previously.
Now we can create our first application with
balena app create myApp
From there you will be able to select which device you will be working with, for example a Raspberry Pi 3.
Before moving on, lets make sure we have our application created
$ balena apps ID APP NAME DEVICE TYPE ONLINE DEVICES DEVICE COUNT 1 myApp raspberrypi3
Once we have some apps it’s time to start provisioning devices into them, to do this we need to first download an balenaOS image for our device type from https://balena.io/os . As we are deploying a Raspberry Pi 3 device, we can go to https://balena.io/os/#downloads-raspberrypi and download the image for it.
After having downloaded the operating system image, unzip it somewhere locally, and then use the balena CLI to configure it for our openBalena instance. This can be done as follows:
$ balena os configure ~/Downloads/balenaos-raspberrypi3-2.22.1+rev1-dev-v7.25.3.img --app myApp
Once the image is configured with network credentials and keys to connect to our openBalena instance we can use https://etcher.io to flash it onto our SD card and then boot the device up.
After about 30 seconds we should be able to see our newly provisioned device in our app, to do this we run
$ balena devices ID UUID DEVICE NAME DEVICE TYPE APPLICATION NAME STATUS IS ONLINE SUPERVISOR VERSION OS VERSION 4 59d7700 winter-tree raspberrypi3 myApp Idle true 7.25.3 balenaOS 2.22.1+rev1
If we want to inspect the device more closely we can use the devices UUID as follows:
$ balena device 59d7700 == WINTER TREE ID: 4 DEVICE TYPE: raspberrypi3 STATUS: online IS ONLINE: true IP ADDRESS: 192.168.43.247 APPLICATION NAME: myApp UUID: 59d7700755ec5de06783eda8034c9d3d SUPERVISOR VERSION: 7.25.3 OS VERSION: balenaOS 2.22.1+rev1
Alright, so we have some devices setup and connected to our openBalena instance, now its time deploy some code. In openBalena, there is no cloud builder service, so all of the building of containers needs to happen locally with the CLI.
For this example, we will deploy an example project using a Raspberry Pi 3 and a Sense Hat from https://github.com/balena-io-playground/sense-snake.
Lets clone this repo to our computer and push it to the device we just provisioned:
$ git clone https://github.com/balena-io-playground/sense-snake.git $ cd sense-snake/ $ balena deploy myApp --logs --source . --emulated
Note that in the deploy code above we added
--emulated to the end, this is because we are building a container for the Raspberry Pi, which has an ARM architecture while our local machine uses an x86_64 architecture.
[Info] Compose file detected [Info] Everything is up to date (use --build to force a rebuild) [Info] Creating release... [Info] Pushing images to registry... [Info] Saving release... [Success] Deploy succeeded! [Success] Release: f62a74c220b92949ec78761c74366046 \ \ \\ \\ >\/7 _.-(6' \ (=___._/` \ ) \ | / / | / > / j < _\ _.-' : ``. \ r=._\ `. <`\\_ \ .`-. \ r-7 `-. ._ ' . `\ \`, `-.`7 7) ) \/ \| \' / `-._ || .' \\ ( >\ > ,.-' >.' <.'_.'' <'
After seeing the unicorn, we can grab some coffee while the code is pushed to the device. In a couple minutes you will notice that the code will start running on our Raspberry Pi.