Project: PlatformIO Remote Build Node
Project: PlatformIO Remote Build Node
1. Overview
We utilize an i9-13900K Server as a centralized build and flash node for embedded devices (ESP32/Arduino/Uno R4). This architecture offloads heavy compilation tasks to the high-power server while allowing the user to plug embedded devices into a lightweight remote laptop (MacBook Pro) for flashing.
2. Architecture
-
Host Hardware (Compiler): i9-13900K Server (Linux/Ubuntu 24.04+)
-
IP:
100.83.197.77(Tailscale) or192.168.0.11(LAN) -
Hostname:
code-server-1,code-server-1.story-pinecone.ts.net
-
-
Client Hardware (Agent): MacBook Pro (or other remote system)
-
Role: USB Passthrough & UI Frontend
-
-
Protocol: VS Code Remote (SSH) + PlatformIO Remote Agent
-
Network: Tailscale Mesh VPN (for seamless DNS and connectivity anywhere)
3. Server-Side Setup (The "Brain")
Perform these steps once on the Linux Server.
A. Dependencies (Fixing the Python Mismatch)
Modern Ubuntu defaults to Python 3, but PlatformIO often looks for a generic python command. We must install compatibility layers.
sudo apt update
sudo apt install -y python3-venv python3-pip python-is-python3
B. Path Configuration
PlatformIO installs into a private directory. We must add this to the global PATH so the VS Code extension can find it.
# Add to .bashrc
echo 'export PATH=$PATH:~/.platformio/penv/bin' >> ~/.bashrc
source ~/.bashrc
4. Client-Side Setup (The Mac)
Perform these steps on any new MacBook/Laptop you want to use.
A. Tailscale & DNS (Split Tunneling)
We utilize a Split DNS configuration. This ensures that the Mac uses its own local Wi-Fi for general internet access (fast, low latency) and only uses the VPN tunnel when connecting to the server.
-
Tailscale Admin Console:
-
Global Nameservers: (Optional) Can include the Pi-hole IP, but it is not strictly required for this node to function.
-
Override local DNS: Disabled. (This ensures we do not force all mobile traffic back to the home network).
-
-
Mac Client Settings:
-
Click the Tailscale Icon in the menu bar.
-
Ensure "Use Tailscale DNS" is CHECKED.
-
Why: This enables MagicDNS, allowing the Mac to resolve
code-server-1by name instantly, without routing your Netflix/Web traffic through the home lab.
-
B. SSH Configuration
Edit ~/.ssh/config to ensure stable connections:
Host code-server-1
HostName code-server-1
User pcamp96
ForwardAgent yes
ServerAliveInterval 15
ConnectTimeout 60
Run ssh-copy-id code-server-1 to enable password-less login.
C. The "Always-On" Flash Agent
To avoid opening a terminal to run pio remote agent start, we install a macOS Launch Agent.
-
Create the Service File: Run this in Mac Terminal to create
~/Library/LaunchAgents/org.platformio.agent.plist:
cat <<EOF > ~/Library/LaunchAgents/org.platformio.agent.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.platformio.agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/pio</string> <string>remote</string>
<string>agent</string>
<string>start</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin</string>
</dict>
</dict>
</plist>
EOF
-
Load the Service:
Bashlaunchctl load ~/Library/LaunchAgents/org.platformio.agent.plist
5. VS Code Configuration (The "Golden" Config)
These settings fix the "Grey Screen" and "Timeout" errors in the PlatformIO extension and streamline the workflow.
A. Remote Settings (settings.json)
Open Remote Settings (JSON) and paste this configuration. This forces the UI to use a fixed port (8008) and bypasses the broken internal browser.
{
"platformio-ide.useBuiltinPIOHome": false, // Force external browser (Safari/Chrome)
"platformio-ide.useBuiltinPython": false, // Use System Python (fixes crash)
"platformio-ide.pioHomeServerHttpHost": "0.0.0.0", // Bind to all interfaces
"platformio-ide.pioHomeServerHttpPort": 8008, // Lock to Port 8008
"platformio-ide.customPATH": "/home/pcamp96/.platformio/penv/bin" // Hard-code executable path
}
B. Manual Port Forwarding
Because auto-detection can fail, we manually forward the fixed port.
-
Open Ports tab in VS Code (bottom panel).
-
Click Forward a Port.
-
Add 8008.
C. The "Unlock" Task (Timeout Fix)
If VS Code crashes, Port 8008 may get stuck ("Timeout Error"). We add a task to "nuke" the zombie process. Create/Edit .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Unlock PIO Home",
"type": "shell",
"command": "pkill -9 -f pio",
"presentation": { "reveal": "silent", "close": true }
}
]
}
D. Custom Keybinding (One-Click Upload)
-
Open Keyboard Shortcuts: Press
Cmd + K, thenCmd + S. -
In the search bar, type:
platformio remote upload. -
Locate the command PlatformIO: Remote Upload.
-
Click the
+icon next to it. -
Press your desired key combination (Recommended:
Cmd + Opt + U). -
Press Enter.
Usage: Now, pressing this combo inside any file will instantly trigger the remote compilation and flash sequence.
6. Daily Workflow & Automation
A. Flashing Devices
No terminal required.
-
Connect Device to Mac.
-
VS Code: Press
Cmd + Opt + U(Custom keybinding forplatformio.remote.upload). -
Code compiles on i9 Server -> Flashes to Mac USB.
B. Toggling the Agent (Apple Shortcut)
Since the agent holds the USB port, it must be disabled to use other tools (like Arduino IDE). Create an Apple Shortcut containing this script to toggle the service:
PLIST="$HOME/Library/LaunchAgents/org.platformio.agent.plist"
if launchctl list | grep -q "org.platformio.agent"; then
launchctl unload "$PLIST"
echo "Agent Stopped 🔴"
else
launchctl load "$PLIST"
echo "Agent Started 🟢"
fi
7. Troubleshooting
Issue: "Timeout Error" or "Could not start PIO Home Server". Cause: The previous session left a "zombie" process holding Port 8008. Fix: Run the "Unlock PIO Home" task in VS Code (or run pkill -9 -f pio in terminal).
Issue: "Grey/Black Screen" when opening PIO Home. Cause: VS Code is not forwarding the port. Fix: Manually forward port 8008 in VS Code.