Trying to combine apps, it doesn't work

Hi all,

Note:
I posted this in the Product support category but I think it belongs here. The other post will be deleted

I’am just getting started on Balena here. Using BalenaCloud and the BalenaCLI on my Mac to get the files together and push this to builder to create the images. I made a post before but I sort of hijacked my own post as I did come up with more questions so this new post seemed more prudent.

My idea was to make a generic image for some RPIs, while they not all need the same apps running as they have slightly different purposes. So I can just run the apps I need. This way, I have one fleet with 3 to 5 devices. Otherwise, I need to make more fleets as each RPI has differs slightly and requires slightly different apps to run (let me know if this would be a better approach then my thought).

I tried following the tutorial on this blogpost. This one seems heavily outdated though. When composing the one docker-compose.yml file from merging the two apps named in the description, I noticed in the two original yml-files there is on both of them a section with hostname. This is not mentioned in the blogpost.

Further more, when I merge the apps, I don’t get the containers hostname, multiroom-client and multiroom-server up and running at all. The container sound-supervisor does get up and running but displays a lot of errors.

Sound-supervisor errors
 sound-supervisor  > sound-supervisor@1.0.1 start /usr/src
 sound-supervisor  > node build/index.js
 sound-supervisor  
 sound-supervisor  internal/fs/utils.js:332
 sound-supervisor      throw err;
 sound-supervisor      ^
 sound-supervisor  
 sound-supervisor  Error: ENOENT: no such file or directory, open 'VERSION'
 sound-supervisor      at Object.openSync (fs.js:498:3)
 sound-supervisor      at Object.readFileSync (fs.js:394:35)
 sound-supervisor      at Object.<anonymous> (/usr/src/build/SoundAPI.js:10:20)
 sound-supervisor      at Module._compile (internal/modules/cjs/loader.js:1114:14)
 sound-supervisor      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
 sound-supervisor      at Module.load (internal/modules/cjs/loader.js:979:32)
 sound-supervisor      at Function.Module._load (internal/modules/cjs/loader.js:819:12)
 sound-supervisor      at Module.require (internal/modules/cjs/loader.js:1003:19)
 sound-supervisor      at require (internal/modules/cjs/helpers.js:107:18)
 sound-supervisor      at Object.<anonymous> (/usr/src/build/index.js:5:20) {
 sound-supervisor    errno: -2,
 sound-supervisor    syscall: 'open',
 sound-supervisor    code: 'ENOENT',
 sound-supervisor    path: 'VERSION'
 sound-supervisor  }
 sound-supervisor  npm ERR! code ELIFECYCLE
 sound-supervisor  npm ERR! errno 1
 sound-supervisor  npm ERR! sound-supervisor@1.0.1 start: `node build/index.js`
 sound-supervisor  npm ERR! Exit status 1
 sound-supervisor  npm ERR! 
 sound-supervisor  npm ERR! Failed at the sound-supervisor@1.0.1 start script.
 sound-supervisor  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
 sound-supervisor  
 sound-supervisor  npm ERR! A complete log of this run can be found in:
 sound-supervisor  npm ERR!     /root/.npm/_logs/2024-08-29T14_03_28_280Z-debug.log
 sound-supervisor  
 sound-supervisor  
 sound-supervisor  > sound-supervisor@1.0.1 start /usr/src
 sound-supervisor  > node build/index.js
 sound-supervisor  
 sound-supervisor  internal/fs/utils.js:332
 sound-supervisor      throw err;
 sound-supervisor      ^
 sound-supervisor  
 sound-supervisor  Error: ENOENT: no such file or directory, open 'VERSION'
 sound-supervisor      at Object.openSync (fs.js:498:3)
 sound-supervisor      at Object.readFileSync (fs.js:394:35)
 sound-supervisor      at Object.<anonymous> (/usr/src/build/SoundAPI.js:10:20)
 sound-supervisor      at Module._compile (internal/modules/cjs/loader.js:1114:14)
 sound-supervisor      at Object.Module._extensions..js (internal/modules/cjs/loader.js:1143:10)
 sound-supervisor      at Module.load (internal/modules/cjs/loader.js:979:32)
 sound-supervisor      at Function.Module._load (internal/modules/cjs/loader.js:819:12)
 sound-supervisor      at Module.require (internal/modules/cjs/loader.js:1003:19)
 sound-supervisor      at require (internal/modules/cjs/helpers.js:107:18)
 sound-supervisor      at Object.<anonymous> (/usr/src/build/index.js:5:20) {
 sound-supervisor    errno: -2,
 sound-supervisor    syscall: 'open',
 sound-supervisor    code: 'ENOENT',
 sound-supervisor    path: 'VERSION'
 sound-supervisor  }
 sound-supervisor  npm ERR! code ELIFECYCLE
 sound-supervisor  npm ERR! errno 1
 sound-supervisor  npm ERR! sound-supervisor@1.0.1 start: `node build/index.js`
 sound-supervisor  npm ERR! Exit status 1
 sound-supervisor  npm ERR! 
 sound-supervisor  npm ERR! Failed at the sound-supervisor@1.0.1 start script.
 sound-supervisor  npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
 sound-supervisor  
 sound-supervisor  npm ERR! A complete log of this run can be found in:
 sound-supervisor  npm ERR!     /root/.npm/_logs/2024-08-29T14_04_23_580Z-debug.log

Before I can get a look at the logs it mentions in the error message, the container restarts so a SSH connection is lost and re-established but that all goes too quick to extract the log and it’s content.

Further, if I go to the ip-address of my Raspberry Pi in a browser, I get a 403 error. I am expecting to see at least either Pihole or Balena-sound-dashboard. Constructing an image with purely balena-sound or balena-pihole works without any errors.

I thought if I figure this all out, I have a good base in doing my own setup afterwards. So any help would be appreciated!

Thanks

For reference:

docker-compose.yml merged apps (the one I created)
version: "2"

volumes:
  spotifycache:
  pihole_config:
  dnsmasq_config:
  tailscale:

services:
  audio:
    build: ./core/audio
    privileged: true
    labels:
      io.balena.features.dbus: 1
    ports:
      - 4317:4317

  sound-supervisor:
    build:
      context: .
      dockerfile: ./core/sound-supervisor/Dockerfile.template
    network_mode: host
    labels:
      io.balena.features.balena-api: "1"
      io.balena.features.supervisor-api: 1

  multiroom-server:
    build: ./core/multiroom/server
    restart: on-failure
    ports:
      - 1704:1704
      - 1705:1705
      - 1780:1780

  multiroom-client:
    build: ./core/multiroom/client
    restart: on-failure

  # Plugins
  # -- Additional plugins can be added. See https://balena-sound.pages.dev/plugins
  # -- Remove unwanted plugins as needed
  bluetooth:
    build: ./plugins/bluetooth
    restart: on-failure
    network_mode: host
    cap_add:
      - NET_ADMIN
    labels:
      io.balena.features.dbus: 1

  airplay:
    build: ./plugins/airplay
    restart: on-failure
    network_mode: host
    privileged: true
    labels:
      io.balena.features.dbus: 1

  spotify:
    build: ./plugins/spotify
    restart: on-failure
    privileged: true
    network_mode: host
    volumes:
      - spotifycache:/var/cache/raspotify

#Pihole stuff
  pihole:
    build: ./balena-pihole/pihole
    cap_add:
      - SYS_TTY_CONFIG
      - NET_ADMIN
    volumes:
      - "pihole_config:/etc/pihole"
      - "dnsmasq_config:/etc/dnsmasq.d"
    dns:
      - "127.0.0.1"
      - "1.1.1.1"
    network_mode: host
    labels:
      io.balena.features.dbus: "1"
    devices:
      - /dev/tty0
      - /dev/tty1
    tmpfs:
      - /var/log/pihole
    environment:
      DNSMASQ_LISTENING: all
      PIHOLE_DNS_: 1.1.1.1;1.0.0.1
      FONTFACE: Terminus
      FONTSIZE: 8x14
      WEBPASSWORD: balena
      VIRTUAL_HOST: balena-devices.com
      WEB_BIND_ADDR: 0.0.0.0

  unbound:
    build: ./balena-pihole/unbound
    cap_add:
     - NET_ADMIN
    ports:
      - "5053:5053/tcp"
      - "5053:5053/udp"

  fbcp:
    image: bh.cr/balenalabs/fbcp/1.0.4
    privileged: true

  hostname:
    image: bh.cr/g_tomas_migone1/hostname-rpi/0.2.1
    restart: no
    labels:
      io.balena.features.supervisor-api: 1
    environment:
      SET_HOSTNAME: pihole

  tailscale:
    image: tailscale/tailscale:v1.72.1@sha256:83a6faec34866f70914a7d241d6ca749e6914f08f4f9059d942e1c3088dc001b
    restart: unless-stopped
    environment:
      TS_STATE_DIR: /var/lib/tailscale
      TS_SOCKET: /var/run/tailscale/tailscaled.sock
      TS_USERSPACE: false
      TS_AUTH_ONCE: false
      TS_HOSTNAME: pi-hole
      TS_EXTRA_ARGS: --accept-dns=false --reset
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
      - SYS_MODULE
    labels:
      io.balena.features.kernel-modules: 1
    tmpfs:
      - /tmp
      - /run
    volumes:
      - tailscale:/var/lib/tailscale
    entrypoint:
      - /bin/sh
      - -c
    command:
      - |
        modprobe tun || true
        modprobe wireguard || true
        mkdir -p /dev/net
        [ ! -c /dev/net/tun ] && mknod /dev/net/tun c 10 200
        /usr/local/bin/containerboot
Original docker-compose.yml balena-sound
version: "2"

volumes:
  spotifycache:

services:
  # Core services
  # -- Required for a fully featured installation of balenaSound
  # -- Mutiroom services can be removed if not using multiroom mode
  audio:
    build: ./core/audio
    privileged: true
    labels:
      io.balena.features.dbus: 1
    ports:
      - 4317:4317

  sound-supervisor:
    build:
      context: .
      dockerfile: ./core/sound-supervisor/Dockerfile.template
    network_mode: host
    labels:
      io.balena.features.balena-api: "1"
      io.balena.features.supervisor-api: 1

  multiroom-server:
    build: ./core/multiroom/server
    restart: on-failure
    ports:
      - 1704:1704
      - 1705:1705
      - 1780:1780

  multiroom-client:
    build: ./core/multiroom/client
    restart: on-failure

  # Plugins
  # -- Additional plugins can be added. See https://balena-sound.pages.dev/plugins
  # -- Remove unwanted plugins as needed
  bluetooth:
    build: ./plugins/bluetooth
    restart: on-failure
    network_mode: host
    cap_add:
      - NET_ADMIN
    labels:
      io.balena.features.dbus: 1

  airplay:
    build: ./plugins/airplay
    restart: on-failure
    network_mode: host
    privileged: true
    labels:
      io.balena.features.dbus: 1

  spotify:
    build: ./plugins/spotify
    restart: on-failure
    privileged: true
    network_mode: host
    volumes:
      - spotifycache:/var/cache/raspotify

  # https://github.com/balenablocks/hostname
  hostname:
    build: ./core/hostname
    restart: no
    labels:
      io.balena.features.supervisor-api: 1
    environment:
      SET_HOSTNAME: balena
Original docker-compose.yml balena-pihole
version: "2.1"

volumes:
  pihole_config: {}
  dnsmasq_config: {}
  tailscale: {}

services:
  pihole:
    build: pihole
    cap_add:
      - SYS_TTY_CONFIG
      - NET_ADMIN
    volumes:
      - "pihole_config:/etc/pihole"
      - "dnsmasq_config:/etc/dnsmasq.d"
    dns:
      - "127.0.0.1"
      - "1.1.1.1"
    network_mode: host
    labels:
      io.balena.features.dbus: "1"
    devices:
      - /dev/tty0
      - /dev/tty1
    tmpfs:
      - /var/log/pihole
    environment:
      DNSMASQ_LISTENING: all
      PIHOLE_DNS_: 1.1.1.1;1.0.0.1
      FONTFACE: Terminus
      FONTSIZE: 8x14
      WEBPASSWORD: balena
      VIRTUAL_HOST: balena-devices.com
      WEB_BIND_ADDR: 0.0.0.0

  unbound:
    build: unbound
    cap_add:
     - NET_ADMIN
    ports:
      - "5053:5053/tcp"
      - "5053:5053/udp"

  # https://github.com/balena-labs-projects/fbcp
  # https://hub.balena.io/blocks/1792683/fbcp
  fbcp:
    image: bh.cr/balenalabs/fbcp/1.0.4
    privileged: true

  # https://github.com/balenablocks/hostname
  # https://hub.balena.io/blocks/1918776/hostname-rpi
  hostname:
    image: bh.cr/g_tomas_migone1/hostname-rpi/0.2.1
    restart: no
    labels:
      io.balena.features.supervisor-api: 1
    environment:
      SET_HOSTNAME: pihole

  # https://hub.docker.com/r/tailscale/tailscale
  # https://github.com/tailscale/tailscale/blob/main/cmd/containerboot/main.go
  # https://tailscale.com/kb/1282/docker
  # https://tailscale.com/kb/1278/tailscaled
  # https://tailscale.com/kb/1241/tailscale-up
  # https://tailscale.com/kb/1242/tailscale-serve
  # https://tailscale.com/kb/1311/tailscale-funnel
  tailscale:
    image: tailscale/tailscale:v1.72.1@sha256:83a6faec34866f70914a7d241d6ca749e6914f08f4f9059d942e1c3088dc001b
    restart: unless-stopped
    environment:
      TS_STATE_DIR: /var/lib/tailscale
      TS_SOCKET: /var/run/tailscale/tailscaled.sock
      TS_USERSPACE: false
      TS_AUTH_ONCE: false
      TS_HOSTNAME: pi-hole
      TS_EXTRA_ARGS: --accept-dns=false --reset
    network_mode: host
    cap_add:
      - NET_ADMIN
      - NET_RAW
      - SYS_MODULE
    labels:
      io.balena.features.kernel-modules: 1
    tmpfs:
      - /tmp
      - /run
    volumes:
      - tailscale:/var/lib/tailscale
    entrypoint:
      - /bin/sh
      - -c
    command:
      - |
        modprobe tun || true
        modprobe wireguard || true
        mkdir -p /dev/net
        [ ! -c /dev/net/tun ] && mknod /dev/net/tun c 10 200
        /usr/local/bin/containerboot