In this guide, I'll walk you through how I set up my Raspberry Pi 4 to run ROS 2 inside Docker containers without needing a monitor or keyboard. This headless setup has become my go-to approach for robotics projects where I want to remotely access and control the Pi.
Step 1: Installing Raspberry Pi OS LiteRather than repeating the basic installation steps here, I’ll direct you to follow the official Raspberry Pi documentation: Installing the Operating System
Here’s what I do differently for this setup:
1. I always choose Raspberry Pi OS Lite (64-bit) — no desktop environment means more resources for our containers
2. During the imaging process with the Raspberry Pi Imager, make sure to:
- Enable SSH in the advanced options (crucial for headless access)
- Set up my username and password
- Configure my WiFi credentials
- Set up my locale settings
I prefer the 64-bit Lite version because:
- It gives me better performance with containerized applications
- Uses less memory without the desktop environment
- Works perfectly with Docker and ROS 2 containers
- Feels more like a proper server setup
Once I've flashed the SD Card:
- I insert it into my Raspberry Pi 4
- Connect the power supply and let it boot
- Wait about 2-3 minutes for the initial setup to complete
- The Pi automatically connects to my configured WiFi network
Since I'm running the Pi headless, I need to find out what IP address my Pi has been assigned. I use my Android phone for this.
My Android Network scanning approach:
1. I installed a network scanner application on my Android device. My favorites are:
- WOM WiFi by Network Scanner (easy-to-use)
- Network Scanner by First Row (simple and reliable)
- Fing by Fing Limited (feature-rich)
2. I make sure my phone is on the same WiFi network as my Pi
3. I run a network scan (using WOM WiFi) and look for:
- Hostname: "raspberrypi" (or whatever custom name I set)
- Manufacturer: "Raspberry Pi Foundation"
- MAC addresses startign with B8:27:EB, DC:A6:32 or E4:5F:01
4. I note down the IP address (something like 192.168.1.100)
Pro tip: I usually see my Pi appear in the scan within 1-2 minutes of booting. If it doesn't show up immediately, I wait a bit and scan again.
Step 4: SSH Connection - My Gateway to the PiNow comes the fun part - connecting to my Pi remotely!
From my Linux host machine (same for Mac machine)
I open Terminal and use the command:
ssh [my-username]@[pi-ip-address]
For example:
ssh pi@192.168.1.100
From my Windows machine
I can open Command Prompt or PowerShell and type:
ssh [my-username]@[pi-ip-address]
What happens on First Connection
1. I see a message about host authenticity:
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no/[fingerprint])?
2. I type yes and hit Enter
3. I enter the password I set during the OS installation
4. Success! I see my Pi's command prompt:
pi@raspberrypi:~ $
Step 5: Initial Configuration - Setting Up My EnvironmentOnce I'm connected, here's what I always do first:
Update Everything
sudo apt update && sudo apt upgrade -y
I grab a coffee while this runs - it usually takes a few minutes.
Configure Additional Interfaces
sudo raspi-config
I navigate through the menu to enable what I need:
- I2C (for sensors I might connect later)
- SPI (for various devices)
- Camera (if I plan to use the Pi camera)
For detailed information about all the configuration options available in raspi-config, check out the official documentation: Raspberry Pi Configuration
Install my Essential Tools
sudo apt install -y curl wget git vim nano htop
These are the tools I can't live without when working on Pi projects.
Step 6: Preparing for DockerIncreasing Swap Space
For 4GB Pi models, I always increase the swap space:
sudo dphys-swapfile swapoff
sudo nano /etc/dphys-swapfile
I change CONF_SWAPSIZE=100 to CONF_SWAPSIZE=1024, then:
sudo dphys-swapfile setup
sudo dphys-swapfile swapon
Memory Split Configuration
sudo raspi-config
I go to Advanced Options -> Memory Split and set it to 16 since I'm not using graphics.
Step 7: Installing Docker - the Container MagicGetting Docker Installed
I use the official Docker Installation script:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Adding myself to the Docker Group
This lets me run Docker commands without sudo:
sudo usermod -aG docker $USER
Starting Docker Services
sudo systemctl enable docker
sudo systemctl start docker
Testing my Installation
I log out and back in, then test:
docker --version
docker run hello-world
When I see "Hello from Docker!" I know everything's working perfectly.
Step 8: Adding Docker ComposeFor managing multi-container applications:
sudo apt install -y python3-pip
sudo pip3 install docker-compose
I verify it worked:
docker-compose --version
Step 9: Setting Up VS Code Remote DevelopmentOne of my favorite ways to work with the Pi is through VS Code's Remote Explorer extension. This gives me a full IDE experience while the code actually runs on the Pi.
Installing the Remote SSH Extension
1. I open VS Code on my Computer
2. Go to the Extensions panel (Ctrl + Shift + X)
3. Search for "Remote-SSH" by Microsoft
4. Install the extension
Connecting to my Pi
1. I press Ctrl + Shift + P to open the command palette
2. Type "Remote-SSH: Connect to Host"
3. Enter my Pi's SSH connection: my-username@pi-ip-address (e.g., pi@192.168.1.100)
4. VS Code opens a new window connected to my Pi
What I get with this setup
- Full file explorer of my Pi's filesystem
- Integrated terminal running directly on the Pi
- Code editing with Intellisense and syntax highlighting
- Extension support for Python, Docker, and ROS development
- Git integration for version control
Pro tip: I can install extensions directly on the Pi through VS Code's interface. I usually install Python, Docker, and ROS Extensions for the best development experience.
For a comprehensive guide on VS Code extensions specifically for ROS development, check out this detailed article: Exploration of VS Code extensions for a ROS Developer.
When Things Go Wrong - My Troubleshooting ChecklistSSH won't connect
- I double-check that my Pi is actually powered ON and the LED is active
- I run another network scan to confirm the IP address
- I verify SSH is enabled by checking /boot/ssh exists
- I try connecting with verbose output: ssh -v my-username@pi-ip-address
VS Code Remote Connection Issues
- I make sure the SSH connection works first in the terminal
- I check that the Remote-SSH extension is properly installed
- I try restarting VS Code and reconnecting
- I verify my SSH config doesn't have conflicting entries
Network Issues
- I verify that my network credentials are correct
- If all else fails, I connect via Ethernet for the initial setup
Performance problems
- I monitor resources with htop to see what's eating CPU/memory
- I consider switching to an SSD via USB 3.0 for better performance
- I make sure my Pi has adequate cooling for long-running tasks
My Raspberry Pi 4 is now ready for serious ROS 2 development! In the next article, I'll show you how to build and run ROS 2 Docker containers specifically optimized for the Pi.
We'll cover:
- Creating custom ROS 2 Docker images for ARM64 architecture
- Setting up Docker Compose files for robotics projects
- Optimizing containers for Pi's resource constraints
This headless setup with VS Code remote development has become my standard approach for Pi-based projects. The combination of Raspberry Pi OS Lite, Docker, and VS Code's remote capabilities gives me a lightweight yet powerful development environment that I can access from anywhere on my network.
The best part? I get the full desktop IDE experience while keeping the Pi running efficiently without a desktop environment. This setup provides the perfect foundation for the ROS 2 Docker containers we'll build in the next article.
Comments