Using The RedBoard+ From Within a Docker Container…

…because why do anything the easy way?

I’ve switched to using the StereoPi image for MacFeegle Prime as it offers the lowest latency for streaming video, the downside is I can’t get ROS to build on it so I’m using Docker which needs to interface with hardware…

I’m using the RedBoard+ by Red Robotics, it uses the pigpio library which can work over a socket or pipe. I’m trying to figure out how to have the pigpio deamon running on the Pi host and access it from a docker container that’s running ROS.

Security Note Of Doom!

The following changes have security implications, only do this if you’re running on a private, trusted network. I don’t really know what I’m doing so assume the worst and double check everything I suggest!

Things To Tweak

Upon some digging, this wasn’t as evil as I thought it would be. For pigpiod you need to change the service definition to remove the “-l” from the start command:

sudo nano /lib/systemd/system/pigpiod.service

Remove the “-l” from the ExecStart line.

This is needed as by default pigpiod runs in localhost mode which means that it’ll only accept connections from the local machine. When connecting from inside of a docker container, it’s considered another host.

In order for the docker container to access the hardware it’ll need to have privileged status, add this to the command when you create your container. Eg:

docker run --priviledged -d ros 

From inside the docker container, and in the same shell instance you’re running the code that calls the RedBoard library, you need to run this:

export PIGPIO_ADDR=[PI IP ADDRESS]

This sets the address used by the pigpio library that RedBoard uses to the host machine.

Conclusion

After doing the above I was able to use the RedBoard keyboard_control.py script to control the robot from inside a docker container. I’ve not tried anything further yet but that proved the concept enough for today!

Raspberry Pi – Docker on USB Drive

As per my last post I’m using Docker on my robot with ROS. The last task is to get docker running from a dedicated USB drive to split resources between that and the SD card the OS is running from. A good guide to mounting a USB drive can be found here.

Note, rather than using umask=000 for mounting you need to mount, then change the permissions of the “host” directory to 777. For example, mount to /media/usb as per the article then chmod 777 /media/usb **WHILE MOUNTED**. This should allow you to mount, then set to automount on boot.

If you are running headless and there is a problem with the fstab file it can get annoying so to test in advance of a reboot run “sudo mount -a” to mount all volumes as per that file. If it succeeds, you can reboot.

I was having a problem mounting with fstab, I could manually mount the usb folder every time but not using “mount -a”. The penny dropped when I did “df -h” to see how much space was free and noticed /media was itself a mount point. I created a new root folder called “docker” and it worked a treat.

Following this answer I moved the location of the docker containers and such to /docker.

I’ve run “docker pull ros” and it’s now happily using the usb drive instead of the SD card. 🙂

StereoPi Image Mods

I’ve been using the Ubiquity Robotics Raspberry Pi ROS image to run both the robot and controller, it seemed the easiest way to get ROS running, but now I’m trying to get low latency streaming working from the cameras it is proving tricky.

New Plan, use the Stereo Pi image with Docker to host ROS images/containers.

Some Mods Needed…

In order to lower the latency as much as possible the Stereo Pi image is a heavily modified version of Raspbian, this includes custom partitions and the file system set to read only. Here are the steps I followed to get it to a state where I can restart development.

1. Get and Modify the Image

Head here and follow the steps to get and install the image, follow the steps to get it on the wifi and under the Advanced section you’ll see details on how to SSH to the Pi afterwards. Once logged in you’ll need to temporarily set the file system to read/write then edit the fstab file.

Under the “SLP Structure Details” section you’ll find this command:

 sudo mount -o rw,remount /   

This will set the file system to read/write, at which point you can open the fstab and edit it to make this permanent by changing the ro to rw for the root.

nano /etc/fstab

2. Resize the Partitions

I was trying to figure out how to do this on Windows then realised I could just install gparted on the controller and remote to it… I put the micro-sd card in a USB card reader and followed these instructions. The 1.8G root partition was expanded to around 25GB and the recording drive slimmed down accordingly.

screenshot of gparted with the final sizes of the partitions

3. Install Docker

This next bit is trivial, run this command, as taken from the Raspberry Pi blog:

 curl -sSL https://get.docker.com | sh 

4. Get ROS Images

Next bit is easy too:

 docker pull ros

Considerations

One of the reasons StereoPi is very quick is because it is tailored not to use the filesystem on the SD card, to that end it may be worth moving all of the docker containers and images over to a USB drive. There’s more information on how to do that here but I’ve not tried it yet:

https://stackoverflow.com/questions/32070113/how-do-i-change-the-default-docker-container-location

Next Steps

The next things I need to do is convert my code to work in a docker container, this shouldn’t be too tricky but as the RedBoard library will need to talk to the hardware there will likely be complications.

Docker, A Reverse Proxy, This Site and LetsEncrypt!

The site was migrated to SSDNodes last year as my previous host was becoming less reliable and I fancied something more versatile.  I’ve not covered it on here but here is how my site runs, now with added HTTPS thanks to LetsEncrypt!

A bit of history.  This is a WordPress site and has been since it was migrated from Windows Live Spaces which shows it’s age!  There is an official Docker container available so I thought I’d give that a go.  I may want to host more than one site on the same virtual server at some point so looked in to my options for a reverse proxy and jwilder had the perfect solution it turned out.  Building on an example I found I managed to get the site going behind the proxy but wanted to secure it.  Unsurprisingly this problem had already been solved too…

Follows are my Docker Compose files that work a treat, as much as examples for others as to help me in the future if I need to set up a new site or rebuild this one if something goes wrong.  When the container for the site is fired up for the first time it creates, and maintains, a Lets Encrypt certificate automatically.  Neat!

One thing for VaultPress users to be aware of is that you’ll need to follow the steps here under the reverse proxy section otherwise the service won’t be able to connect to your site to back it up.

If I need to host a new site, I just need to create a new site definition file and it should sort itself out.  Please note, the formatting may be screwy if you copy and paste these so you may need to manually tweak them.

neave-eng.yml

version: '2'

services:

neaveeng:
 depends_on:
 - mariadb
 image: wordpress
 links:
 - mariadb:mysql
 environment:
 WORDPRESS_DB_PASSWORD: [YOURDBPASSWORDHERE]
 WORDPRESS_DB_NAME: wp_neaveeng
 APACHE_RUN_USER: wp-neaveeng
 APACHE_RUN_GROUP: wp-neaveeng
 VIRTUAL_HOST: neave.engineering
 LETSENCRYPT_HOST: neave.engineering
 LETSENCRYPT_EMAIL: my.email@domain.com
 volumes:
 - ./neaveeng/code:/code
 - ./neaveeng/html:/var/www/html
 - /etc/passwd:/etc/passwd:ro
 - /etc/group:/etc/group:ro
 restart: always

mariadb:
 image: mariadb
 environment:
 MYSQL_ROOT_PASSWORD: [YOURDBPASSWORDHERE]
 MYSQL_DATABASE: wp_neaveeng
 volumes:
 - ./neaveeng/database:/var/lib/mysql
 restart: always

proxy.yml

version: '2'

services:
 nginx-proxy:
 image: jwilder/nginx-proxy
 ports:
 - "80:80"
 - "443:443"
 volumes:
 - /var/run/docker.sock:/tmp/docker.sock:ro
 - "/etc/nginx/vhost.d"
 - "/usr/share/nginx/html"
 - "/etc/nginx/certs"
 restart: always

letsencrypt-nginx-proxy-companion:
 image: jrcs/letsencrypt-nginx-proxy-companion
 volumes:
 - "/var/run/docker.sock:/var/run/docker.sock:ro"
 volumes_from:
 - "nginx-proxy"

whoami:
 image: jwilder/whoami
 environment:
 - VIRTUAL_HOST=whoami.local
 restart: always