Headless setup of your Raspberry Pi

Here I’ll show you how to get your Pi up and running on your WiFi network by only flipping switches directly on the SD card, before even starting the Pi.

There are a few tricky parts in getting your Raspberry Pi up and running, especially if you do not have an external monitor, keyboard and Ethernet cable to hook it up with.

With no monitor we have a headless setup. Also, with no Ethernet cable we must get WiFi working before even powering on the Pi.

When setting up the Pi, there are many factors that need to work and where each one could break the whole setup. Also with a headless setup it’s not obvious to understand where and why it didn’t work.

That’s why we rely on Space.sh and its modules to help us conquer the headless setup in a repeatable and understandable way.

If you haven’t heard about Space.sh yet, you should definitely check it out and all its other use cases. Space.sh is a true master of command line productivity (disclaimer: I’m one of the authors).

It is time for you to decide which Operating System (OS) you would want your Pi to run. This will depend on what you want to do with it.
If it’s meant to be working as a headless setup, maybe as an Internet of Things (IoT) device in your home, up in a tree or something fun like that you should go with a slimmed down OS distribution. If you want to connect it to a monitor (or Virtual Network Computing - VNC) and run graphics, you should consider a more fleshed out OS distribution. Please post a comment below and tell us what your use cases are!

We would recommend going for a Raspbian based OS, such as Raspbian itself or HypriotOS.

If you are interested in running Docker containers on your Pi (there are good reasons for this), you should definitely go for HypriotOS. They have been pioneering Docker on ARM for some time now. Raspberry Pi cameras works flawlessly on HypriotOS too.

The X11 Window System doesn’t come bundled with HypriotOS but is really easy to install later, on a separate step.

Raspbian and HypriotOS differ in how to setup WiFi, Space.sh will help you either way.

1. Download OS distribution

Find the download links at:
https://blog.hypriot.com/downloads/ https://www.raspberrypi.org/downloads/raspbian/

Download and unzip the img file.

For HypriotOS:

curl -LO https://github.com/hypriot/image-builder-rpi/releases/download/v1.4.0/hypriotos-rpi-v1.4.0.img.zip
unzip hypriotos-rpi-v1.4.0.img.zip

For Raspbian, the slim version:

curl -LO https://downloads.raspberrypi.org/raspbian_lite_latest
unzip raspian_lite_latest

2. Write OS image to SD card

Now it is time to leverage Space.sh to help us for the rest of the process.

Install Space.sh

Space.sh installs on UNIX-like systems such as GNU/Linux, BusyBox/Linux, OSX and other BSD flavours. It also runs under the Windows sub system for Linux.

This only takes a second (detailed instructions about Space.sh here):

curl https://get.space.sh | sudo sh

Great! Almost there.

Did you plug in the SD card yet? If not, it is time to do so now. Also unplug any other external hard drives or USB sticks you have, to not risk wiping them.

We need to find out what device path the SD card is using on your laptop. You could run dmesg or lsblk and look for it, or you could let Space.sh list devices for you.

space -m gitlab.com/rpi-shell/sdcard /list/
# Note: The first time running a Space module Space.sh 
#       will download the module, using git or curl/wget.

Small note on using Space.sh. space -m module [node]
module is a git repository and node is a node path in the modules YAML file, which looks a lot like a file path, but it’s not.

The output would look something like this:

sda                                   8:0    0 119.2G  0 disk
├─sda1                                8:1    0   511M  0 part /boot
├─sda2                                8:2    0   114G  0 part /
└─sda3                                8:3    0     4G  0 part [SWAP]
mmcblk0                             179:0    0  14.7G  0 disk
├─mmcblk0p1                         179:1    0    64M  0 part
└─mmcblk0p2                         179:2    0   935M  0 part

Here we can spot that mmcblk0 is the device of the SD card (p1 and p2 are the partitions). But you must know that this is very important to get right, otherwise you risk overwriting your hard drive.
When you have figured out the device set it as -e device=[path] as shown below.

Write it!

space -m gitlab.com/rpi-shell/sdcard /write/ \
      -e image=hypriotos-rpi-v1.4.0.img -e device=/dev/mmcblk0 -s sudo

Note: If the above shell syntax looks confusing with the backslash and a new line -don’t worry- this is just a way of splitting one long command line into multiple lines for brevity. This way it is still possible to copy and paste it.

Congratulations, you are good to go! But wait, you most likely want to setup WiFi too, right? Keep reading.

3. Setup WiFi

Getting WiFi to work on your Pi is an infamously tricky process, but it has become a lot easier over the years.

A small note on WiFi drivers

The biggest problem would be if you have a WiFi dongle which drivers does not come with the OS distribution you chose. Usually you would get a dongle that is known to work with Raspbian, or even better if you have the Raspberry Pi 3, the WiFi adapter is built in and those drivers are definitely in a fresh Raspbian-based distribution.

However, if you have to install drivers, you would need to copy the drivers over to the SD card and have a one time boot script which installs the drivers for you. We will not cover that here because it seems to be a diminishing problem nowadays.

Mount the partitions on the SD card

To be able to work with the OS installed on the SD card, we need to mount it to access the files on it.

If your device is named something else than /dev/mmcblk0 apply that for the -e device= flag.

space -m gitlab.com/rpi-shell/sdcard /mount/ \
        -e device=/dev/mmcblk0 -s sudo

This will mount the boot and root partitions to /mnt/sdcard/boot and /mnt/sdcard/root.

Mounting differently

To change the default mount points, set the mnt variable as -e mnt=/mnt/ext.

space -m gitlab.com/rpi-shell/sdcard /mount/ \
        -e mnt=/mnt/ext -e device=/dev/mmcblk0 -s sudo
# This will mount to /mnt/ext/boot and /mnt/ext/root.

The default partitions to mount on the SD card are p1 for boot and p2 for root. If your device is named something else than /dev/mmcblk0 your partitions might also just be named 0 and 1 then adjust the command as:

space -m gitlab.com/rpi-shell/sdcard /mount/ \
        -e device=/dev/sdx -e bootpartition=0 -e rootpartition=1 -s sudo

The mounted partitions will be visible in /mnt/sdcard or to where you defined it using the -e mnt=... flag.

Note that if you change the mnt directory, then you have to provide it as -e mnt=... for all commands below that access the files on the partitions.

Configure WiFi on HypriotOS

The Hypriot people are really improving on the Pi experience by creating tools and helpers for us, not to forget their Docker efforts!

The WiFi setup on HypriotOS differs from how it’s done on Raspbian in that they have a tool named: device-init.

This tool is triggered by us placing the file device-init.yaml on the boot partition on the SD card. The tool will setup the network interface and configure the WiFi.

Create the file device-init.yaml using your favourite text editor (vim):
Replace the variables below with your information.

# device-init.yaml
hostname: "${HOSTNAME}"
            ssid: "${WIFI_SSID}"
            password: "${WIFI_PASSWORD}"

Now we want to copy this file over to the SD cards boot partition. First we need to mount the partitions of the SD card.
Space.sh will help us with both these tasks:

Copy the device-init.yaml to the boot partition

space -m gitlab.com/rpi-shell/sdcard \
      /mounted/boot/hypriot/cpinit/ -s sudo

If you had a different mount point you must provide that with -e mnt=...

.. or edit the file device-init.yaml directly on the boot partition

You could let Space.sh launch your favourite editor for you (make sure $EDITOR variable is set):

space -m gitlab.com/rpi-shell/sdcard /mounted/boot/edit/ \
        -e file=/device-init.yaml -s sudo

Now, skip down to “Unmount the partitions of the SD card”.

Configure WiFi on Raspbian

Configuring WiFi on Raspbian is more of a sysadmin task than on HypriotOS. We need to make sure we have a wlan interface and then that WiFi settings are configured in the wpa_supplicant.conf system file.

Setting up the wlan interface

This is preconfigured on Raspbian to use dynamic IP addresses (DHCP) and you do not have to change anything. However, If you need to edit the interfaces file:

You could let Space.sh launch your favourite editor for you (make sure $EDITOR variable is set):
The interfaces file is located at /mnt/sdcard/root/etc/network/interfaces.

space -m gitlab.com/rpi-shell/sdcard /mounted/root/edit/ \
        -e file=/etc/network/interfaces -s sudo

Make sure the file has something that looks like:

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

We are not using static IP addresses since Space.sh can help us locate the Pi. In the next tutorial we will look at how SpaceAgent can make your Pi accessible no matter where it is located.

Configuring WiFi credentials

This is important, we need to configure our WiFi settings on the Pi.

The file of interest is wpa_supplicant.conf located at /mnt/sdcard/root/etc/wpa_supplicant/wpa_supplicant.conf.

space -m gitlab.com/rpi-shell/sdcard /mounted/root/edit/ \
        -e file=/etc/wpa_supplicant/wpa_supplicant.conf -s sudo

The file should contain:


If you have a file containing your WiFi configuration you could copy it directly instead of editing the existing wpa_supplicant:

space -m gitlab.com/rpi-shell/sdcard /mounted/root/cp/  \
        -e device=/dev/mmcblk0 \
        -e file=my_wpa_file \
        -e dest=/etc/wpa_supplicant/wpa_supplicant.conf \
        -s sudo 

Making sure that the SSH server is activated

Raspbian doesn’t have the SSH daemon activated by default, but it has a very easy way of getting it activated. We only need to create an empty file on the boot partition named ssh. Space.sh does this for us:

space -m gitlab.com/rpi-shell/sdcard \
        /mounted/boot/raspbian/initsshd/ -s sudo

Change the host name of the Pi

It can be useful to give each Pi it’s own host name.

For this we want to edit the /etc/hostname/ file on the root partition:

space -m gitlab.com/rpi-shell/sdcard /mounted/root/edit/ \
        -e file=/etc/hostname -s sudo

4. Unmount the partitions of the SD card

To finalize our changes to the SD card we need to unmount it so we can safely remove it.

If your device is named something else than /dev/mmcblk0 apply that for the -e device= flag.
Also, if bootpartition and rootpartition were set when mounting, set them here again.

space -m gitlab.com/rpi-shell/sdcard /umount/ \
        -e device=/dev/mmcblk0 -s sudo

5. Congratulations

You are good to go! Pop out that SD card and push it into your Pi, power it on (make sure the WiFi dongle is connected), give it a few moments to boot and then it should appear on your local network. You can find its local IP address by looking in your WiFi router connection log or scanning the local network using nmap.

First find your own local IP address by running ifconfig, then run nmap on the same IP block:

# If ifconfig says that your wlan IP is,
# then run nmap as:
nmap -sP "192.168.43.*"

The Pi should appear with its local IP address.

Now you can connect to it via ssh:

# For Raspbian, user: pi, password: raspberry
ssh pi@

# For HypriotOS, user: pirate, password: hypriot
ssh pirate@

If you get this message when connecting:


…it means that there was another Pi or server on that address prior and your SSH client already has a record for that and it thinks that someone has compromised that server because the host key changed.
To remove this error remove the record in the file ~/.ssh/known_hosts for the given address.

Important note: For security reasons you should at the very least change the password of the default user right after login using the passwd command. Preferably you should setup login by keys instead of using passwords. Luckily Space.sh can help you with this too, look here for help with setting that up.

This tutorial was written by @ThomasBacklund.
Please share this tutorial if you find it useful. Check us out on GitLab , Twitter and other social media following the links at the bottom of this page.