# Disable services that eat RAM for breakfast
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable bluetooth
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable avahi-daemon
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable triggerhappy
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily--weight: 500;">upgrade.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable man-db.timer # Disable swap — on SD cards, swap kills your storage
-weight: 600;">sudo dphys-swapfile swapoff
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable dphys-swapfile # Drop to single TTY instead of six
# Edit /etc/systemd/logind.conf
NAutoVTs=1
ReserveVT=0
# Disable services that eat RAM for breakfast
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable bluetooth
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable avahi-daemon
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable triggerhappy
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily--weight: 500;">upgrade.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable man-db.timer # Disable swap — on SD cards, swap kills your storage
-weight: 600;">sudo dphys-swapfile swapoff
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable dphys-swapfile # Drop to single TTY instead of six
# Edit /etc/systemd/logind.conf
NAutoVTs=1
ReserveVT=0
# Disable services that eat RAM for breakfast
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable bluetooth
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable avahi-daemon
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable triggerhappy
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable -weight: 500;">apt-daily--weight: 500;">upgrade.timer
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable man-db.timer # Disable swap — on SD cards, swap kills your storage
-weight: 600;">sudo dphys-swapfile swapoff
-weight: 600;">sudo -weight: 500;">systemctl -weight: 500;">disable dphys-swapfile # Drop to single TTY instead of six
# Edit /etc/systemd/logind.conf
NAutoVTs=1
ReserveVT=0
# Serve static files from /var/www with BusyBox httpd
# -f keeps it in foreground, -p sets port, -h sets document root
busybox httpd -f -p 80 -h /var/www
# Serve static files from /var/www with BusyBox httpd
# -f keeps it in foreground, -p sets port, -h sets document root
busybox httpd -f -p 80 -h /var/www
# Serve static files from /var/www with BusyBox httpd
# -f keeps it in foreground, -p sets port, -h sets document root
busybox httpd -f -p 80 -h /var/www
# Build from source — it's literally one file
gcc -O2 -o darkhttpd darkhttpd.c # Run it
./darkhttpd /var/www --port 80 --daemon --log /var/log/darkhttpd.log
# Build from source — it's literally one file
gcc -O2 -o darkhttpd darkhttpd.c # Run it
./darkhttpd /var/www --port 80 --daemon --log /var/log/darkhttpd.log
# Build from source — it's literally one file
gcc -O2 -o darkhttpd darkhttpd.c # Run it
./darkhttpd /var/www --port 80 --daemon --log /var/log/darkhttpd.log
<!-- Keep it simple. This entire page is under 5KB. -->
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My Solar-Powered Site</title> <style> /* Inline CSS — one fewer HTTP request */ body { font-family: system-ui, sans-serif; /* no web font download */ max-width: 42rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; color: #1a1a1a; } /* Use prefers-color-scheme instead of JS theme toggles */ @media (prefers-color-scheme: dark) { body { background: #111; color: #e0e0e0; } } </style>
</head>
<body> <h1>Served by sunlight</h1> <p>This page was delivered by a computer running on a solar panel.</p> <!-- Server -weight: 500;">status injected by a simple CGI script or cron-generated file --> <p>Battery: <!--#include virtual="/-weight: 500;">status.txt" --></p>
</body>
</html>
<!-- Keep it simple. This entire page is under 5KB. -->
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My Solar-Powered Site</title> <style> /* Inline CSS — one fewer HTTP request */ body { font-family: system-ui, sans-serif; /* no web font download */ max-width: 42rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; color: #1a1a1a; } /* Use prefers-color-scheme instead of JS theme toggles */ @media (prefers-color-scheme: dark) { body { background: #111; color: #e0e0e0; } } </style>
</head>
<body> <h1>Served by sunlight</h1> <p>This page was delivered by a computer running on a solar panel.</p> <!-- Server -weight: 500;">status injected by a simple CGI script or cron-generated file --> <p>Battery: <!--#include virtual="/-weight: 500;">status.txt" --></p>
</body>
</html>
<!-- Keep it simple. This entire page is under 5KB. -->
<!DOCTYPE html>
<html lang="en">
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My Solar-Powered Site</title> <style> /* Inline CSS — one fewer HTTP request */ body { font-family: system-ui, sans-serif; /* no web font download */ max-width: 42rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; color: #1a1a1a; } /* Use prefers-color-scheme instead of JS theme toggles */ @media (prefers-color-scheme: dark) { body { background: #111; color: #e0e0e0; } } </style>
</head>
<body> <h1>Served by sunlight</h1> <p>This page was delivered by a computer running on a solar panel.</p> <!-- Server -weight: 500;">status injected by a simple CGI script or cron-generated file --> <p>Battery: <!--#include virtual="/-weight: 500;">status.txt" --></p>
</body>
</html>
#!/bin/bash
# /usr/local/bin/power-monitor.sh
# Check battery voltage via ADC and gracefully shut down before power dies VOLTAGE=$(cat /sys/class/power_supply/battery/voltage_now 2>/dev/null)
# Threshold in microvolts — 3.3V is the danger zone for most LiPo cells
THRESHOLD=3300000 if [ -n "$VOLTAGE" ] && [ "$VOLTAGE" -lt "$THRESHOLD" ]; then logger "Battery critical ($VOLTAGE uV), initiating shutdown" # Sync filesystem before power dies — SD card corruption is the real enemy sync shutdown -h now
fi
#!/bin/bash
# /usr/local/bin/power-monitor.sh
# Check battery voltage via ADC and gracefully shut down before power dies VOLTAGE=$(cat /sys/class/power_supply/battery/voltage_now 2>/dev/null)
# Threshold in microvolts — 3.3V is the danger zone for most LiPo cells
THRESHOLD=3300000 if [ -n "$VOLTAGE" ] && [ "$VOLTAGE" -lt "$THRESHOLD" ]; then logger "Battery critical ($VOLTAGE uV), initiating shutdown" # Sync filesystem before power dies — SD card corruption is the real enemy sync shutdown -h now
fi
#!/bin/bash
# /usr/local/bin/power-monitor.sh
# Check battery voltage via ADC and gracefully shut down before power dies VOLTAGE=$(cat /sys/class/power_supply/battery/voltage_now 2>/dev/null)
# Threshold in microvolts — 3.3V is the danger zone for most LiPo cells
THRESHOLD=3300000 if [ -n "$VOLTAGE" ] && [ "$VOLTAGE" -lt "$THRESHOLD" ]; then logger "Battery critical ($VOLTAGE uV), initiating shutdown" # Sync filesystem before power dies — SD card corruption is the real enemy sync shutdown -h now
fi
# Mount root filesystem as read-only
# Add 'ro' to your /etc/fstab root entry, then:
-weight: 600;">sudo mount -o remount,ro / # Use tmpfs for anything that needs writes
tmpfs /var/log tmpfs defaults,noatime,nosuid,size=5m 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=5m 0 0
# Mount root filesystem as read-only
# Add 'ro' to your /etc/fstab root entry, then:
-weight: 600;">sudo mount -o remount,ro / # Use tmpfs for anything that needs writes
tmpfs /var/log tmpfs defaults,noatime,nosuid,size=5m 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=5m 0 0
# Mount root filesystem as read-only
# Add 'ro' to your /etc/fstab root entry, then:
-weight: 600;">sudo mount -o remount,ro / # Use tmpfs for anything that needs writes
tmpfs /var/log tmpfs defaults,noatime,nosuid,size=5m 0 0
tmpfs /tmp tmpfs defaults,noatime,nosuid,size=5m 0 0 - Cloudflare Tunnel (formerly Argo Tunnel) — the cloudflared daemon is lightweight and gives you HTTPS for free. Memory cost is around 10-15MB though, which is significant at this scale.
- WireGuard to a cheap VPS that reverse-proxies to your Pi. WireGuard's kernel module uses almost no userspace memory.
- Yggdrasil or Tailscale for overlay networking if you're okay with non-traditional access. - Use overlayfs or a read-only root. I cannot stress this enough. SD card corruption will ruin your weekend.
- Monitor with free -h obsessively during testing. Memory leaks that are invisible on a 16GB laptop will crash your server in hours.
- Set up a watchdog timer. The Pi has a hardware watchdog — use it. If your server hangs, it auto-reboots.
- Test your shutdown script by actually yanking power. Simulate the worst case before the worst case finds you.
- Log to tmpfs, not the SD card. Rotate or discard logs on reboot. If you need persistent logs, write them to a USB stick.