This guide covers taking a stock, unmodified Nintendo Wii and turning it into a rehosted node — a solar-powered web server on your LAN that syncs and serves static sites.
[WII SPECS] CPU : IBM Broadway (PowerPC 729MHz) RAM : 88 MB (24 MEM1 + 64 MEM2) Storage : SD card via EXI bus (slow) Network : WiFi 802.11b/g / USB Ethernet adapter Power draw : 15-20W under load OS target : wii-linux-ngx (Debian-based)
The Wii needs to run unsigned code. This is a well-documented, reversible process. We use the LetterBomb exploit to install the Homebrew Channel.
private/
boot.elf
nand.bin
keys.bin
Priiloader adds a pre-system-menu layer that lets you auto-boot into homebrew apps — essential for making the Wii boot straight into Linux on power-on.
apps/priiloader/
We use wii-linux-ngx, a community-maintained Linux distribution for the Wii based on Debian. It runs from the SD card.
wii-jessie-*.img.xz
xz -d wii-jessie-*.img.xz
dd if=wii-jessie-*.img of=/dev/sdX bs=4M status=progress
/dev/sdX
# After writing the image: sudo parted /dev/sdX resizepart 2 100% sudo e2fsck -f /dev/sdX2 sudo resize2fs /dev/sdX2
apps/
root
dmesg | grep -i eth
# /etc/network/interfaces auto eth0 iface eth0 inet static address 192.168.4.60 netmask 255.255.255.0 gateway 192.168.4.1 dns-nameservers 192.168.4.1
ifup eth0
ping 192.168.4.48
which sshd
update-rc.d ssh defaults /etc/init.d/ssh start
apt-get update apt-get install openssh-server
ssh root@192.168.4.60
ssh-copy-id -i deploy/deploy_key.pub root@192.168.4.60
The node agent is a single Python file. No pip, no virtualenv, no dependencies.
python --version # Likely Python 2.7 python3 --version # Might be 3.2 or 3.4 if available
Either version works. The agent is written for Python 2.7+ / 3.2+ compatibility.
mkdir -p /opt/rehosted cd /opt/rehosted
scp -i deploy/deploy_key node_agent/node_agent.py root@192.168.4.60:/opt/rehosted/ scp -i deploy/deploy_key node_agent/config.example.json root@192.168.4.60:/opt/rehosted/config.json
config.json
{ "controller_url": "http://192.168.4.48:8080", "hardware_id": "wii-001", "port": 8080, "sync_interval": 120, "sites_dir": "/opt/rehosted/sites" }
sync_interval
cd /opt/rehosted python node_agent.py
[server] Listening on port 8080, serving from /opt/rehosted/sites/ [agent] Sync interval: 120s [agent] Controller: http://192.168.4.48:8080 [agent] Hardware ID: wii-001 [sync] Downloaded xrouter/index.html ...
curl -H "Host: xrouter.rehosted.net" http://192.168.4.60:8080/
Wii Linux uses sysvinit (no systemd). Create an init script:
cat > /etc/init.d/rehosted-agent << 'INITEOF' #!/bin/sh ### BEGIN INIT INFO # Provides: rehosted-agent # Required-Start: $network $local_fs # Required-Stop: $network $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: Rehosted node agent ### END INIT INFO AGENT_DIR=/opt/rehosted PIDFILE=/var/run/rehosted-agent.pid LOGFILE=/var/log/rehosted-agent.log case "$1" in start) echo "Starting rehosted-agent..." cd "$AGENT_DIR" python node_agent.py >> "$LOGFILE" 2>&1 & echo $! > "$PIDFILE" ;; stop) echo "Stopping rehosted-agent..." if [ -f "$PIDFILE" ]; then kill $(cat "$PIDFILE") 2>/dev/null rm -f "$PIDFILE" fi ;; restart) $0 stop $0 start ;; status) if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE") 2>/dev/null; then echo "rehosted-agent is running (PID $(cat "$PIDFILE"))" else echo "rehosted-agent is not running" fi ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac exit 0 INITEOF chmod +x /etc/init.d/rehosted-agent update-rc.d rehosted-agent defaults
Test it: /etc/init.d/rehosted-agent start, then check tail -f /var/log/rehosted-agent.log
/etc/init.d/rehosted-agent start
tail -f /var/log/rehosted-agent.log
The controller needs to know about the Wii so it can route traffic and generate the manifest.
https://rehosted.net/admin/
Name: Nintendo Wii Description: Nintendo Wii (Broadway PPC, 88MB RAM, SD storage) Power watts: 18
Name: wii-001 Node type: Nintendo Wii Hardware ID: wii-001 IP Address: 192.168.4.60 Port: 8080 Is Active: True (once tested) / False (to use fallback)
wii-001
# On the Pi, inside the container: docker exec rehosted-web-1 python rehosted_site/manage.py generate_nginx_conf docker exec rehosted-web-1 nginx -s reload
This generates a vhost that proxies bucketname.rehosted.net to 192.168.4.60:8080, with a fallback to the local copy if the Wii is unreachable (502/503/504).
bucketname.rehosted.net
192.168.4.60:8080
The final step: make the Wii boot straight into Linux on power-on, with no human interaction needed. This is what makes it a proper unattended server.
Power cycle the Wii. It should boot straight into Linux, the network should come up, and the rehosted agent should start automatically. Verify by checking last_seen in Django admin — it should update within a couple of minutes.
last_seen
curl http://192.168.4.48:8080/
/var/log/rehosted-agent.log
hardware_id
user_files/{bucket}/
This is a known risk. If the Wii can't maintain a reliable Linux install, mark the node as inactive in Django admin. Nginx will serve the fallback copy from the Pi. The Wii stays listed as the node for branding purposes — the site still says "hosted on a Nintendo Wii" — while the Pi does the actual serving. You can revisit when wii-linux-ngx improves.