Building a machine to develop on.

Hello, i’m very new to balena and using containers. But i have been creating projects on raspberry pi for years usually with python. But they are usually one off projects as prototypes so im not really familiar with using development workflows. But i want to start making my projects more repeatable.

So i want to start by creating a machine to develop projects on. I think that i want to deploy the development machines itself using Balena and all i need on the machine is github, balena cli and docker.

But i can’t quite get my head around how to do this. Do i need a balena image that has these tools on already?

Any pointers or resources you can point me at are greatly appreciated.

1 Like

Hello @peteoheat first of all welcome to the balena community! here we are to help you :slight_smile:

Actually we had a private conversation with @keenanjohnson @nmaas87 @maggie0002 @barryjump @SnoWake and @ajlennon some months ago related with the development worklows recommendations. Actually i’m sure @shawaj or @vpetersson can give some suggestions.

Looking forwar to read all your good ideas in the public to inspire other developers.

Hello! It’s great to hear that you’re interested in using Balena to create more repeatable projects. Balena can indeed be a useful tool for managing and deploying your projects.

To set up a development machine using Balena, you can follow these general steps:

  1. Choose a base operating system: Balena supports various base operating systems, such as balenaOS, which is a minimal Linux distribution optimized for containers. You can select a suitable base operating system for your development machine.
  2. Create a Dockerfile: In order to include the necessary tools like GitHub, Balena CLI, and Docker on your development machine, you’ll need to create a Dockerfile. This file defines the steps to build your custom container image. Here’s a basic example of a Dockerfile:

DockerfileCopy code

FROM balenalib/<base-os>:<version>

RUN apt-get update && apt-get install -y \
    git \
    balena-cli \
    docker.io

# Additional configuration or customization if needed

CMD ["/bin/bash"]

In this example, <base-os> refers to the base operating system you selected in step 1 (e.g., debian, ubuntu, etc.). <version> is the version of the base operating system you want to use.
3. Build and deploy the container: Once you have your Dockerfile, you can build the container image using the Docker CLI or Balena CLI. Here’s an example command using Balena CLI:

perlCopy code

balena build -t my-development-machine .

This command builds the container image using the Dockerfile in the current directory and assigns it the tag my-development-machine.
4. Deploy the container image: After building the container image, you can deploy it to your development machine using Balena. You’ll need to set up a Balena application and add your development machine as a device within that application. Then, push your container image to the Balena application, and it will be deployed to your development machine.

These are the general steps to get started with setting up a development machine using Balena. You can find more detailed information and resources in the Balena documentation, specifically the “Getting Started” guide and the documentation on building and deploying containers.

I hope this helps you get started with using Balena for your development workflows. If you have any further questions, feel free to ask!

1 Like

Thanks you, this was a helpful starter. After a lot of trial and error, I’ve had some success with the following docker file. I found that balena-cli was not available from the Debian Bullseye APT repository and couldn’t find any repository I could add that had it. For a while I messed with installing it via npm and finally settled on simple wget and unzip.

FROM balenalib/aarch64-debian:bullseye-build

RUN apt-get update && apt-get install -y \
    git \
    curl \
	python3 \
	g++ \
	unzip \
    docker.io

RUN wget https://github.com/balena-io/balena-cli/releases/download/v16.1.0/balena-cli-v16.1.0-linux-arm64-standalone.zip -O temp.zip && unzip temp.zip && rm temp.zip

CMD ["/bin/bash"]

Next to get the git and balena cli’s to login using credentials

The workflow I find that works best for me is something like this (though I’m still developing it and tweaking for each new project):

  • Start by developing code locally inside of a docker container using the incredibly awesome VSCode Dev containers feature. See an example of this that I developed here for ros2. . Developing inside this container has several benefits:
    • It largely eliminates the “Works on my machine problem” when working with a team and allows me to know that I’m using consistent versions of things like python, os libs, etc.
    • It also means that I’m set up to fairly easily deploy to balena later
  • Once I have good confidence in the good and ideally some good automated tests set up in the local container, my next step is pushing the docker container to some sort of CI system (ex: Github actions). I find this key for the longevity of any project and with the free price of github actions, there really is no excuse for any project not to do this anymore. One of the key aspects of CI is that I can use dockerx to build for multiple architectures, which is a key prerequisite for deploying to balena later
  • If the project has multiple containers, I develop each one separately using the workflow above first and get good unit and integration tests for each, then I move towards testing in an integrated fashion.
  • Ideally I try to test by running all the containers together locally first, but often there is some hardware dependency that my local machine can’t meet which prevents me from truly testing well. So I generally move straight to deploying onto a balena target.
  • I find I like to deploy using the local mode, though sometimes this does mean a lot of time waiting for things to recompile.
  • If I have a lot of debugging to do, specifically with some sort of weird hardware or sensor interaction, I have set up shared filesystems as you have linked to above @maggie0002, however, it’s sort of a pain to configure, so I don’t usually do it at the beginning of a project.
  • Once things are generally working well with the first few deploys, I always try to set up a test fleet and make sure things still work in the fleet. There are a lot of fleet configuration settings, variables, etc that can in practice break things in the fleet setting. For any serious projects, I have both a testing fleet and a production fleet.

@keenanjohnson, I had moved towards balenaVirt instead of the container solution so I was closer to on-device development from the outset and could use multi-container solutions in the balena ecosystem: GitHub - balena-labs-research/balena-virt: Easy virtualization of balenaOS

I would then mount the filesystem locally with this: GitHub - balena-labs-research/go-cli: balena CLI developer tools in Golang

Was all in very early stages though, would be fun to play around with but not a fully rounded solution yet.

1 Like

Oh interesting @maggie0002 !

1 Like