Install IOTstack on a Mac Mini

Let me help you install IOTstack on a Mac Mini. Why? Just because you can? Well, maybe. The true motivation, however, is that I had an un(der)used late 2012 Mac Mini at home that looked to be perfectly suited to run a few Docker containers.

The IOTstack README introduces the project like this:

IOTstack is a builder for docker-compose to easily make and maintain IoT stacks on the Raspberry Pi.

Motivation

Indeed, I had previously run, but hardly used, IOTstack on a Raspberry Pi. However, due to the global chip shortage RPis are hard to come by these days. Used ones sell for astronomical sums on second hand sites. The internet is full of articles evaluating Raspberry Pi alternatives. Yet, none mention that you can get excellent second had Mac Minis for little money. But… the IOTstack documentation does not mention how to set it up on alternative hardware.

So, with no Raspberry Pi to spare and no documentation how to install IOTstack on a Mac Mini I was not sure how far I would get. On the other hand, isn’t IOTstack “just” a collection of opinionated Docker Compose recipes that should run on any system that runs Docker?

Install IOTstack on a Mac Mini

macOS preparation

There are number of pieces to this puzzle that you need to install on the Mac Mini before you can start installing IOTstack.

  • Update macOS to the latest available version for the Mac Mini. For the late 2012 model Catalina is the last supported OS version. Sure, there are ways to work around Apple’s policies and install later versions but I saw no need to here.
  • Install Docker (Desktop) but WATCH OUT! The latest supported version for Catalina is 4.15.0. The next version removed support for Catalina without prior notice and no hint in the release notes. Also, I recommend you turn off auto-updates as Docker would otherwise update itself to death.
  • Install Homebrew – the missing package manager for Mac.
  • Using Homebrew install Python (3.x) and virtualenv.
  • Install Git, either standalone or through the Xcode Command Line Tools (again, using Homebrew).
  • IOTstack relies on Whiptail to render dialogs for its visual installation process. Whiptail, however, ist not available for macOS. Hence, what you want to do is create a whiptail alias for dialog which, you guessed it, you install using Homebrew.

Install IOTstack

Finally, time to install IOTstack. On the Pi you would install it into the home folder of the standard pi user. On the Mac I installed it into the home folder of an admin user. Whether admin privileges are required I do not know.

The first steps where smooth sailing.

$ git clone https://github.com/SensorsIot/IOTstack.git ~/IOTstack
$ cd ~/IOTstack
$ pip install -r requirements-menu.txt
$ ./menu.sh

Then all hell broke loose on my machine. If it works for you then skip ahead.

Checking for project update
From https://github.com/SensorsIot/IOTstack
 * branch            master     -> FETCH_HEAD
Project is up to date
User is NOT in 'docker' group
!! You might experience issues with docker or bluetooth. To fix run: ./menu.sh --run-env-setup
Python virtualenv found.
Python Version: 'Python 3.10.9'. Python and virtualenv is up to date.
Please enter sudo pasword if prompted
Command: docker version -f "{{.Server.Version}}"
Docker version 20.10.21 >= 18.2.0. Docker is good to go.
Project dependencies up to date

Existing installation detected.
Creating python virtualenv for menu...
Installing menu requirements into the virtualenv...
  error: subprocess-exited-with-error
  
  × python setup.py bdist_wheel did not run successfully.
  │ exit code: 1
  ╰─> [25 lines of output]
      sys.argv ['/private/var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/pip-install-87_0vwhx/ruamel-yaml-clib_e4463b8ccc374758841c1a9f4782b10d/setup.py', 'bdist_wheel', '-d', '/private/var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/pip-wheel-ozuupoac']
      test compiling /var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/tmp_ruamel_57mervj8/test_ruamel_yaml.c -> test_ruamel_yaml OK
      /Users/gatekeeper/IOTstack/.virtualenv-menu/lib/python3.11/site-packages/setuptools/dist.py:285: SetuptoolsDeprecationWarning: The namespace_packages parameter is deprecated, consider using implicit namespaces instead (PEP 420).
        warnings.warn(msg, SetuptoolsDeprecationWarning)
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.macosx-10.15-x86_64-cpython-311
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel
      copying .ruamel/__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml
      copying .ruamel/yaml/__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      copying ./__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      copying ./LICENSE -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      running build_ext
      building '_ruamel_yaml' extension
      creating build/temp.macosx-10.15-x86_64-cpython-311
      clang -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -I/Users/gatekeeper/IOTstack/.virtualenv-menu/include -I/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/include/python3.11 -c _ruamel_yaml.c -o build/temp.macosx-10.15-x86_64-cpython-311/_ruamel_yaml.o
      _ruamel_yaml.c:198:12: fatal error: 'longintrepr.h' file not found
        #include "longintrepr.h"
                 ^~~~~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for ruamel.yaml.clib
  error: subprocess-exited-with-error
  
  × Running setup.py install for ruamel.yaml.clib did not run successfully.
  │ exit code: 1
  ╰─> [27 lines of output]
      sys.argv ['/private/var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/pip-install-87_0vwhx/ruamel-yaml-clib_e4463b8ccc374758841c1a9f4782b10d/setup.py', 'install', '--record', '/private/var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/pip-record-itkp1hji/install-record.txt', '--single-version-externally-managed', '--compile', '--install-headers', '/Users/gatekeeper/IOTstack/.virtualenv-menu/include/site/python3.11/ruamel.yaml.clib']
      test compiling /var/folders/8l/dr_qb7v56g5gk6vj818zx1z40000gn/T/tmp_ruamel_dvuwa8o_/test_ruamel_yaml.c -> test_ruamel_yaml OK
      /Users/gatekeeper/IOTstack/.virtualenv-menu/lib/python3.11/site-packages/setuptools/dist.py:285: SetuptoolsDeprecationWarning: The namespace_packages parameter is deprecated, consider using implicit namespaces instead (PEP 420).
        warnings.warn(msg, SetuptoolsDeprecationWarning)
      running install
      /Users/gatekeeper/IOTstack/.virtualenv-menu/lib/python3.11/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      creating build
      creating build/lib.macosx-10.15-x86_64-cpython-311
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel
      copying .ruamel/__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml
      copying .ruamel/yaml/__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml
      creating build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      copying ./__init__.py -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      copying ./LICENSE -> build/lib.macosx-10.15-x86_64-cpython-311/ruamel/yaml/clib
      running build_ext
      building '_ruamel_yaml' extension
      creating build/temp.macosx-10.15-x86_64-cpython-311
      clang -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -I/Users/gatekeeper/IOTstack/.virtualenv-menu/include -I/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/include/python3.11 -c _ruamel_yaml.c -o build/temp.macosx-10.15-x86_64-cpython-311/_ruamel_yaml.o
      _ruamel_yaml.c:198:12: fatal error: 'longintrepr.h' file not found
        #include "longintrepr.h"
                 ^~~~~~~~~~~~~~~
      1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> ruamel.yaml.clib

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

I had no idea what the root cause for the error(s) was, but I was irritated to see virtualenv mentioning python3.11 in the output – I had installed Python 3.10. Turns out that the virtualenv Homebrew formula depends on Python 3.11, yet when you install the latest stable Python formula you get 3.10. Scrolling through the virtualenv formula’s Git history you realize that the last version still depending on Python 3.10 is 20.16.7. Hence, I had to force install that version, which is a bit of a pain with Homebrew.

$ cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/virtualenv.rb /tmp
$ curl https://raw.githubusercontent.com/Homebrew/homebrew-core/ad8df1de005bba0b0321789c6a1a0091e8cc8da0/Formula/virtualenv.rb > /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/virtualenv.rb
$ brew reinstall virtualenv
$ cp /tmp/virtualenv.rb /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/virtualenv.rb

Once this was patched, running the IOTstack installer again (./menu.sh) completed successfully. Please refer to the IOTstack “Getting Started” guide for further details. Note that so far I did not have to patch any of the macOS system libraries or components (as the guide requires for Pi).

Configure containers

I cannot claim that all available IOTstack container recipes work on macOS. However, the ones I need do. The excellent documentation describes all of them in great detail.

Leave a Reply