Local mode is the development mode for balena. It allows you to build and sync code to a single development device in your local network without having to go through the balenaCloud build service and deployment pipeline. It uses the Docker daemon on the device to build container images, and then the device Supervisor starts the containers in the same way as if they were deployed via the cloud.
Local mode requirements
To use local mode on a device:
- The device must be running balenaOS v2.29.0 or higher.
- The device must be running a development variant of the OS.
- You must have the balena CLI installed on your development machine.
- Local mode must be enabled through the balenaCloud dashboard. You can enable it from the device Settings tab.
Local mode caveats
- In local mode, a device will not send logs back to the balenaCloud dashboard. Refer to the local mode logs section to view logs in local mode.
- Device and service environment variables set from the balenaCloud will not be applied to local mode containers. It is still possible to set environment variables in your
- Changes to device configuration, for example,
BALENA_HOST_CONFIG_gpu_mem, will result in the device rebooting and applying those settings.
- Actions such as Restart and Purge data from the balenaCloud dashboard will not apply to local mode containers.
- When switching out of local mode and back to tracking releases from balenaCloud, the Supervisor will destroy any local mode containers and volumes, as well as clean up unneeded base images, and then start the release that balenaCloud instructs it to run.
Scan the network and find your device
Before you can get your app running on your device in local mode, you have to find your device. You can find the
short-uuid and local IP address of the device from the device dashboard or by scanning the network. To perform a scan, login to the balena CLI and use
balena scan to find any local balenaOS devices. All balenaOS devices advertise themselves on the network using Avahi. The names take the form
<short-uuid>.local, where the
short-uuid is the UUID you see on your device dashboard.
Note: You may need administrator privileges to run
balena scan as it requires access to all network interfaces.
sudo balena scan
Reporting scan results - host: 63ec46c.local address: 192.168.86.45 dockerInfo: Containers: 1 ContainersRunning: 1 ContainersPaused: 0 ContainersStopped: 0 Images: 4 Driver: aufs SystemTime: 2020-01-09T21:17:11.703029598Z KernelVersion: 4.19.71 OperatingSystem: balenaOS 2.43.0+rev1 Architecture: armv7l dockerVersion: Version: 18.09.8-dev ApiVersion: 1.39
Push over a new project
When local mode has been activated, balena CLI can push code directly to the local device instead of going via the balenaCloud builders. As code is built on the device and then executed, this can significantly speed up development when requiring frequent changes. To do this, we use the
balena push command providing either the local IP address or
<short-uuid>.local, obtained from the preceding
balena scan command.
Note: By default
balena push will build from the current working directory, but it is also possible to specify the project directory via the
Once the code has been built on the device, it immediately starts executing, and logs are output to the console. At any time, you can disconnect from the local device by using
Ctrl-C. Note that after disconnection, the services on the device will continue to run.
balena push 63ec46c.local
Local mode also has another huge benefit, known as Livepush. Livepush makes intelligent decisions on how, or even if, to rebuild an image when changes are made. Instead of creating a new image and container with every code change, the Dockerfile commands are executed from within the running container. This means that, for example, if you added a dependency to your
package.json, rather than having to install all of the dependencies again, only the new dependency would be installed.
When a source file is modified, the Supervisor will immediately detect the change and then either rebuild the image or, for source files that run in-service, replace the changed files in situ in the relevant container layer and restart the service. As this happens in a few seconds, it makes the process of developing much faster and more convenient.
[Live] Detected changes for container main, updating... [Live] [main] Restarting service..
Note: You can disable Livepush by passing the
--nolive option to
balena push. In this case to rebuild on the device you will need to perform another
Local mode logs
By default, when pushing code to a device in local mode using the balena CLI, the logs will be output to the console. You can prevent this by passing the
-d) option to the
balena push command (you may also detach the console at any time by pressing
balena push 63ec46c.local --detached
When detached, the services continue to run on the device, and you can access the logs using the
balena logs command, again passing the local IP address or
balena logs 63ec46c.local
This command will output logs for the system and all running services. You may optionally filter the output to include only system or specific service logs using the available
-s) options. For example, to output only the system logs:
balena logs 63ec46c.local --service <service name>
To filter logs by a service, use the
--service option. You may specify this option multiple times to output logs from multiple services.
balena logs 63ec46c.local --service main balena logs 63ec46c.local --service first --service second
These options can be combined to output system and selected service logs e.g.
balena logs 827b231.local --system --service first --service second
Note: You may also specify the
--system options using the
balena push command to filter the log output.
SSH into the running app container or host OS
To access the local device over SSH, use the
balena ssh command specifying the device IP address or
<short-uuid>.local. By default, SSH access is routed into the host OS shell and, from there, we can check system logs and perform other troubleshooting tasks:
balena ssh 192.168.86.45
To connect to a container, we can specify the service name e.g.
sudo balena ssh 63ec46c.local my-service
Note: If an IP address or a
.local hostname is used (instead of a fleet name or device UUID),
balena ssh establishes a direct connection to the device on port
22222 that does not rely on cloudlink.
Using a Private Docker Registry
If your project relies on a private base image, then it is possible to specify your registry credentials when doing a
balena push by passing the
--registry-secrets option, as shown below.
balena push 192.168.86.45 --registry-secrets /Path/To/File/dockerhub-secret.yml
dockerhub-secret.yml is a YAML file containing my private registry usernames and passwords to be used by the device balenaEngine when pulling base images during a build.
Sample secrets YAML file:
'https://index.docker.io/v2/': username: johnDoe password: myPassword