GithubHelp home page GithubHelp logo

klutchell / balena-cli-docker Goto Github PK

View Code? Open in Web Editor NEW
1.0 3.0 2.0 4.79 MB

Unofficial Docker images with the balena CLI and Docker-in-Docker

Home Page: https://hub.docker.com/r/klutchell/balena-cli/

Dockerfile 57.28% Shell 42.72%
balena cli docker

balena-cli-docker's Introduction

balena-cli-docker

Unofficial Docker images with the balena CLI and Docker-in-Docker.

Environment Variables

These environment variables are available for additional functionality included in the CLI image. In most cases these are optional, but some examples will highlight when environment variables are required.

  • -e "SSH_PRIVATE_KEY=$(</path/to/priv/key)": copy your private SSH key file contents as an environment variable
  • -e "DOCKERD=1": enable the included Docker-in-Docker daemon (requires --privileged)
  • -e "DOCKERD_EXTRA_ARGS=--key=val": provide additional args for the Docker-in-Docker daemon

Volumes

Volumes can be used to persist data between instances of the CLI container, or to share files between the host and the container. In most cases these are optional, but some examples will highlight when volumes are required.

  • -v "balena_data:/root/.balena": persist balena credentials and downloads between instances
  • -v "docker_data:/var/lib/docker": persist cache between instances when using Docker-in-Docker (requires -e "DOCKERD=1")
  • -v "$PWD:$PWD" -w "$PWD": bind mount your current working directory in the container to share app sources or balenaOS image files
  • -v "${SSH_AUTH_SOCK}:/ssh-agent": bind mount your host ssh-agent socket with preloaded SSH keys
  • -v "/var/run/docker.sock:/var/run/docker.sock": bind mount your host Docker socket instead of Docker-in-Docker

Build

This example is not published on any repo so you'll need to build it yourself.

# enable docker buildkit and experimental mode
export DOCKER_BUILDKIT=1
export DOCKER_CLI_EXPERIMENTAL=enabled

# build local image for native platform
docker build . --tag balena-cli

# enable QEMU for arm emulation
docker run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset -p yes

# cross-build for another platform
docker buildx build . --tag balena-cli --platform linux/arm/v7

Usage

Here are some examples of common CLI commands and how they are best used with this image, since some special considerations must be made.

  • login - login to balena
  • push - start a build on the remote balenaCloud build servers, or a local mode device
  • logs - show device logs
  • ssh - SSH into the host or application container of a device
  • apps - list all applications
  • app - display information about a single application
  • devices - list all devices
  • device - show info about a single device
  • tunnel - tunnel local ports to your balenaOS device
  • preload - preload an app on a disk image (or Edison zip archive)
  • build - build a project locally
  • deploy - deploy a single image or a multicontainer project to a balena application
  • join - move a local device to an application on another balena server
  • leave - remove a local device from its balena application
  • scan - scan for balenaOS devices on your local network

login

The balena login command can't be used with web authorization and a browser when running in a container. Instead it must be used with --token or --credentials.

Notice that here we've used a named volume balena_data to store credentials for future runs of the CLI image. This is optional but avoids having to run the login command again every time you run the image.

$ docker volume create balena_data
$ docker run --rm -it -v "balena_data:/root/.balena" balena-cli /bin/bash
    
> balena login --credentials --email "[email protected]" --password "secret"
> balena login --token "..."
> exit

push

In this example we are mounting your current working directory into the container with -v "$PWD:$PWD" -w "$PWD". This will bind mount your current working directory into the container at the same absolute path.

This bind mount is required so the CLI has access to your app sources.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "$PWD:$PWD" -w "$PWD" \
    balena-cli /bin/bash

> balena push myApp --source .
> balena push 10.0.0.1 --env MY_ENV_VAR=value --env my-service:SERVICE_VAR=value
> exit

logs

$ docker run --rm -it -v "balena_data:/root/.balena" \
    balena-cli /bin/bash

> balena logs 23c73a1 --service my-service
> balena logs 23c73a1.local --system --tail
> exit

ssh

The balena ssh command requires an existing SSH key added to your balenaCloud account.

One way to make this key available to the container is to pass the private key file contents as an environment variable.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -e "SSH_PRIVATE_KEY=$(</path/to/priv/key)" \
    balena-cli /bin/bash

> balena ssh f49cefd
> balena ssh f49cefd my-service
> balena ssh 192.168.0.1 --verbose
> exit

Another way to share SSH keys with the container is to mount your SSH agent socket with keys preloaded.

$ eval ssh-agent
$ ssh-add /path/to/priv/key

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "${SSH_AUTH_SOCK}:/ssh-agent" \
    balena-cli /bin/bash

> balena ssh f49cefd
> balena ssh f49cefd my-service
> balena ssh 192.168.0.1 --verbose
> exit

app | apps

$ docker run --rm -it -v "balena_data:/root/.balena" \
    balena-cli /bin/bash

> balena apps
> balena app myorg/myapp
> exit

device | devices

$ docker run --rm -it -v "balena_data:/root/.balena" \
    balena-cli /bin/bash

> balena devices --application MyApp
> balena device 7cf02a6
> exit

tunnel

The balena tunnel command is easiest used when the host networking stack can be shared with the container and ports can be easily assigned.

However the host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.

Instead you can bind specific port ranges to the host so you can access the tunnel from outside the container via localhost:[localPort].

Note that when exposing individual ports, you must specify all interfaces in the format [remotePort]:0.0.0.0:[localPort] otherwise the tunnel will only be listening for connections within the container.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -p 22222:22222 \
    -p 12345:54321
    balena-cli /bin/bash

> balena tunnel 2ead211 -p 22222:0.0.0.0
> balena tunnel myApp -p 54321:0.0.0.0:12345
> exit

If you have host networking available then you do not need to specify ports in your run command, and the interface 0.0.0.0 is optional in your tunnel command.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    --network host \
    balena-cli /bin/bash

> balena tunnel 2ead211 -p 22222
> balena tunnel myApp -p 54321:12345
> exit

preload

The balena preload command requires access to a Docker client and daemon.

The easiest way to run this command is to use the included Docker-in-Docker daemon.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "docker_data:/var/lib/docker" \
    -e "DOCKERD=1" --privileged \
    balena-cli /bin/bash

> balena os download raspberrypi3 -o raspberry-pi.img
> balena os configure raspberry-pi.img --app MyApp
> balena preload raspberry-pi.img --app MyApp --commit current
> exit

Another way to run the preload command is to use the host OS Docker socket and avoid starting a Docker daemon in the container. This is achieved with -v "/var/run/docker.sock:/var/run/docker.sock".

In this example we are mounting your current working directory into the container with -v "$PWD:$PWD" -w "$PWD". This will bind mount your current working directory into the container at the same absolute path.

This bind mount is required when using the host Docker socket because the absolute path to the balenaOS image file must be the same from both the perspective of the CLI in the container and the host Docker socket.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "/var/run/docker.sock:/var/run/docker.sock" \
    -v "$PWD:$PWD" -w "$PWD" \
    balena-cli /bin/bash

> balena os download raspberrypi3 -o raspberry-pi.img
> balena os configure raspberry-pi.img --app MyApp
> balena preload raspberry-pi.img --app MyApp --commit current
> exit

build | deploy

The build and deploy commands both require access to a Docker client and daemon.

The easiest way to run these commands is to use the included Docker-in-Docker daemon.

In this example we are mounting your current working directory into the container with -v "$PWD:$PWD" -w "$PWD". This will bind mount your current working directory into the container at the same absolute path.

This bind mount is required so the CLI has access to your app sources.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "docker_data:/var/lib/docker" \
    -e DOCKERD=1 --privileged \
    -v "$PWD:$PWD" -w "$PWD" \
    balena-cli /bin/bash

> balena build --application myApp
> balena deploy myApp
> exit

Another way to run the build and deploy commands is to use the host OS Docker socket and avoid starting a Docker daemon in the container. This is achieved with -v "/var/run/docker.sock:/var/run/docker.sock".

In this example we are mounting your current working directory into the container with -v "$PWD:$PWD" -w "$PWD". This will bind mount your current working directory into the container at the same absolute path.

This bind mount is required so the CLI has access to your app sources.

$ docker run --rm -it -v "balena_data:/root/.balena" \
    -v "/var/run/docker.sock:/var/run/docker.sock" \
    -v "$PWD:$PWD" -w "$PWD" \
    balena-cli /bin/bash

> balena build --application myApp
> balena deploy myApp
> exit

join | leave

$ docker run --rm -it -v "balena_data:/root/.balena" \
    balena-cli /bin/bash

> balena join balena.local --application MyApp
> balena leave balena.local
> exit

scan

The balena scan command requires access to the host network interface in order to bind and listen for multicast responses from devices.

However the host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server.

docker run --rm -it --network host balena-cli scan

balena-cli-docker's People

Contributors

dependabot[bot] avatar klutchell avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

balena-cli-docker's Issues

alpine/arm64 fails on ffi-napi node-gyp-build

May need to open an issue on the node-ffi-napi project as it fails as a standalone pip install (without balena-cli).

https://github.com/node-ffi-napi/node-ffi-napi

Possibly a complication of musl + arm64 (+ qemu)?

#6 172.9 /usr/lib/gcc/aarch64-alpine-linux-musl/9.3.0/../../../../aarch64-alpine-linux-musl/bin/ld: Release/obj.target/deps/libffi/libffi.a(ffi.o): in function `ffi_prep_closure_loc':
#6 172.9 ffi.c:(.text+0xb60): undefined reference to `ffi_data_to_code_pointer'
#6 172.9 /usr/lib/gcc/aarch64-alpine-linux-musl/9.3.0/../../../../aarch64-alpine-linux-musl/bin/ld: Release/obj.target/ffi_bindings.node: hidden symbol `ffi_data_to_code_pointer' isn't defined
#6 172.9 /usr/lib/gcc/aarch64-alpine-linux-musl/9.3.0/../../../../aarch64-alpine-linux-musl/bin/ld: final link failed: bad value
#6 172.9 collect2: error: ld returned 1 exit status
#6 172.9 make: *** [ffi_bindings.target.mk:150: Release/obj.target/ffi_bindings.node] Error 1
#6 172.9 make: Leaving directory '/usr/src/app/node_modules/ffi-napi/build'

add CI/CD (test, build, push)

This repo could benefit from some automatic test/build/push actions, either via Github Actions or some other CI/CD.

I already have the templates for GA, I just want to get some feedback on which tools/repos to use before proceeding.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.