What you'll accomplish: Transform a blank Raspberry Pi into a configured Linux server ready for Kiwix.
Time required: 1h 45min (tested actual time - first build with learning)
Difficulty: ⭐⭐☆☆☆ Easy (headless setup works perfectly)
Skills learned: Linux basics, SSH keys, headless configuration, system optimization
💡 Real experience: Everything worked on first try. Headless setup is amazing - never needed monitor or keyboard!
By the end of this guide, you'll have:
- ✅ Raspberry Pi OS installed on your microSD card
- ✅ Ability to SSH into your Pi from your laptop (no monitor needed)
- ✅ System updated and secured
- ✅ Essential software installed
- ✅ Pi optimized for running Kiwix
The moment of victory: When you type ssh prometheus on your laptop and connect instantly with no password. 🎉
Before we start, gather everything:
- Raspberry Pi 4 (ideally 8GB RAM, but 4GB works)
Option 1: Medical Mission Pack (~64GB needed)
- SD Card: 64GB A2 class (~20€)
- Content: 5.5GB humanitarian medical pack
- Best for: Field missions, disaster response
- Why: Cost-effective, faster downloads
Option 2: Full Knowledge Base (~256GB needed)
- SD Card: 256GB A2 class (~35€)
- Content: Complete Wikipedia EN + FR (120GB+)
- Best for: Permanent installations, educational centers
Option 3: Minimal Test (~32GB needed)
- SD Card: 32GB A2 class (~15€)
- Content: 750MB emergency protocols only
- Best for: Prototyping, quick deployment testing
💡 Tip: Start with 64GB. You can always upgrade SD card later if needed.
- USB-C power supply (official 5V 3A, or quality equivalent - don't cheap out!)
- Your laptop/computer (Windows, Mac, or Linux)
- SD card reader (built-in or USB adapter)
- Ethernet cable (optional, but helpful for initial setup)
- HDMI cable + monitor (for troubleshooting if SSH fails)
- USB keyboard (same reason)
- Raspberry Pi Imager (official tool, free)
- SSH client (probably already on your computer)
- WiFi network name (SSID) you'll connect the Pi to - case sensitive!
- WiFi password
- Your laptop connected to same network
Ready? Let's build! 🚀
Before jumping into commands, let's understand the process:
┌──────────────────────────────────────────────────────────┐
│ YOUR LAPTOP │
│ │
│ 1. Download Raspberry Pi Imager │
│ 2. Insert microSD card │
│ 3. Write operating system to card │
│ 4. Configure WiFi + SSH settings │
│ 5. Eject card safely │
│ │
└──────────────────────────────────────────────────────────┘
│
│ [Insert card into Pi]
▼
┌──────────────────────────────────────────────────────────┐
│ RASPBERRY PI │
│ │
│ 6. Pi boots from microSD card │
│ 7. Connects to WiFi automatically │
│ 8. SSH server starts │
│ │
└──────────────────────────────────────────────────────────┘
│
│ [SSH connection]
▼
┌──────────────────────────────────────────────────────────┐
│ YOUR LAPTOP (again) │
│ │
│ 9. SSH into Pi: "ssh prometheus@192.168.x.x" │
│ 10. Update system, install packages │
│ 11. Configure settings │
│ │
└──────────────────────────────────────────────────────────┘
Key insight: We're doing 90% of the work on your laptop BEFORE the Pi even boots. This is called "headless setup" and it's way easier than fiddling with monitors and keyboards.
What is it? Official software from Raspberry Pi Foundation that writes operating systems to SD cards.
Why not just copy files? Operating systems need special formatting and boot sectors. The Imager handles all the technical stuff automatically.
- Go to: https://www.raspberrypi.com/software/
- Click "Download for Windows"
- Run the downloaded
.exefile - Install like any Windows program (Next → Next → Install)
- Same URL: https://www.raspberrypi.com/software/
- Click "Download for macOS"
- Open the
.dmgfile - Drag Raspberry Pi Imager to Applications
- Launch from Applications folder
# Ubuntu/Debian
sudo apt install rpi-imager
# Fedora
sudo dnf install rpi-imager
# Arch
sudo pacman -S rpi-imagerVerification: Launch the app. You should see a simple interface with three buttons: "Choose OS", "Choose Storage", "Write".
-
Find your SD card reader
- Built into laptop? Usually on the side
- USB adapter? Plug it in first
-
Insert the microSD card
- Metal contacts face down (usually)
- Should click into place
-
Wait for your computer to recognize it
- Windows: Check "This PC" → Should see new drive
- macOS: Check Finder → Should see mounted volume
- Linux: Run
lsblk→ Should see new device (like/dev/sdb)
⚠� CRITICAL WARNING: We're about to ERASE this card completely. Make sure:
- It's the RIGHT card (not your phone's SD card, not your camera's)
- Any important data is backed up elsewhere
- You're 100% certain before proceeding
Launch Raspberry Pi Imager and click "Choose OS"
You'll see many options. Here's what to pick:
Path:
Choose OS
→ Raspberry Pi OS (other)
→ Raspberry Pi OS Lite (64-bit)
Why this one?
- ✅ No desktop environment → Saves ~500MB RAM for Kiwix
- ✅ Headless-optimized → Designed for SSH access
- ✅ 64-bit → Better performance on Pi 4
- ✅ Smaller download → ~500MB vs 1.1GB
- ✅ Faster boot → Less stuff to load
"But I'm scared of command line!" Don't be. You'll type maybe 20 commands total. We'll explain every single one.
Path:
Choose OS
→ Raspberry Pi OS (other)
→ Raspberry Pi OS (64-bit)
When to choose this:
- You want a visual desktop (like Windows/Mac)
- You plan to connect a monitor permanently
- You're very uncomfortable with command line
Trade-offs:
- Uses more RAM (~1.5GB vs ~500MB)
- Slower boot time
- Same functionality for Prometheus Station
My recommendation: Start with Lite. If you hate it, you can always re-flash with Desktop version later. It's not permanent.
Click "Choose Storage"
You should see your microSD card listed. It might show as:
- "Generic Mass Storage" (Windows)
- "SD Card Reader" (macOS)
- "31.9 GB Device" (shows actual capacity)
How to be SURE it's the right one:
- Check the size (256GB should show as ~238GB actual)
- If multiple drives appear, eject others temporarily
- When in doubt, only have ONE SD card connected
Click your microSD card to select it.
After choosing your OS and storage, you'll see a button "NEXT" at the bottom right.
Click "NEXT"
A popup appears asking: "Would you like to apply OS customisation settings?"
Click "EDIT SETTINGS" (or "MODIFIER LES RÉGLAGES" in French)
� Configure Each Tab:
- ✅ Hostname:
prometheus-station - What it does: This is your Pi's name on the network
- Why: Easier to remember than an IP address
Example: Your input should look like the image - Prometheus-Station
- ✅ Username:
prometheus(or your choice, but remember it!) - ✅ Password: Choose something STRONG (you'll type it a lot)
- Good:
Pr0m3th3us!Station - Bad:
password123
- Good:
Why a custom username?
- Old default was
pi(everyone knew this) - Security best practice: unique username
- Makes brute-force attacks harder
- ✅ SSID: Exactly as your WiFi network name appears
- Case-sensitive! "MyWiFi" ≠"mywifi"
- Include spaces if your network has them
- ✅ Password: Your WiFi password (also case-sensitive)
- ✅ Wireless LAN country: Select your country
- France = FR
- USA = US
- Critical for legal radio frequencies
Why this matters: The Pi will connect to WiFi on first boot, automatically.
- ✅ Time zone: Your timezone (e.g.,
Europe/Paris) - ✅ Keyboard layout: Your keyboard type (e.g.,
frorus)
Why: Makes dates/logs readable, typing behaves correctly
This is CRITICAL for headless setup!
- ✅ Enable SSH: CHECK THIS BOX
- Choose: "Use password authentication"
What it does: Allows you to control the Pi remotely from your laptop
Without this: You'd need to connect a monitor and keyboard every time
- Leave unchecked for now (we're using Tailscale instead)
- Click "SAVE" (bottom right)
- You're back to the main screen
- Click "YES" when asked "Would you like to apply OS customisation settings?"
- Confirm the warning: "All existing data will be erased"
- Click "YES" to start writing
Now that all settings are configured:
-
Review the summary:
- OS: Raspberry Pi OS Lite (64-bit) ✅
- Storage: Your 256GB microSD ✅
- Customisation applied ✅
-
Click "YES" to proceed with writing
-
Final confirmation:
- "All existing data on [your SD card] will be erased"
- Click "YES" (you backed up anything important, right?)
-
Wait for the magic:
Progress stages:
Downloading Raspberry Pi OS... [0-30%] ├─ ~500MB download ├─ Speed depends on your internet └─ Coffee break time ☕ Writing to SD card... [30-70%] ├─ Actual OS installation ├─ Takes 5-10 minutes └─ Don't eject the card! Verifying... [70-100%] ├─ Checks everything wrote correctly ├─ Takes 2-5 minutes └─ This is important, don't skip! -
Success message appears:
Write Successful You can now remove the SD card -
Eject the SD card safely:
- Windows: Right-click → "Eject"
- macOS: Drag to trash (becomes eject icon)
- Linux:
sudo umount /dev/sdX(replace X with your device)
If the write fails:
- Check SD card isn't write-protected (tiny switch on adapter)
- Try a different SD card reader
- Re-download the OS (might be corrupted)
- Check if SD card is fake (common with cheap ones)
- Remove the microSD card from your computer
- Find the card slot on Raspberry Pi (underside, spring-loaded)
- Insert card (metal contacts facing the board)
- Push until it clicks
- Should be flush with the board
- Connect power cable (USB-C)
- Power on (no power button, just plug it in)
What happens next:
[0-10 seconds]
- Green LED starts blinking (reading SD card)
- Pi is booting up
[10-30 seconds]
- OS loading
- WiFi connecting
- Services starting
[30-60 seconds]
- System ready
- SSH server active
- Green LED blinks occasionally (normal activity)
How do you know it's ready?
- Green LED stops rapid blinking
- Settles into occasional flashes
- Wait 60 seconds total to be safe
If red LED turns on but green LED does nothing:
- Bad SD card write → Re-flash
- Incompatible SD card → Try different brand
- Power supply insufficient → Use official 3A supply
Your Pi is now on your network, but where? You need its IP address to SSH in.
-
Open your router's admin page:
- Common addresses:
192.168.1.1or192.168.0.1 - Or check sticker on router
- Common addresses:
-
Login:
- Default credentials often on router
- Or you set them up before
-
Find "Connected Devices" or "DHCP Clients"
-
Look for:
- Hostname:
prometheus-station - Or manufacturer: "Raspberry Pi Foundation"
- Note the IP address (like
192.168.1.42)
- Hostname:
ping prometheus-station.local
# Expected output:
# PING prometheus-station.local (192.168.1.42): 56 data bytes
# 64 bytes from 192.168.1.42: icmp_seq=0 ttl=64 time=2.4 msThe IP address is right there! (192.168.1.42 in this example)
On Windows:
ping prometheus-station.localIf it works, you'll see the IP.
For Android: Download "Fing" from Play Store For iOS: Download "Fing" from App Store For Desktop: Download "Angry IP Scanner"
- Open the app
- Scan your network
- Look for "Raspberry Pi" or "prometheus-station"
- Note the IP address
- Connect HDMI cable to Pi and monitor
- Connect USB keyboard
- Pi will show login screen
- Type command:
hostname -I - It will print the IP address
- Write it down
For the rest of this guide, I'll use 192.168.1.42 as an example. Replace it with YOUR actual IP.
This is the moment. You're about to control your Pi remotely for the first time.
-
Open PowerShell:
- Press
Win + X - Select "Windows PowerShell" or "Terminal"
- Press
-
Type this command:
ssh prometheus@192.168.1.42(Replace
192.168.1.42with YOUR Pi's IP address) -
First-time connection warning:
The authenticity of host '192.168.1.42' can't be established. ECDSA key fingerprint is SHA256:xxxxxxxxxxxxx Are you sure you want to continue connecting (yes/no)?- Type:
yesand press Enter - This is normal and only happens once
- It's SSH's way of saying "I've never met this device before"
- Type:
-
Enter password:
- Type the password you set in Raspberry Pi Imager
- You won't see characters as you type (security feature)
- Just type it and press Enter
-
Success looks like:
Linux prometheus-station 6.1.0-rpi7-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.63-1+rpt1 (2023-11-24) aarch64 prometheus@prometheus-station:~ $
You're in! 🎉
-
Open Terminal:
- macOS:
Cmd + Space→ type "Terminal" - Linux:
Ctrl + Alt + T
- macOS:
-
Same SSH command:
ssh prometheus@192.168.1.42
-
Same first-time warning:
- Type
yes - Enter password
- You're connected!
- Type
Your Laptop Raspberry Pi
│ │
│ "Hey, I want to control you" │
├─────────────────────────────────────>│
│ │
│ "Prove you're the owner" │
│<─────────────────────────────────────┤
│ │
│ [Sends password] │
├─────────────────────────────────────>│
│ │
│ "OK, you're in. Here's a shell" │
│<─────────────────────────────────────┤
│ │
│ [You type commands] │
├─────────────────────────────────────>│
│ │
│ [Pi executes and sends results] │
│<─────────────────────────────────────┤
Everything you type now runs ON THE RASPBERRY PI, not your laptop.
Mind-blowing realization: You could be in a coffee shop in Paris, SSHing into a Pi in Tokyo, and it would work exactly the same way. That's the power of SSH.
The problem: Typing password for every SSH connection gets old fast. You'll connect 50+ times during this build.
The solution: SSH keys = instant, secure, password-free login.
What you'll gain:
- ✅ 2-second connections (vs 10 seconds with password)
- ✅ More secure (2048-bit key vs guessable password)
- ✅ Works with scp, rsync, git automatically
- ✅ Industry standard practice
💡 Real experience: This saved me ~13 minutes over 100+ connections. Worth the 10min setup!
1. Generate SSH key pair:
ssh-keygen -t ed25519 -C "your-email@example.com"Prompts you'll see:
Generating public/private ed25519 key pair.
Enter file in which to save the key (C:\Users\YourName/.ssh/id_ed25519):
- Press Enter (accept default location)
Enter passphrase (empty for no passphrase):
- Press Enter for no passphrase (or set one for extra security)
- Press Enter again to confirm
Result: Key generated in ~2 seconds!
2. Copy public key to Pi:
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh prometheus@YOUR_PI_IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"Replace YOUR_PI_IP with your actual IP (e.g., 192.168.1.42)
- You'll be asked for password ONE LAST TIME
- Type it and press Enter
- This command creates
.sshfolder on Pi and adds your public key
3. Secure permissions on Pi:
ssh prometheus@YOUR_PI_IP
# Once connected:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
exitWhy: Prevents other users from reading your authorized keys.
4. Create SSH alias (optional but amazing):
notepad $env:USERPROFILE\.ssh\configIf file doesn't exist, Notepad will ask "Do you want to create?" - click Yes.
Add this content:
Host prometheus
HostName YOUR_PI_IP_OR_HOSTNAME
User prometheus
IdentityFile C:\Users\YOUR_USERNAME\.ssh\id_ed25519
Replace:
YOUR_PI_IP_OR_HOSTNAMEwith IP orprometheus-station.localYOUR_USERNAMEwith your Windows username
Save and close (File → Save, then close Notepad)
5. Test the magic:
ssh prometheusINSTANT CONNECTION. NO PASSWORD! 🚀
From now on, just type ssh prometheus - that's it!
1. Generate SSH key:
ssh-keygen -t ed25519 -C "your-email@example.com"Press Enter for all prompts (accept defaults, no passphrase).
2. Copy to Pi:
ssh-copy-id prometheus@YOUR_PI_IPReplace YOUR_PI_IP with your Pi's IP address.
- Enter password when prompted
- Key is automatically copied and permissions set
3. Test:
ssh prometheus@YOUR_PI_IPShould connect without password! ✅
Optional alias (same as Windows):
nano ~/.ssh/configAdd:
Host prometheus
HostName YOUR_PI_IP
User prometheus
Save (Ctrl+X, Y, Enter)
Now: ssh prometheus works!
Your laptop has two keys:
- Private key (
id_ed25519) - stays on your laptop, NEVER share - Public key (
id_ed25519.pub) - copied to Pi
When you SSH:
- Pi says: "Prove you have the private key"
- Your laptop uses private key to create signature
- Pi verifies with public key
- Connection allowed - no password needed!
More secure than password: Even if someone sees your username, they can't login without your private key file.
Now that you're logged in, let's configure the Pi properly.
Why? Your OS image was created weeks/months ago. Security patches and bug fixes have been released since then.
sudo apt update && sudo apt upgrade -yLet's decode this command:
sudo= "Run as administrator" (super user do)apt= Package manager (like App Store for Linux)update= Refresh the list of available packagesupgrade -y= Install all updates (-y means "yes to all prompts")&&= "Run second command only if first succeeds"
What you'll see:
Hit:1 http://deb.debian.org/debian bookworm InRelease
Get:2 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
...
Reading package lists... Done
Building dependency tree... Done
...
47 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 68.2 MB of archives.
After this operation, 124 kB of additional disk space will be used.
How long? 5-15 minutes depending on internet speed and number of updates.
Coffee break time ☕
When it finishes:
prometheus@prometheus-station:~ $
You're back at the prompt, ready for the next command.
sudo raspi-configWhat is this? A text-based menu for configuring Pi-specific settings.
You'll see a blue screen with options:
┌─────────────┤ Raspberry Pi Software Configuration Tool ├──────────────�
│ │
│ 1 System Options Configure system settings │
│ 2 Display Options Configure display settings │
│ 3 Interface Options Configure connections to peripherals │
│ 4 Performance Options Configure performance settings │
│ 5 Localisation Options Configure language and regional settings │
│ 6 Advanced Options Configure advanced settings │
│ 8 Update Update this tool to the latest version │
│ 9 About raspi-config Information about this configuration tool │
│ │
│ <Select> <Finish> │
└────────────────────────────────────────────────────────────────────────┘
Navigation:
- Use arrow keys to move up/down
- Press Enter to select
- Press Tab to move between buttons (
<Select>/<Finish>) - Press Esc twice to exit
Path: 6 Advanced Options → A1 Expand Filesystem
What it does: Makes the entire SD card available (by default, only 2GB is used)
Why: We need all 256GB for Wikipedia files
Action:
- Select
6 Advanced Options - Select
A1 Expand Filesystem - Press Enter on "OK"
- You're back at main menu
Path: 4 Performance Options → P2 GPU Memory (if available)
Important Note: On newer Raspberry Pi OS versions (late 2024+), this option may not exist. GPU memory is now automatically managed by the system.
If you see "P2 GPU Memory":
What it does: Allocates RAM between CPU and GPU
Why: We're headless (no monitor), so GPU doesn't need much RAM
Action:
- Select
4 Performance Options - Select
P2 GPU Memory - Enter:
16(minimum for GPU) - Press Enter
- Back to main menu
What this gives you: ~16MB saved for CPU/Kiwix = faster searches
If you DON'T see this option:
- Your system already manages GPU memory automatically
- This is normal on newer OS versions
- Skip to Setting 3 - your system is already optimized!
Path: 3 Interface Options → I2 SSH
What it does: Ensures SSH is enabled (should already be from Imager settings)
Why: Double-check it's on
Action:
- Select
3 Interface Options - Select
I2 SSH - Should say "SSH server is enabled"
- If not, select "Yes" to enable
- Back to main menu
Path: 1 System Options → S4 Hostname
What it does: Change the network name
Why: If you didn't set it in Imager, or want to change it
Action:
- Select
1 System Options - Select
S4 Hostname - Enter:
prometheus-station - Press Enter
If you see "P2 GPU Memory":
- Select
4 Performance Options - Select
P2 GPU Memory - Enter:
16(minimum for GPU) - Press Enter
- Back to main menu
What this gives you: ~240MB RAM freed for Kiwix
If you DON'T see this option:
- This is NORMAL on newer OS versions
- GPU memory is optimized automatically
- Skip to Setting 3 - your system is already optimized!
| curl | Download files from URLs | Scripting, API calls |
| wget | Alternative file downloader | Backup for curl |
| vim | Text editor | Edit config files (alternative to nano) |
| htop | Process monitor | See what's using CPU/RAM |
| ufw | Firewall | Security (block unwanted connections) |
Installation takes: ~2 minutes
What is Tailscale? A VPN that lets you access your Pi from ANYWHERE in the world, securely.
Without Tailscale:
- You can SSH into Pi only when on same WiFi network
- If you're at a coffee shop, you can't access your Pi at home
- Port forwarding is complicated and insecure
- Dynamic IP addresses are a nightmare
With Tailscale:
- Access Pi from anywhere: home, work, coffee shop, another country
- No port forwarding needed (works through firewalls)
- Encrypted connection (VPN-grade security)
- Works even if your home IP changes
- Free for personal use (up to 100 devices)
Real-world scenario:
You're in a café in Paris.
Your Pi is at home in Lyon.
Type: ssh prometheus@100.x.x.x (Tailscale IP)
→ You're connected instantly. Securely. Magically.
Think of it as: Your Pi gets a permanent phone number that works globally.
1. Install Tailscale:
curl -fsSL https://tailscale.com/install.sh | shWhat this does:
- Downloads official Tailscale installer
- Installs Tailscale daemon (background service)
- Configures system integration
Takes: ~30 seconds
2. Start Tailscale and Authenticate:
sudo tailscale upYou'll see:
To authenticate, visit:
https://login.tailscale.com/a/xxxxxxxxxxxx
What to do:
- Copy that URL (the one starting with https://login.tailscale.com/)
- Open it in your web browser (on your laptop, not the Pi)
- Sign in with:
- Google account (easiest)
- GitHub account
What is swap? When RAM fills up, the system uses SD card as "fake RAM" (swap space).
Problem: SD cards are SLOW and wear out from constant writing.
Solution: Disable swap (we have 8GB RAM, plenty for our needs).
# Turn off swap immediately
sudo swapoff -a
# Prevent swap from coming back after reboot
sudo systemctl disable dphys-swapfile.service 2>/dev/null || sudo systemctl mask swap.target
# Check it's off
free -hExpected output:
total used free shared buff/cache available
Mem: 7.6Gi 313Mi 6.6Gi 9.6Mi 806Mi 7.3Gi
Swap: 0B 0B 0B
See that Swap: 0B? Perfect. ✅
What the commands do:
swapoff -a→ Disables all swap immediatelysystemctl mask swap.target→ Prevents swap from re-enabling on reboot- The
2>/dev/null ||part handles both old and new OS versions gracefully
Verify after reboot:
sudo rebootWait 30 seconds, reconnect, then:
free -hSwap should still be 0B. ✅
If you have 4GB RAM: Consider keeping swap enabled (skip these commands).
Example output:
100.84.123.45
Write this down! This is your Pi's permanent address.
4. Test It:
From your laptop (open a NEW terminal, don't disconnect your current SSH):
ping 100.84.123.45(Use YOUR Tailscale IP, not this example)
Expected:
PING 100.84.123.45: 56 data bytes
64 bytes from 100.84.123.45: icmp_seq=0 ttl=64 time=12.4 ms
It works! Even though you're on the same network now, this will work from ANYWHERE.
5. SSH via Tailscale:
Try connecting through Tailscale:
ssh prometheus@100.84.123.45If it works: You can now access your Pi from anywhere! �
Optional but Recommended: Disable Key Expiry
By default, Tailscale keys expire after 180 days (you'd need to re-authenticate).
To disable expiry:
- Go to: https://login.tailscale.com/admin/machines
- Find "prometheus-station"
- Click the "..." menu
- Select "Disable key expiry"
- Confirm
Now your Pi stays connected forever. No re-authentication needed.
Optional: Set a Friendly Hostname
In the Tailscale admin panel:
- Click on "prometheus-station"
- Under "Machine name" → Edit
- Set to:
prometheus(short and easy) - Save
Now you can SSH with:
ssh prometheus@prometheusEven cleaner! (Tailscale handles the .ts.net domain automatically)
From now on, you have TWO ways to access your Pi:
Method 1: Local Network (when at home)
ssh prometheus@192.168.1.42
# Fast, direct connectionMethod 2: Tailscale (from anywhere)
ssh prometheus@100.84.123.45
# or
ssh prometheus@prometheus.ts.net
# Works globally, encryptedBest practice: Use Tailscale for EVERYTHING. It works locally AND remotely.
1. MagicDNS (automatic)
- Your Pi is accessible at:
prometheus-station.your-tailnet-name.ts.net - No need to remember IPs
2. File sharing:
# On Pi, share a file
tailscale file cp /path/to/file.txt YOUR_LAPTOP_NAME:
# On laptop, receive it
tailscale file get3. Exit node (advanced):
- Route ALL your laptop's internet through your Pi
- Useful for accessing home network resources remotely
Problem: "curl: command not found"
# Install curl first
sudo apt install curl
# Then retry Tailscale installProblem: "tailscale up" hangs
- Press Ctrl+C
- Check internet:
ping 8.8.8.8 - Retry:
sudo tailscale up
Problem: Can't access auth URL
- URL is ONLY for your laptop's browser, not the Pi
- Copy-paste the ENTIRE URL (including the long code)
Problem: Tailscale IP doesn't ping
- Check Tailscale status:
tailscale status - Restart Tailscale:
sudo systemctl restart tailscaled - Check firewall allows Tailscale:
sudo ufw allow in on tailscale0
If you installed Tailscale, allow it through the firewall:
# Allow all traffic on Tailscale interface
sudo ufw allow in on tailscale0Why: Tailscale creates its own network interface. UFW needs to know it's safe.
# See connected devices
tailscale status
# See your IPs
tailscale ip -4
# Test connection to another device
tailscale ping OTHER_DEVICE_NAMEBy installing Tailscale, you've:
- ✅ Created a global VPN for your Pi
- ✅ Eliminated the need for port forwarding
- ✅ Made your Pi accessible from anywhere
- ✅ Added military-grade encryption to all connections
- ✅ Future-proofed your deployment (works even if you move)
This is POWERFUL. You can now manage Prometheus Station from literally anywhere on Earth with internet. �
Skip Tailscale? You can, but you'll regret it when you want to check on your Pi remotely and can't. Just install it now. Takes 2 minutes, saves hours of frustration later.
Why a firewall? Your Pi is on your network. A firewall blocks unwanted connections.
# Allow SSH (port 22) - CRITICAL, or you'll lock yourself out!
sudo ufw allow 22/tcp
# Allow Kiwix web server (port 80)
sudo ufw allow 80/tcp
# Enable firewall
sudo ufw enableYou'll see:
Command may disrupt existing ssh connections. Proceed with operation (y|n)?
Type y and press Enter.
Why port 22 FIRST? If you enable UFW without allowing SSH, your connection drops and you can't get back in. Always allow SSH before enabling.
Check firewall status:
sudo ufw statusExpected output:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
✅ Perfect! Firewall is protecting you while allowing necessary services.
What is swap? When RAM fills up, the system uses SD card as "fake RAM" (swap space).
Problem: SD cards are SLOW and wear out from constant writing.
Solution: Disable swap (we have 8GB RAM, plenty for our needs).
Note: Commands have changed in newer Raspberry Pi OS versions. Use this updated method:
# Turn off swap immediately
sudo swapoff -a
# Prevent swap from coming back after reboot
sudo systemctl disable dphys-swapfile.service 2>/dev/null || sudo systemctl mask swap.target
# Check it's off
free -hExpected output:
total used free shared buff/cache available
Mem: 7.6Gi 313Mi 6.6Gi 9.6Mi 806Mi 7.3Gi
Swap: 0B 0B 0B
See that Swap: 0B? Perfect. ✅
What the commands do:
swapoff -a→ Disables all swap immediatelysystemctl mask swap.target→ Prevents swap from re-enabling on reboot- The
2>/dev/null ||part handles both old and new OS versions gracefully
Verify after reboot:
sudo rebootWait 30 seconds, reconnect, then:
free -hSwap should still be 0B. ✅
If you have 4GB RAM: Consider keeping swap enabled (skip these commands).
What are services? Background programs that start automatically.
Problem: Some are useless for a headless server and waste resources.
# Bluetooth (we're not using it)
sudo systemctl disable bluetooth.service
# Bluetooth modem (related to above)
sudo systemctl disable hciuart.service
# Audio (no speakers on a headless server)
sudo systemctl disable alsa-state.service
# Verify they're disabled
sudo systemctl status bluetooth.serviceExpected: Loaded: loaded (/lib/systemd/system/bluetooth.service; disabled;
RAM saved: ~50-100MB
Boot time saved: ~2-3 seconds
This is a handy script to check system health at any time.
# Create the script
nano ~/system_status.shNano editor opens. Paste this script:
#!/bin/bash
# Prometheus Station System Status
echo "======================================"
echo " PROMETHEUS STATION - System Status"
echo "======================================"
echo ""
# System uptime
echo "Uptime:"
uptime
echo ""
# Temperature
echo "CPU Temperature:"
vcgencmd measure_temp
echo ""
# Memory usage
echo "Memory Usage:"
free -h
echo ""
# Disk usage
echo "Disk Usage:"
df -h / | grep -v Filesystem
echo ""
# Network interfaces
echo "Network Interfaces:"
ip -brief addr
echo ""
# Active connections
echo "Active SSH Connections:"
who
echo ""
echo "======================================"Save the file:
- Press
Ctrl + X - Press
Y(yes, save) - Press
Enter(confirm filename)
Make it executable:
chmod +x ~/system_status.shTest it:
~/system_status.shYou'll see:
======================================
PROMETHEUS STATION - System Status
======================================
Uptime:
08:23:14 up 15 min, 1 user, load average: 0.08, 0.12, 0.09
CPU Temperature:
temp=42.8'C
Memory Usage:
total used free shared buff/cache available
Mem: 7.8Gi 156Mi 7.4Gi 8.0Mi 287Mi 7.5Gi
Swap: 0B 0B 0B
Disk Usage:
/dev/root 233G 2.1G 220G 1% /
Network Interfaces:
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 DOWN
wlan0 UP 192.168.1.42/24
Active SSH Connections:
prometheus pts/0 2025-12-26 08:08 (192.168.1.100)
======================================
Bookmark this! You'll use it constantly to check on your Pi.
Before moving to Step 2 (Kiwix), verify everything works:
- Can SSH into Pi from laptop:
ssh prometheus@192.168.1.42 - (If installed) Can SSH via Tailscale:
ssh prometheus@100.x.x.x - Filesystem expanded (df -h shows full SD card capacity)
- System updated (
sudo apt updateshows no pending updates)
- Hostname set correctly (
hostnamereturnsprometheus-station) - GPU memory set to 16MB (
vcgencmd get_mem gpureturnsgpu=16M) - SSH enabled (
sudo systemctl status sshshows "active (running)") - (If installed) Tailscale running (
tailscale statusshows connected devices)
- Firewall active (
sudo ufw statusshows "Status: active") - SSH port allowed (port 22 in firewall rules)
- Kiwix port allowed (port 80 in firewall rules)
- (If installed) Tailscale allowed (
tailscale0interface in ufw rules)
- Swap disabled (
free -hshows Swap: 0B) - Bluetooth disabled (
systemctl status bluetoothshows "disabled") - System monitoring script works (
~/system_status.shruns without errors)
- Temperature under 60°C (
vcgencmd measure_temp) - Free RAM > 6GB (
free -h) - CPU load average < 1.0 (
uptime)
All checkboxes ticked? 🎉 You're ready for Step 2!
System specs you should see:
hostname
# Output: Prometheus-Station (or your chosen name)
uname -a
# Output: Linux Prometheus-Station 6.12.47+rpt-rpi-v8 #1 SMP PREEMPT Debian... (or newer kernel)
vcgencmd measure_temp
# Output: temp=40.0-45.0'C (idle, with fan)
free -h
# Mem: 7.8Gi total, ~7.4Gi free (after fresh boot)
# Swap: 0B 0B 0B
df -h /
# /dev/root: 233G total (for 256GB SD), ~2.1G used initiallyWhat's normal:
- Temperature: 40-50°C idle (with fan), up to 60°C under load
- Boot time: ~45-60 seconds from power-on to SSH ready
- RAM usage: ~300-500MB after boot
- Kernel version: 6.12.x or newer (OS is actively updated)
- First update: 40-50 packages typically need updating
What's NOT normal (troubleshoot if you see this):
- ❌ Temperature >70°C idle → Check fan, improve cooling
- ❌ RAM usage >2GB idle → Something is wrong, investigate
- ❌ "Under-voltage detected" warnings → Bad power supply!
- ❌ Swap not 0B after disabling → Reboot and verify again
- ❌ SD card showing only 2GB → Filesystem not expanded
Symptom: ssh: connect to host 192.168.1.42 port 22: Connection refused
Possible causes:
-
Wrong IP address
- Solution: Re-scan network, find correct IP
-
Pi didn't connect to WiFi
- Solution: Connect monitor, check
ifconfig - Verify WiFi SSID/password in imager were correct
- Solution: Connect monitor, check
-
SSH not enabled
- Solution: Re-flash SD card, ensure SSH enabled in imager settings
-
Firewall blocking (on your laptop)
- Windows: Check Windows Defender Firewall
- macOS: Check System Preferences → Security
-
Pi not booted yet
- Solution: Wait 2 full minutes after power-on
Symptom: Connects, then disconnects within seconds
Possible causes:
-
Power supply insufficient
- Solution: Use official 3A power supply
- Check for "low voltage" icon on Pi (lightning bolt)
-
SD card corruption
- Solution: Re-flash SD card, use quality A2 card
-
Overheating
- Solution: Add heatsinks, improve ventilation
- Check temp:
vcgencmd measure_temp(should be <80°C)
Symptom: Failed to fetch... Could not resolve 'deb.debian.org'
Cause: No internet connection
Solutions:
-
Check WiFi connection:
iwconfig # Should show wlan0 connected -
Verify DNS working:
ping 8.8.8.8 # Should get responses -
Reconnect WiFi:
sudo raspi-config # Navigate to: System Options → Wireless LAN # Re-enter SSID and password
Symptom: df -h shows only 2GB available
Solution:
# Expand manually
sudo raspi-config
# Navigate to: Advanced Options → Expand Filesystem
# Reboot
sudo rebootSymptom: vcgencmd measure_temp shows >70°C
Immediate action:
# Check what's using CPU
htop
# Press F10 to quitLong-term solutions:
- Add heatsink to CPU
- Add fan (if you have POE HAT)
- Improve airflow around Pi
- Don't run in enclosed space
Critical: If temp hits 80°C+, Pi will throttle (slow down). At 85°C, it will shut down to protect itself.
Symptom: SSH asks for password, but you forgot what you set
Solution (requires monitor + keyboard):
- Connect monitor and keyboard to Pi
- At login: username =
prometheus, try common passwords - If locked out completely:
- Re-flash SD card
- Set new password in Imager
- Start over (sorry, no password recovery on Linux)
Prevention: Write down your password somewhere safe!
Based on real experience building this - these mistakes cost me ~30 minutes combined. You can skip them all!
- ❌ Mistake: Buying cheap A1 or Class 10 card to save 5€
- ✅ Solution: Get A2 class specifically
- Impact: 3-5x slower Wikipedia searches, frustrating user experience
- Why it matters: A2 has better random read/write for databases
- ❌ Mistake: Using phone charger (2A) or cheap no-name adapter
- ✅ Solution: Official Raspberry Pi power supply (3A) or quality equivalent
- Impact: Random reboots, "low voltage" warnings, SD card corruption
- Why it matters: Pi 4 needs stable 3A, especially under load
- ❌ Mistake: Typing "MyWiFi" when actual network is "mywifi"
- ✅ Solution: Copy-paste SSID exactly (it's case sensitive!)
- Impact: Pi won't connect to WiFi, need monitor/keyboard to debug
- How to avoid: Triple-check SSID in Raspberry Pi Imager settings
- ❌ Mistake: Running
sudo ufw enablebeforesudo ufw allow 22/tcp - ✅ Solution: ALWAYS allow SSH port first, THEN enable firewall
- Impact: Locked out of your Pi! Need monitor/keyboard to fix
- Remember: SSH = port 22. Allow it before enabling UFW!
- ❌ Mistake: Pasting ``` or ** or other markdown into PowerShell/Terminal
- ✅ Solution: Only copy actual commands, not the formatting around them
- Impact: Confusing "command not found" errors
- Tip: If guide shows ```bash, don't copy that line - start after it!
- ❌ Mistake: Using
&&to chain commands (Bash syntax) - ✅ Solution: Use
;in PowerShell instead - Example:
git add . ; git commit -m "msg" ; git push - Why: PowerShell and Bash have different syntax for chaining
- ❌ Mistake: Skipping SSH key setup to "save time"
- ✅ Solution: Take 10 minutes to set up keys now
- Impact: You'll waste 13+ minutes typing passwords during build
- Bonus: More secure AND more convenient!
💡 Pro tip: If something doesn't work, check these pitfalls first. They're the most common issues!
Congratulations! You've just:
✅ Installed an operating system from scratch
✅ Configured headless access (no monitor needed)
✅ Secured a Linux system (firewall, SSH hardening)
✅ Optimized performance (disabled swap, unnecessary services)
✅ Learned basic Linux commands (sudo, apt, systemctl)
✅ Troubleshot network issues (finding IP, SSH debugging)
These skills transfer to:
- Any Raspberry Pi project
- Linux server administration
- IoT device management
- Cloud computing (same principles)
You're now a sysadmin. 🎉 (Well, baby sysadmin. But still!)
Keep these handy:
# System information
uname -a # Kernel version
cat /etc/os-release # OS version
vcgencmd measure_temp # CPU temperature
free -h # RAM usage
df -h # Disk usage
# Network
ip addr # Show IP addresses
ping google.com # Test internet
iwconfig # WiFi status
# Tailscale (if installed)
tailscale status # See all connected devices
tailscale ip -4 # Show your Tailscale IP
tailscale ping DEVICE # Test connection to another device
sudo tailscale up # Connect to Tailscale network
sudo tailscale down # Disconnect from Tailscale
# Process management
htop # Visual process monitor
ps aux # List all processes
kill <PID> # Kill a process
# Services
sudo systemctl status <name> # Check service status
sudo systemctl start <name> # Start service
sudo systemctl stop <name> # Stop service
sudo systemctl restart <name> # Restart service
sudo systemctl enable <name> # Auto-start on boot
sudo systemctl disable <name> # Disable auto-start
# File operations
ls -la # List files (detailed)
cd /path/to/directory # Change directory
nano filename # Edit file
cat filename # Display file contents
chmod +x filename # Make file executable
# System maintenance
sudo apt update # Update package list
sudo apt upgrade # Upgrade packages
sudo apt clean # Clean package cache
sudo reboot # Reboot system
sudo shutdown -h now # Shutdown immediatelyPro tip: Bookmark this section. You'll reference it constantly.
Your Raspberry Pi is now ready for Kiwix!
Head to: Step 2: Kiwix Installation
In Step 2, you'll:
- Install Kiwix server software
- Download Wikipedia ZIM files (~171GB)
- Configure Kiwix as a systemd service
- Access Wikipedia through your browser
Estimated time: 3-4 hours (mostly downloading)
See you there! 🔥
Last updated: December 2025
Tested on: Raspberry Pi 4 (8GB), Raspberry Pi OS Lite (64-bit)
Written by: Guillain Mejane
Questions? Open an issue on GitHub!
| Phase | Actual Time | Notes |
|---|---|---|
| SD Card Prep | 28 min | First time, learning Imager interface |
| First Boot & Find IP | 20 min | Exploring router, testing connectivity |
| SSH Key Setup | 10 min | Worth every second - saves time later! |
| System Configuration | 45 min | System updates took ~35min on 50 Mbps connection |
| TOTAL | 1h 45min | Smooth process, zero blockers |
Time Perspective:
- First-time build: ~2 hours with learning and exploration
- Repeat builds: ~1 hour once you know the process
- Waiting time: ~45min (downloads, updates - make coffee!)
- Active hands-on time: ~60min
What slows you down:
- Internet speed (for OS download + system updates)
- First time learning Raspberry Pi Imager
- Finding Pi's IP address if router is unfamiliar
What speeds you up:
- SSH keys (instant connections)
- Headless setup (no monitor juggling)
- This guide (skip my mistakes!)
For Windows users: Some command syntax differs from Linux/macOS guides.
Chaining commands:
# ❌ WRONG (Bash syntax):
sudo apt update && sudo apt upgrade -y
# ✅ RIGHT (PowerShell):
# Just run commands separately, or use:
sudo apt update ; sudo apt upgrade -yWhy: PowerShell uses ; not && for command chaining.
Paths:
# Bash uses:
~/.ssh/config
# PowerShell uses:
$env:USERPROFILE\.ssh\configWhen in doubt: Just run commands one at a time instead of chaining.