Running a dockerized Shiny-Server on Raspberry Pi 4b Buster

Hi everyone,

I recently found myself running an experiment on a shiny-server and wondered if I can also get it to work on the raspberry pi 4b. Additionally, I wanted it to work in a docker container as I'd like to keep my main os free of library clutter. Below you can find a tutorial on how to easily deploy shiny server on your raspberry pi 4b buster. There have been multiple tutorials posted online to do that, but they don't use docker and didn't work for debian buster. In the following tutorial I'll guide you on how to do that easily.

First we need to install docker. There are plenty of tutorials online, but simply executing the following commands in the console will get docker installed on your system

curl -sSL https://get.docker.com | sh
sudo usermod -aG docker pi
docker run hello-world

If you see the following output, then the installation of docker has worked
Hello from Docker!
This message shows that your installation appears to be working correctly.

Now that we have docker we can either compile shiny-server ourselves or download a precompiled version from docker hub. By far the more convenient way is to download the image. The image will take 1GB of space on your device.

For those that want to build their own image, at the very end of this post I'll provide instructions and a few things to be mindful about when doing that.

The next step would be to create the directory structure, which will allow us access to the container's insides, namely the logs, deployed applications as well as configuration files

cd ~
mkdir shiny-server
mkdir shiny-server/logs
mkdir shiny-server/conf
mkdir shiny-server/apps

We need to create named volumes in order to expose paths from our container on our host os.

docker volume create --name shiny-apps --opt type=none --opt device=/home/pi/shiny-server/apps/ --opt o=bind
docker volume create --name shiny-logs --opt type=none --opt device=/home/pi/shiny-server/logs/ --opt o=bind
docker volume create --name shiny-conf --opt type=none --opt device=/home/pi/shiny-server/conf/ --opt o=bind

Now you can start the container with the following command and you're good to go! Docker will fetch the image and will run it for you.

docker run -d -p 3838:3838 -v shiny-apps:/srv/shiny-server/ \
-v shiny-logs:/var/log/shiny-server/ -v shiny-conf:/etc/shiny-server/ \
--name rpi-shiny-server hvalev/rpi-shiny-server-docker

You can now access your shiny server and check if the installation worked by opening the shiny-server hello-world app on the following page http://196.168.1.25:3838/hello/. Of course you will need to substitute the IP with the one your pi uses.

You can manage your shiny-installation by interacting with the following folders we created earlier.

  • ~/shiny-server/apps/ hosts all deployed applications. To deploy a new application, simply move it to that path and restart the container.
  • ~/shiny-server/logs/ contains the logs files from all your applications. If an application is not running correctly, the log files can give you some information about why that is.
  • ~/shiny-server/conf/ holds your shiny-server.conf configuration file as well as the init.sh and init_done files. If you want to make any changes to your container (for example install additional R libraries) you can use the template in init.sh to do that, delete the init_done file and restart the container. Upon starting the script will install libraries and will recreate the init_done file. Installed libraries will persist between restarts as long as you don't remove or recreate the container.

Stopping, starting and restarting the container can be done simply via the following comands:

docker stop rpi-shiny-server
docker start rpi-shiny-server
docker restart rpi-shiny-server

Optionally, you can also install docker-compose, which is a different way of deploying and managing docker images. It works through defining a docker-compose.yml file. To install docker-compose, you can execute the following commands after installing docker from the previous step.

sudo apt-get install libffi-dev libssl-dev -y
sudo apt-get install python3 python3-pip -y
sudo pip3 install --upgrade pip
sudo pip3 install docker-compose

This may take a couple of minutes.
Afterwards, we need to create the folder structure to access shiny-servers' app, config and log folders as before

cd ~
mkdir shiny-server
mkdir shiny-server/logs
mkdir shiny-server/conf
mkdir shiny-server/apps

Now we need to create a docker-compose.yml file and copy the following contents into it with your favorite editor. For this example I'll use nano.

touch docker-compose.yml
nano docker-compose.yml

Copy paste the following contents into the docker-compose file

version: "3.8"
services:
  rpi-shiny-server:
    image: hvalev/rpi-shiny-server-docker
    container_name: rpi-shiny-server-docker
    ports:
      - 3838:3838
    volumes:
       - shiny-apps:/srv/shiny-server/
       - shiny-logs:/var/log/shiny-server/
       - shiny-conf:/etc/shiny-server/
    restart: always

volumes:
  shiny-apps:
    name: shiny-apps
    driver_opts:
      type: none
      device: /home/pi/shiny-server/apps/
      o: bind
  shiny-logs:
    name: shiny-logs
    driver_opts:
      type: none
      device: /home/pi/shiny-server/logs/
      o: bind
  shiny-conf:
    name: shiny-conf
    driver_opts:
      type: none
      device: /home/pi/shiny-server/conf/
      o: bind

As you can see we are again using named volumes to access the logs, configuration files as well as applications from our shiny-server container, but all of this is embedded in the docker-compose file. To start and stop the container respectively, use the following docker-compose commands in the same path as your docker-compose file

docker-compose up -d
docker-compose down

Congratulations! You now have a working shiny-server installation. You can now access your shiny server and check if the installation worked by opening the shiny-server hello-world app on the following page http://196.168.1.25:3838/hello/. As before, you will need to substitute the IP with the one your pi uses.

For the people that have stuck around and want to build the container themselves, you need to be mindful of the following things before you proceed and know how to do a few things, as I won't go into details explaining that.

  • Building the image yourself implies you having a couple of spare hours to wait
  • You need to reserve roughly 6GB of free space
  • You might need over 1GB of RAM. You could use swap memory if you fall short.
  • The Dockerfile uses a multi-stage build, where it uses a discardable container for building R and shiny-server and then copying the compiled binaries to a new clean container.
  • You could reduce the amount of memory required by removing the -j4 tag from the various make and install commands and force docker to build it on one core. This will slow the installation down somewhat, but not dramatically.
  • There are a few additional hints in the repository GitHub - hvalev/shiny-server-arm-docker: Dockerized shiny server for armv7, arm64 and x86 which are worth checking out if the build fails.

Use the following commands to check out the repository and build the container

git clone https://github.com/hvalev/rpi-shiny-server-docker.git
docker build rpi-shiny-server-docker --tag rpi-shiny-server-docker

After the build is done you can follow the instructions above, but substituting hvalev/rpi-shiny-server-docker with rpi-shiny-server-docker, which will use your locally built image instead.

To give credit where it is due, the following guide has been extremely helpful in getting this project to work:

Enjoy your brand new self-hosted shiny-server on your raspberry pi!

4 Likes

Hi..in my case It's running a subshell and in the event that it prevails with regards to evolving registries, it attempts to run npm. Is it accurate to say that you are running a pi2 or pi3? Do you have trade? I don't have a clue how enormous this application is, however there have been times that I was unable to manufacture something with the first 512meg pi without including a trade streak drive. When you are assembling this, would you say you are watching it from another window with something like htop? Perhaps it breaks now since it is coming up short on memory.

pcb assembly services

Hi BonnieCase, I did this on a 4gb rpi4, so memory was not an issue even with the -j4 tag. I did use a second terminal with htop to check how it is doing from time to time and 512mb is definitely not enough as compiling cmake spiked the ram usage to a little over 1gb. Are you trying to build it on a rpi2/3? If you don't care about building the image yourself, you can always use the prebuild docker image. If you do want to compile it yourself, I suggest to add at least 1gb of swap memory and remove the -j4 tag from the dockerfile to force it to build it on one core, hence use less memory.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.