Part 3: Deploying Theia IDE using Docker
Using a web based IDE running on a remote machine
This is part 3 of the serie Hands on Development with Raspberry Pi 4, whose primary goal is to setup a workspace on a high performance and cost effective setup, intended both for rapid prototyping, as well as for fast transfer to a production environment. The scope is suitable for cluster management (using Docker, and even Kubernetes), as well as for IoT projects and High-Performance Computing (HPC).
Before going into the specific content of this article, it is worth remebering the scope of the four parts that compose this serie:
- Part 1: Getting the most from Raspberry Pi 4 , whose concrete scope is to integrate a M.2 SSD physical disk with a 64 bits operating system running the Raspberry Pi, that provides 4Gb RAM.
- Part 2: Installing Docker in Raspberry Pi 4, that focuses in development methodology and shows the process to prepare a Docker ready development environment.
- Part 3: Deploying Theia IDE using Docker. In this part we will explain how to have a full featured IDE for editing code in a headless Raspberry Pi. This way we skip the need of a monitor, keyboard and mouse for the board. Hence we will confortably work from our laptop without the cumbersome need of additional hardware.
- Part 4: Monitoring Raspberry Pi 4 performance in real time. To finish the serie we provide a simple and powerful example of how to deploy an application using Docker Compose. We will build a Chronograf dashboard of top of InfluxDB andTelegraf using Docker Compose.
This article is part 3 and consists of the last step to complete the environment. Afterwards you will be ready to start coding applications.
Hence, for the purpose of writing code we will use a general purpose IDE like Theia, suitable for editing and debugging code in Javascript, Java, Python, etc. So go through the next sections to discover why we selected Theia IDE and how to quickly deploy the application in your Raspberry Pi.
Why a web based IDE?
The most important decision a developer has to make to eel confortable and be productive is the choice of IDE (Integrated Development Environment) where to code.
For a sofware engineer the IDE is like the notebook for the student, i.e. it is the common and most visited place where he will write and debug his applications. The following is the list of key points that drove us to select Theia:
- It reuses quite a few technologies and concepts from Visual Studio Code (VSC), the most popular IDE in the developer’s world. So when you see Theia interface, it will feel very familiar because it looks and works as your loved VSC.
- Although it can also be used in the desktop, what we like more is that it is accessible via http, so you can install it in a remote server and code directly over that server. This is the role that the Raspberry Pi will play in the practical explanations below.
- Theia supports more that 60 programming languages, so it serves very well to the goal of one-for-all. If you are a developer at present, we are sure you will be using languages like Javascript, Java and Python.
- It also integrates git control version, so you can easily stage changes, commit your code and perform common push/pull operations.
After this brief introduction it is time to hands-on installing Theia on your Docker based infraestructure.
Deploying Theia with Docker in Raspberry Pi
The official Theia docker image is designed forAMD64 architectures, the common one that powers laptops and desktop PCs. In this case we are going to use a custom image to extend the compatibility to ARM devices like Raspberry Pi.
Since you want your whole home directory to be accessible from the IDE, change to that location and check the result with the pwd command:
$ cd /home/pi
$ pwd
/home/pi
The output /home/pi confirms that you are now in the root of your home. This is essential to make sure that your whole user workspace is mounted into the container, persisting all the modifications you will do later with the IDE.
Given this premise, you can safely start now the Theia service with the following command:
$ docker run -it --restart always \
-p 8000:3000 \
-v "$(pwd):/home/project" \
--name theia \
-d \
brjapon/theia-arm64
Let’s briefly explain each of the options provided to docker run command:
- -it option makes the container interactive so that so you can access using SSH, i.e. docker exec -it theia bash.
- - - restart always tells Docker to keep the container always running, be stopped for any reason or on a reboot event.
- -p 8000:3000 forwards Theia internal port in the container (3000) to another port in the host machine (8000). This is something to take into account because if you had some other service running in port 3000 in the host, Theia will not be able to attach to that busy port. That’s the reason for which we are forwarding the application trafic to port 8000.
- -v “$(pwd):/home/project” tells Docker to mount your current folder to the location where Theia user data is located, i.e. /home/project. So when you access the IDE you will see all the content of your user workspace in the host machine.
- - - name theia gives a human readable name to refer to the container when running commands from the host, i.e. the SSH example shown with the first option -it above.
- -d tells Docker to run the container in the foregroung. This way, if you kill the terminal the service will keep on running.
- brjapon/theia-arm64 is the argument of the docker run command. It provides the account (brjapon) and image name (theia) in the Docker public registry, i.e. https://hub.docker.com/r/brjapon/theia
NOTE: If needed, you can use the version for 32bits operating system (the typical case for Raspberry Pi 3). In that case replace the last argument by brjapon/theia-arm
Since the image is not locally available, the first thing Docker does is to download it from the public registry. The following lines shows the build process:
Unable to find image ‘brjapon/theia-arm-64:latest’ locally
latest: Pulling from brjapon/theia-arm64
856f4240f8db: Pull complete
0ea0270eaa0b: Extracting [============================================> ] 18.35MB/20.61MB
6067b7ad6974: Download complete
68eb5a3384e3: Download complete
b2dbde9a8879: Download complete
3f5e1a1094e2: Download complete
cc8f68ace72c: Download complete
3fdcd09d1408: Download complete
f35eab9cb68c: Download complete
Once it finishes, you can open the following URL in a browser window using the IP address of the Raspberry Pi (192.168.1.103 in my case):
http://192.168.1.103:8000
Alternatively, if you are using a web browser on a Linux PC, you can take advantage of the name resolution capability provided with Ubuntu and point to the Raspberry Pi with <HOSTNAME>.local as follows:
http://pi4-m2.local:8000
If you do not remember the hostname of your Pi, simply run this command in a terminal to recap:
$ hostname
pi4-m2
NOTE: Be aware that Raspberry Pi and laptop has to be in the same wifi network so that you can access to Theia.
The result in the browser should be similar to this:

In the file explorer on the left side of the window you will see all the directories in your workspace in the host machine. In particular, look at the file that is highlighted in the image above. It is docker-compose.yml from the core file of the hello world repository we used in part 2: Installing Docker in Raspberry Pi 4. When clicking on it with the mouse, its content is shown in the editor window.
You can even open a bash terminal in the IDE as shown in the next image. This way you can skip the SSH command whenever you want to run a command right in the Raspberry Pi.

At this point, the development environment is ready to start coding.
Docker under the hood
This last section of the article goes beyond the practical guidelines and gives you essential insights of how the container was built. So let’s understand what happened.
The good thing about Docker is that an image is composed of stacked layers. After downloading each of them, the layer is extracted to build the local image. The following snippet shows the build process in a state where all the them are already downloaded to the machine:
856f4240f8db: Pull complete
0ea0270eaa0b: Pull complete
6067b7ad6974: Pull complete
68eb5a3384e3: Pull complete
b2dbde9a8879: Pull complete
3f5e1a1094e2: Pull complete
cc8f68ace72c: Extracting [============> ] 2.261MB/9.002MB
3fdcd09d1408: Download complete
f35eab9cb68c: Download complete
Each line represents a layer, that also corresponds to a single line in the original Dockerfile from which the image was built. This way you have a modular architecture that can be shared by other Docker images in your machine to reduce the download time. For example, two different images could share the same base operating system (this would be the first layer, the top one in the list).
Given this explanation you can now understand what each tag to the right of each layer name means:
- Download complete means that the layer is already in the local machine.
- Extracting … refers to the fact that it is being decompresed.
- Pull complete message means that the layer has completed all the build operations, and is already allocated to the local image.
This is a three steps process that every layer has to completed in the same order of the list.
Afterwards you can inspect Docker images present in the Raspberry Pi with the following command:
pi@pi4-M2:~$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest a29f45ccde2a 8 months ago 9.14kB
brjapon/theia-arm64 latest 72a8b2590f3f 11 months ago 315MB
You can see two images. The first one, hello-world, is the one we created in the last article part 2: Installing Docker in Raspberry Pi 4 to check our Docker installation. The second one, brjapon/theia-arm64, is the one we have just pulled.
Finally you can list the running containers with the following command:
pi@pi4-M2:~$ docker psCONTAINER ID IMAGE COMMAND
002e8fcbad06 brjapon/theia-arm64 "node /home/theia/sr…"CREATED STATUS PORTS NAMES
2 weeks ago Up 2 minutes 0.0.0.0:8000->3000/tcp theia
As expected there is only one, that corresponds to Theia IDE and is accesible from the host through the port 8000.
Not so hard, right? In order to acquire fluency with Docker there’s no secret. Just spend hours pulling and/or creating images from scratch, deploying them in containers afterwards. There are plenty of resources and tutorials in the web to make all these practices.
Conclusion
Hence, you now have an integrated environment to interact with the Pi 4 board and start developing code. In part 4 of the serie we will deploy our first end user application. It will consist of building a Chronograf dashboard of top of InfluxDB and Telegraf using Docker Compose. This application will serve the purpose of monitoring Raspberry Pi 4 performance in real time.
Happy coding with Theia ;)