This guide will walk you through the steps of deploying an openBalena server, that together with the 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 and others.
This guide assumes a setup with two separate machines:
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
Clone the openBalena project to the home directory:
$ 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 below.
This will create a new directory,
config, and generate appropriate SSL certificates and
configuration for the server. 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 server 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 server with:
$ systemctl start docker $ ./scripts/compose up -d
-d argument run the docker containers as a background process.
You can stop the server with:
$ ./scripts/compose stop
A few CNAME records must be configured to point to the openBalena server:
api.mydomain.com registry.mydomain.com vpn.mydomain.com s3.mydomain.com
Check with your internet domain name registrar for instructions on how to configure CNAME records.
Follow the balena CLI installation instructions to install the balena CLI on the local machine, e.g. your laptop.
At the moment, please install balena CLI version 12.2.2 rather than the latest version, for full compatibility with openBalena. (Work is ongoing to allow the latest CLI version to be used.)
The installation of the openBalena server produces a few self-signed certificates, including a
ca.crt file. In this guide, the openBalena server is installed in
~/open-balena/, so the
ca.crt file will be found at
~/open-balena/config/certs/root/ca.crt (on the server).
ca.crt file from the server to the local machine, then install it with the following
$ 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 on the local machine 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.
Point the balena CLI to your server by setting
balenaUrl to the server domain name in the CLI
configuration file (create a new file if it does not yet exist):
Linux or macOS:
In addition, set an environment variable that points to the copy of the
ca.crt file on the local
The commands below should be run on a command prompt / terminal on the local machine (where the balena CLI was installed). Ensure that the NODEEXTRACA_CERTS environment variable mentioned above is set.
balena login, select
Credentials and use the super user information generated previously.
Create the 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 server. 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 server 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
The next step is to deploy some code. There is no balenaCloud builder service in openBalena, and application images are built on the local machine using the balena CLI, backed by Docker.
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.