Γιατί Droidian;
Τα περισσότερα Android τηλέφωνα που κυκλοφόρησαν μεταξύ 2018 και 2022 θεωρούνται πλέον ξεπερασμένα ως smartphones, όμως ως μικροί ARM servers παραμένουν εξαιρετικά ενδιαφέρουσες συσκευές.
Το Droidian φέρνει ένα πλήρες περιβάλλον Debian πάνω από το Android kernel και το Halium compatibility layer. Αυτό σημαίνει ότι ένα παλιό τηλέφωνο μπορεί να τρέξει σχεδόν το ίδιο λογισμικό που θα έτρεχε ένας κανονικός Linux server:
- Tailscale
- Vaultwarden
- Jellyfin
- Navidrome
- Samba
- Syncthing
- PhotoPrism
- …
- οποιαδήποτε ARM64 Debian υπηρεσία
Το πιο ενδιαφέρον όμως είναι το κόστος.
Ένα μεταχειρισμένο συμβατό Droidian τηλέφωνο βρίσκεται συνήθως:
| Συσκευή | Τιμή |
|---|---|
| Google Pixel 3a | 30-50€ |
| Google Pixel 4a | 50-90€ |
| Xiaomi Redmi Note 9S | 40-70€ |
| Poco X3 NFC | 60-100€ |
Αντίστοιχα ένα Raspberry Pi σήμερα συχνά κοστίζει:
| Hardware | Τιμή |
|---|---|
| Raspberry Pi 4 4GB | 70-100€ |
| Raspberry Pi 5 4GB | 90-130€ |
| Τροφοδοτικό | +10€ |
| Κάρτα SD ή SSD | +10-30€ |
| Κουτί | +5-20€ |
Το τηλέφωνο έχει ήδη:
- μπαταρία UPS
- Wi-Fi
- Bluetooth
- eMMC/UFS storage
- οθόνη για troubleshooting
- USB-C
- ιδιαίτερα χαμηλή κατανάλωση
Στην πράξη, ένα Pixel 3a ή ένα Redmi Note 9S μπορεί να λειτουργήσει ως ARM64 home server καταναλώνοντας περίπου 2-4W, τιμή συγκρίσιμη ή και χαμηλότερη από πολλά SBCs.
Το μεγαλύτερο εμπόδιο είναι ότι το Droidian εξακολουθεί να συμπεριφέρεται σαν κινητό τηλέφωνο. Υπηρεσίες όπως το Phosh, το ModemManager και οι Android μηχανισμοί εξοικονόμησης ενέργειας συνεχίζουν να προσπαθούν να βάλουν τη συσκευή σε sleep.
Για έναν server αυτό είναι ανεπιθύμητο.
Στόχος μας είναι:
- σταθερό uptime
- μόνιμη δικτυακή σύνδεση
- απενεργοποίηση του γραφικού περιβάλλοντος
- ελαχιστοποίηση κατανάλωσης RAM
- αποφυγή deep sleep
Ο οδηγός αυτός περιγράφει πώς μετατρέπω το Redmi Note 9S μου σε πλήρως headless, always-on server με εντυπωσιακό uptime .
- Προϋποθέσεις
Πριν ξεκινήσεις:
- Bootloader ξεκλειδωμένος (OEM unlock enabled)
- adb + fastboot εγκατεστημένα
- USB debugging ενεργό
- battery > 60%
- γνωστό target build για τη συσκευή σου (Droidian port συγκεκριμένου device)
Downgrade σε συγκεκριμένη έκδοση android για τη συσκευή σου πάνω στην οποία είναι χτισμένο το hallium boot .
⸻
Γιατί αυτό το βήμα είναι κρίσιμο
Το Droidian δεν είναι “app install”. Είναι full system replacement layer.
Σε αντίθεση με:
- Raspberry Pi images
- standard Debian installs
εδώ έχουμε:
- Android kernel (device-specific)
- vendor blobs (GPU, modem, DSP)
- Halium abstraction layer
- rootfs που πρέπει να “κουμπώσει” πάνω στο hardware stack
Αν γίνει λάθος εδώ:
-
δεν υπάρχει boot
-
δεν υπάρχει recovery UI
-
χρειάζεται reflash από fastboot ή EDL (Qualcomm)
Εντολές:
adb devices
adb reboot bootloader
fastboot devices
fastboot flash boot boot.img
fastboot flash dtbo dtbo.img
fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img
fastboot flash userdata userdata.img
fastboot format:ext4 userdata
fastboot reboot system
Το droidian έρχεται πακεταρισμένο σε zip με έτοιμο script που εγκαθιστά τα image από fastboot και φάκελο ο οποίος περιέχει τα images .
Αν επιλέξεις τη μέθοδο του fastboot καλύτερα εγκατέστησε χειροκίνητα τα αρχεία γιατί κάποιες συσκευές απαιτούν disable verity ή set enforce 0 (απενεργοποίηση shelinux policy)
Τα zip είναι διαθεσιμα εδω
Αν δεν θες να μπλέξεις με terminal υπάρχει installer αρχικά για Ubuntu touch ομως Πλέον διαθέτει και στις συσκευές droidian και είναι διαθέσιμος εδω
Τα release χωρίζονται σε snapshot και nighty
Τα snapshot δεν έχουν embed στο rootfs τα devtool τα οποίος θα χρειαστείς αν θες ssh over usb
- Προετοιμασία
Πριν ξεκινήσετε βεβαιωθείτε ότι έχετε:
- λειτουργικό SSH
- πρόσβαση στο τοπικό δίκτυο
- γνωστή IP της συσκευής
Η διαδικασία μετατρέπει πρακτικά το τηλέφωνο σε headless server.
- Απενεργοποίηση υπηρεσιών τηλεφωνίας και αχρησιμοποίητου hardware
sudo systemctl disable --now ModemManager
sudo systemctl disable --now ofono
Έλεγχος GPS:
gsettings get org.gnome.system.location enabled
Απενεργοποίηση:
gsettings set org.gnome.system.location enabled false
Αυτές οι υπηρεσίες διαχειρίζονται SIM, δίκτυο κινητής και τηλεφωνία.
Σε ένα headless server:
δεν χρειάζονται
καταναλώνουν RAM και CPU cycles
δημιουργούν background wakeups στο modem stack
Ρίσκο
Κανένα, εκτός αν χρησιμοποιείται SIM για data.
- Ρύθμιση Swappiness
Έλεγχος:
cat /proc/sys/vm/swappiness
Ορισμός σε 10:
sudo sh -c 'echo "vm.swappiness=10" >> /etc/sysctl.conf'
sudo sysctl -p
Αυτό μειώνει τη χρήση swap και προτεραιοποιηση τη χρήση της πιο γρήγορης ram.
Το Android-derived kernel συχνά προσπαθεί να αποφύγει RAM pressure μέσω aggressive swapping.
Σε flash storage (eMMC/UFS):
- το swap είναι αργό
- αυξάνει write wear
- δημιουργεί latency spikes
- Απενεργοποίηση Sleep States
sudo systemctl mask sleep.target
sudo systemctl mask suspend.target
sudo systemctl mask hibernate.target
sudo systemctl mask hybrid-sleep.target
Το systemd προσπαθεί να διαχειριστεί power states σαν laptop/phone OS.
- suspend = downtime
- deep sleep = network drop
- broken SSH sessions
Ρίσκο
Αυξάνει κατανάλωση μπαταρίας αν δεν υπάρχει τροφοδοσία.
- Ρύθμιση logind
Επεξεργασία:
sudo nano /etc/systemd/logind.conf
Προσθέστε:
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore
IdleAction=ignore
Εφαρμογή:
sudo systemctl restart systemd-logind
Απενεργοποιεί lid/idle based sleep logic.
- Απενεργοποίηση Wi-Fi Power Saving
Δημιουργία αρχείου:
sudo tee /etc/NetworkManager/conf.d/99-wifi-powersave.conf >/dev/null <<'EOF'
[connection]
wifi.powersave=2
EOF
Επανεκκίνηση:
sudo systemctl restart NetworkManager
Έλεγχος:
iw dev wlan0 get power_save
Wi-Fi chipset προσπαθεί να:
- μπαίνει σε low-power states
- μειώνει beacon listening
Αυτό προκαλεί:
- packet loss
- SSH lag spikes
- random disconnects σε long uptime servers
- Headless Server Mode
Αντί να κάνουμε mask το Phosh από την αρχή, προτιμάμε μια πιο ασφαλή προσέγγιση.
Αυτό δίνει ένα παράθυρο ανάκτησης σε περίπτωση που η ρύθμιση παραμέτρων Wi-Fi διακοπεί ή το SSH δεν είναι διαθέσιμο.
Η συσκευή εκκινεί κανονικά.
Αφού σταθεροποιηθεί το δίκτυο, το γραφικό περιβάλλον τερματίζεται αυτόματα.
Δημιουργούμε:
sudo nano /etc/systemd/system/server-mode.service
Προσθέτουμε:
[Unit]
Description=Server Mode
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/systemd-inhibit \
--what=sleep:idle \
--mode=block \
--why="server mode active" \
/usr/local/bin/server-mode.sh
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
Δημιουργούμε:
sudo nano /usr/local/bin/server-mode.sh
Προσθέτουμε:
#!/bin/sh
sleep 10
/usr/sbin/iw dev wlan0 set power_save off 2>/dev/null || true
echo on > /sys/class/net/wlan0/device/power/control 2>/dev/null || true
STABLE=0
for i in $(seq 1 60); do
ping -c1 1.1.1.1 >/dev/null 2>&1 && STABLE=$((STABLE+1)) || STABLE=0
[ "$STABLE" -ge 15 ] && break
sleep 2
done
sleep 120
systemctl stop phosh.service || true
echo 0 > /sys/class/backlight/panel0-backlight/brightness 2>/dev/null || true
while true; do
sleep 3600
done
Δικαιώματα:
sudo chmod +x /usr/local/bin/server-mode.sh
Ενεργοποίηση:
sudo systemctl daemon-reload
sudo systemctl enable --now server-mode.service
Τι κάνει
- περιμένει να σταθεροποιηθεί network
- απενεργοποιεί Phosh
- μειώνει power state του display
- κρατά το system alive μέσω loop
Γιατί γίνεται
Το πιο σημαντικό architectural κομμάτι:
Το Droidian δεν είναι headless OS. Άρα:
- το GUI είναι system-critical dependency
- το shutdown του UI πρέπει να γίνει late, όχι early
Αυτό αποτρέπει lockouts.
- Καθαρισμός GNOME Power Management
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing'
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'
gsettings set org.gnome.desktop.session idle-delay 0
Τι κάνει
Απενεργοποιεί idle timers και power plugins.
Γιατί γίνεται
GNOME services:
- κάνουν periodic wakeups
- ελέγχουν inactivity
- ενεργοποιούν screen blanking logic
- Στατική IP
Παράδειγμα:
sudo -i
nmcli connection modify "vippo_EXT" \
ipv4.method manual \
ipv4.addresses 192.168.1.198/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "1.1.1.1,8.8.8.8"
nmcli connection modify "vippo_EXT" \
802-11-wireless.cloned-mac-address permanent
nmcli connection down "vippo_EXT"
nmcli connection up "vippo_EXT"
exit
Τι κάνει
Ορίζει fixed IP στο NetworkManager.
Γιατί γίνεται
Servers πρέπει να είναι:
- predictable
- reachable
- Απενεργοποίηση USB Autosuspend
Εντοπισμός συσκευής:
lsusb
Παράδειγμα:
ID 0480:0900 Toshiba America Inc MQ04UBF100
Δημιουργία κανόνα:
sudo nano /etc/udev/rules.d/99-usb-autosuspend.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0480", ATTR{idProduct}=="0900", ATTR{power/control}="on"
Εφαρμογή:
sudo udevadm control --reload-rules
sudo udevadm trigger
Γιατί γίνεται
Linux kernel προσπαθεί να κάνει autosuspend USB devices για power saving.
Σε external HDD:
- προκαλεί disconnects
- filesystem corruption risk
- random I/O stalls
- CPU Governor
Απενεργοποίηση power profiles:
sudo systemctl disable --now power-profiles-daemon
Δημιουργία υπηρεσίας:
sudo nano /etc/systemd/system/cpufreq-schedutil.service
Προσθέτουμε:
[Unit]
Description=Force CPU governor to schedutil
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'for p in /sys/devices/system/cpu/cpufreq/policy*/scaling_governor; do echo schedutil > "$p"; done'
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Ενεργοποίηση:
sudo systemctl daemon-reload
sudo systemctl enable cpufreq-schedutil.service
Τι κάνει
Ορίζει schedutil ως default governor.
Γιατί γίνεται
Android kernels συχνά fallback σε:
- powersave
- interactive profiles
Αποτέλεσμα:
- throttling
- unpredictable latency
- broken server responsiveness
schedutil = πιο balanced kernel scheduler-driven scaling.
- Περιορισμός RAM Υπηρεσιών
Παράδειγμα για Jellyfin:
sudo systemctl edit jellyfin
[Service]
MemoryMax=600M
MemoryHigh=500M
CPUWeight=50
IOWeight=50
Γιατί γίνεται
Σε low-RAM devices ένα service μπορεί να:
- καταναλώσει όλη τη RAM
- προκαλέσει OOM kill cascade
Αυτό απομονώνει workloads.
- Έλεγχος Ρυθμίσεων
systemctl list-unit-files | grep -E "sleep|suspend|hibernate" && \
loginctl show-logind -p IdleAction -p HandleLidSwitch && \
systemd-inhibit --list && \
sudo iw dev wlan0 get power_save
- Κατάσταση Συστήματος
Πληροφορίες μπαταρίας:
upower -i $(upower -e | grep 'battery')
Χρήση RAM:
ps -eo size,pid,user,command --sort -size | \
awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' | head -n 12
15. Droidian Suspend
Η παραδοσιακή αναστολή λειτουργίας (suspend) είναι ουσιαστικά σπασμένη στους περισσότερους Android kernels. Για τον λόγο αυτό το Droidian χρησιμοποιούσε παλαιότερα το batman, το οποίο πλέον έχει καταργηθεί και αντικατασταθεί από το Mobile Power Saver (MPS), το οποίο είναι ενεργό από προεπιλογή.
Το κλασικό suspend συχνά ξυπνά τη συσκευή ανά τακτά χρονικά διαστήματα χωρίς να επιτυγχάνει πραγματική αναστολή λειτουργίας. Η συμπεριφορά αυτή μπορεί να απενεργοποιηθεί με overrides τόσο στο GNOME Power όσο και στο Mobile Power Saver.
Η απενεργοποίηση δεν δημιουργεί πρόβλημα λειτουργίας, καθώς το batman ήταν ιστορικά ο βασικός daemon διαχείρισης ενέργειας στο Droidian και πλέον θεωρείται deprecated.
Override για το GNOME Power
Το παρακάτω override λέει στο gnome-settings-daemon να μην επιχειρεί ποτέ αναστολή λειτουργίας λόγω αδράνειας, είτε η συσκευή λειτουργεί με ρεύμα είτε με μπαταρία.
[org.gnome.settings-daemon.plugins.power]
sleep-inactive-ac-type='nothing'
sleep-inactive-battery-type='nothing'
Overrides για το Mobile Power Saver (MPS)
Το Mobile Power Saver χρησιμοποιεί GLib schemas και overrides για τη διαχείριση εξοικονόμησης ενέργειας.
Βήμα 1: Μετονομασία του override ώστε να φορτώνεται τελευταίο
Τα αρχεία override εφαρμόζονται αλφαριθμητικά. Δίνοντας μεγαλύτερο αριθμό εξασφαλίζουμε ότι οι δικές μας ρυθμίσεις υπερισχύουν.
sudo mv \
/usr/share/glib-2.0/schemas/90-org.adishatz.Mps.homelab.override \
/usr/share/glib-2.0/schemas/99-homelab.gschema.override
Βήμα 2: Δημιουργία του override
Το παρακάτω αρχείο απενεργοποιεί όλες τις λειτουργίες power saving που θα μπορούσαν να επηρεάσουν υπηρεσίες ή δικτυακή συνδεσιμότητα.
sudo tee /usr/share/glib-2.0/schemas/99-homelab.gschema.override > /dev/null <<'EOF'
[org.adishatz.Mps]
suspend-services=false
suspend-processes=[]
screen-off-power-saving=false
radio-power-saving=false
bluetooth-power-saving=false
EOF
Βήμα 3: Επαναμεταγλώττιση των schemas
Μετά από κάθε αλλαγή σε override αρχείο απαιτείται επαναμεταγλώττιση των GLib schemas.
sudo glib-compile-schemas /usr/share/glib-2.0/schemas/
Βήμα 4: Επαναφορά των ρυθμίσεων χρήστη
Αν υπάρχουν ήδη αποθηκευμένες τιμές στο dconf, θα υπερισχύσουν των νέων defaults. Η επαναφορά επιτρέπει τη φόρτωση των νέων τιμών.
gsettings reset-recursively org.adishatz.Mps
Τι σημαίνουν τα 5 κλειδιά
suspend-services=false
Αποτρέπει το MPS από το να σταματά user services όταν σβήσει η οθόνη.
Παραδείγματα:
- SSH
- Nextcloud
- Syncthing
- WebDAV
- PhotoPrism
Οι υπηρεσίες συνεχίζουν να λειτουργούν κανονικά στο παρασκήνιο.
suspend-processes=[]
Κενή λίστα σημαίνει ότι το MPS δεν παγώνει καμία διεργασία με SIGSTOP.
Οι εφαρμογές παραμένουν ενεργές στη RAM και συνεχίζουν να εκτελούνται κανονικά.
screen-off-power-saving=false
Απενεργοποιεί το λεγόμενο screen-off suspend.
Σε αρκετούς Android kernels η λειτουργία αυτή δεν οδηγεί σε πραγματικό suspend αλλά προκαλεί συνεχείς αφυπνίσεις της συσκευής.
Με την επιλογή αυτή η συσκευή παραμένει σε απλό idle state.
radio-power-saving=false
Διατηρεί το Wi-Fi και τα δεδομένα κινητής τηλεφωνίας σε πλήρη λειτουργία όταν σβήσει η οθόνη.
Χρήσιμο για:
- SSH
- WebDAV
- Tailscale
- Syncthing
- Nextcloud
Οι συνδέσεις παραμένουν άμεσα διαθέσιμες.
bluetooth-power-saving=false
Αποτρέπει την ενεργοποίηση power saving στο Bluetooth όταν η οθόνη είναι κλειστή.
Χρήσιμο για:
- Bluetooth πληκτρολόγια
- Bluetooth ποντίκια
- Ακουστικά
- BLE συσκευές
Έλεγχος ρυθμίσεων
Επιβεβαίωσε ότι οι τιμές έχουν φορτωθεί:
gsettings list-recursively org.adishatz.Mps | \
grep -E 'suspend-services|suspend-processes|screen-off'
Επαναφορά και επανέλεγχος
Αν θέλεις να επιβεβαιώσεις ότι τα defaults προέρχονται από το override:
gsettings reset-recursively org.adishatz.Mps
gsettings get org.adishatz.Mps suspend-services
Αναμενόμενο αποτέλεσμα:
false
Τελικός έλεγχος
Κάνε επανεκκίνηση του Mobile Power Saver και παρακολούθησε τα logs:
systemctl --user restart mobile-power-saver
journalctl --user -u mobile-power-saver -f
Αν δεν εμφανίζονται μηνύματα για αναστολή υπηρεσιών ή διεργασιών, τότε το override εφαρμόστηκε επιτυχώς.Αποτελέσματα
Στο Redmi Note 9S που χρησιμοποιώ ως server:
- Κατανάλωση περίπου 2-4 Watt
- Περίπου 900 MB RAM σε idle
- Uptime πολλών εβδομάδων
- Tailscale
- Vaultwarden
- Jellyfin
- μικρές Go υπηρεσίες
- εξωτερικός USB δίσκος μέσω OTG
Ένα σημαντικό μέρος της RAM εξακολουθεί να δεσμεύεται από το Halium και διάφορα Android services όπως netmgrd, qcrild και qseecomd. Παρότι καταναλώνουν περίπου 150-250 MB μνήμης, η απενεργοποίησή τους μπορεί να προκαλέσει αστάθεια ή ακόμη και αδυναμία εκκίνησης της συσκευής.
Για τον λόγο αυτό συνιστάται να παραμείνουν ενεργά.
Παρά τους περιορισμούς αυτούς, ένα Droidian τηλέφωνο μπορεί να αποτελέσει μια εξαιρετικά οικονομική, αθόρυβη και ενεργειακά αποδοτική πλατφόρμα self-hosting, αξιοποιώντας συσκευές που διαφορετικά θα κατέληγαν σε κάποιο συρτάρι.