From 0b09eab4f26d3fdb4f210156640be6e8dfcc238f Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Sat, 21 Jun 2025 10:14:31 +0200 Subject: initial commit --- Makefile | 12 ++ build.sh | 235 +++++++++++++++++++++++++++ favicon.png | Bin 0 -> 601 bytes feed.xml | 37 +++++ genrss.sh | 50 ++++++ index.html | 47 ++++++ meta.sh | 6 + readme.md | 15 ++ this-server/a_web_server_on_a_solar_phone.md | 55 +++++++ this-server/index.html | 48 ++++++ this-server/meta.sh | 6 + this-server/server.jpeg | Bin 0 -> 64598 bytes 12 files changed, 511 insertions(+) create mode 100644 Makefile create mode 100755 build.sh create mode 100644 favicon.png create mode 100644 feed.xml create mode 100755 genrss.sh create mode 100644 index.html create mode 100644 meta.sh create mode 100644 readme.md create mode 100644 this-server/a_web_server_on_a_solar_phone.md create mode 100644 this-server/index.html create mode 100644 this-server/meta.sh create mode 100644 this-server/server.jpeg diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4041406 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +# Generate the static web site from markdown files. +build: + ./build.sh + ./genrss.sh > feed.xml + +# Launch a local web server. +server: + yaegi -e 'http.ListenAndServe(":8080", http.FileServer(http.Dir(".")))' + +# Publish on github pages. +publish: + git push diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..166eeba --- /dev/null +++ b/build.sh @@ -0,0 +1,235 @@ +#!/bin/sh + +header=' + + +' + +md2html() { +# Usage: +# md2html file.md > file.html +# Options: -v esc=false to not escape html +awk ' + function newblock(nblock) { + if (text) + print "<" block ">" text "" + text = "" + block = nblock ? nblock : "p" + } + + function subinline(tgl, inl) { + while (match($0, tgl)){ + if (inline[ni] == inl) + ni -= sub(tgl, "") + else if (sub(tgl, "<" inl ">")) + inline[++ni] = inl + } + } + + function dolink(href, lnk) { + # Undo escaped html in uris + gsub(/&/, "\\&", href) + gsub(/</, "<", href) + gsub(/>/, ">", href) + # & can be tricky, and not standard: + gsub(/&/, "\\\\\\&", href) + gsub(/&/, "\\\\\\&", lnk) + return "" lnk "" + } + + BEGIN { + ni = 0; # inlines + nl = 0; # nested lists + text = "" + block = "p" + } + + # Escape html + esc != "false" { + gsub("&", "\\&") + gsub("<", "\\<") + gsub(">", "\\>") + } + + # Horizontal rules (_ is not in markdown) + /^[ ]*([-*_] ?)+[ ]*$/ && text == "" { + print "
" + next + } + + # Tables (not in markdown) + # Syntax: + # Right Align| Center Align |Left Align + /([ ]\|)|(\|[ ])/ { + if (block != "table") + newblock("table") + nc = split($0, cells, "|") + $0 = "\n" + for (i = 1; i <= nc; i++){ + align = "left" + if (sub(/^[ ]+/, "", cells[i])){ + if (sub(/[ ]+$/, "", cells[i])) + align = "center" + else + align = "right" + } + sub(/[ ]+$/,"", cells[i]) + $0 = $0 "" cells[i] "\n" + } + $0 = $0 "" + } + + # Ordered and unordered (possibly nested) lists + /^[ ]*([*+-]|(([0-9]+[\.-]?)+))[ ]/ { + newblock("li") + nnl = 1 + while (match($0, /^[ ]/)){ + sub(/^[ ]/,"") + nnl++ + } + while (nl > nnl) + print "" + while (nl < nnl){ + list[++nl] = "ol" + if (match($0, /^[*+-]/)) + list[nl] = "ul" + print "<" list[nl] ">" + } + sub(/^([*+-]|(([0-9]+[\.-]?)+))[ ]/,"") + } + + # Multi line list items + block == "li" { + sub(/^( *)|( *)/,"") + } + + # Code blocks + /^( | )/ { + if (block != "code") + newblock("code") + sub(/^( | )/, "") + text = text $0 "\n" + next + } + + # Paragraphs + /^$/ { + newblock() + while (nl > 0) + print "" + } + + # Headers + /^#/ { + newblock() + match($0, /#+/) + n = RLENGTH + if (n > 6) + n = 6 + text = substr($0, RLENGTH + 1) + block = "h" n + next + } + + # Alternate headers (underlined) + /^=+$/ { + block = "h" 1 + next + } + + /^-+$/ { + block = "h" 2 + next + } + + { + # Images + while (match($0, /!\[[^\]]+\]\([^\)]+\)/)){ + split(substr($0, RSTART, RLENGTH), a, /(!\[)|\)|(\]\()/) + sub(/!\[[^\]]+\]\([^\)]+\)/, "\""") + } + # Links + while (match($0, /\[[^\]]+\]\([^\)]+\)/)){ + split(substr($0, RSTART, RLENGTH), a, /[\[\)]|(\]\()/) + sub(/\[[^\]]+\]\([^\)]+\)/, dolink(a[3], a[2])) + } + # Auto links (uri matching is poor) + na = split($0, a, /(^\()|[ ]|([,\.\)]([ ]|$))/) + for (i = 1; i <= na; i++) + if (match(a[i], /^(((https?|ftp|file|news|irc):\/\/)|(mailto:)).+$/)) + sub(a[i], dolink(a[i], a[i])) + # Inline + subinline("(\\*\\*)|(__)", "strong") + subinline("\\*", "em") + subinline("`", "code") + text = text (text ? " " : "") $0 + } + + END { + while (ni > 0) + text = text "" + newblock() + while (nl > 0) + print "" + }' "$1" +} + +genhtml() ( + cd "$1" || return + + . ./meta.sh + + exec 1>index.html + + # Header + echo "" + echo "" + echo "" + echo "$title" + [ "$description" ] && echo "" + echo "$header" + [ "$1" != . ] && echo "$blog_title
" + + # Body + # pandoc *.md + for f in *.md; do + [ -f "$f" ] && md2html "$f" + done + + # Footer + [ "$1" != . ] && echo "
From: $author, $date" +) + +for d in *; do + [ -d "$d" ] && genhtml "$d" +done +genhtml . + +# Fix for mastodon. +sed '/mstdn/s/href=/rel="me" href=/' index.html >xx && mv xx index.html +# Put a license in index footer. +echo '
' >>index.html diff --git a/favicon.png b/favicon.png new file mode 100644 index 0000000..d7cb86d Binary files /dev/null and b/favicon.png differ diff --git a/feed.xml b/feed.xml new file mode 100644 index 0000000..f973500 --- /dev/null +++ b/feed.xml @@ -0,0 +1,37 @@ + + + +Marc's Notes +https://dot.vertes.org/ +An experimental website on a solar phone +marc@vertes.org (Marc Vertes) +Fri, 20 Jun 2025 16:58:13 +0200 + +https://dot.vertes.org/this-server/ +A web server on a solar phone +https://dot.vertes.org/this-server/ +Hosting a web server on a solar powered phone +marc@vertes.org (Marc Vertes) +Fri, 20 June 2025 12:00:00 +0200 + + A web server on a solar phone +

I have this old low-cost phone which was the first one offered to my kid when he was 15 (he is now 21), before he moved to a more fashionable model. I noticed that without a SIM card, only on WIFI, the phone needed to be recharged not after 1 or 2 days, but only after 2 weeks! So this small device, plugged to a small solar panel, could be the perfect always-on personal web server. The site that you are browsing right now is hosted on it.

+

The server with its solar panel, and a cat

+

Hardware

+

The phone is an entry-level Motorola G7 Play, purchased in 2019 for 120€ or so, worth nothing today. It was used by my son for less than 2 years, then dormant since. The display is slighly shattered, but it doesn't matter, as I use it headless.

+

I bought a small solar panel on Amazon, 10W produced by 2 plates of 17x17 cm. Cost: 28€. I could probably get something less expensive.

+

And that's it. The solar panel is just suspended vertically at a south window. The phone sits below, connected to the panel by a USB cable, in the shadow (do not put the phone directly under the sun, or closed without fresh air).

+

Software

+

The single purpose of this device is now to run a small standalone static web server. By using termux on top of Android, I can run a ssh server for remote access and Nginx, an efficient web server. I do not need to root the phone, as port redirection from my internet router compensate for the restriction of not using a port number below 1024.

+

Nevertheless, I installed LineageOS on the phone, as it supports my model and keeps the system updated. I could have kept the stock android image, at the expanse of a less secure system. I could have gone further and install PostmarketOS on it, to have a full unrestricted Linux machine, but I was both lazy and curious to see what I could get from just Android.

+

I then installed F-Droid, only to install Termux from it. Do not install Termux from the Google Play Store, it is too limited. The version from F-Droid is fine.

+

The phone connects to my internet box via WIFI and my internet service provider allows me to have a static IP4 address at no additional cost.

+

The last part is to configure the SSL certificate. I used Acme.sh, downloaded directly from Github.

+

Operation

+

It's too early to say. Lets see how it goes over time (a few months), and if a relatively old phone can find a second life and be used as an autonomous web server, running solely on free photons and electrons.

+

But for now, we are in june and the battery level is almost always at 100%.

+
From: Marc Vertes, 20 june 2025]]> +
+
+
+
diff --git a/genrss.sh b/genrss.sh new file mode 100755 index 0000000..f92c1ac --- /dev/null +++ b/genrss.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +fixhtml() { + gawk ' + # Skip everything before first

. + /

+ + + $title + $link/ + $description + $email ($author) + $(date -R) +EOT + +for d in *; do + [ -d "$d" ] || continue + cd $d + . ./meta.sh + cat <<- EOT + + $link/$d/ + $title + $link/$d/ + $description + $email ($author) + $date_rfc2822 + + + + + EOT +done + +cat <<- EOT + + +EOT diff --git a/index.html b/index.html new file mode 100644 index 0000000..7029132 --- /dev/null +++ b/index.html @@ -0,0 +1,47 @@ + + + +Marc's Notes + + + + + +

Marc's Notes

+

A blog about programming and other stories.

+

Posts

+ +

A web server on an old smartphone, solar powered.

+

Contact

+ +
diff --git a/meta.sh b/meta.sh new file mode 100644 index 0000000..e6d75fe --- /dev/null +++ b/meta.sh @@ -0,0 +1,6 @@ +title="Marc's Notes" +author="Marc Vertes" +email="marc@vertes.org" +description="An experimental website on a solar phone" +link="https://dot.vertes.org" +date="20 th of June 2025" diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..81a4acf --- /dev/null +++ b/readme.md @@ -0,0 +1,15 @@ +# Marc's Notes + +A blog about programming and other stories. + +## Posts + +- [About this server](this-server) june 2025 + + A web server on an old smartphone, solar powered. + +## Contact + +* Email: marc@vertes.org +* Github: [@mvertes](https://github.com/mvertes) +* Mastodon: [@mvertes](https://mstdn.fr/@mvertes) diff --git a/this-server/a_web_server_on_a_solar_phone.md b/this-server/a_web_server_on_a_solar_phone.md new file mode 100644 index 0000000..ad2757b --- /dev/null +++ b/this-server/a_web_server_on_a_solar_phone.md @@ -0,0 +1,55 @@ +# A web server on a solar phone + +I have this old low-cost phone which was the first one offered to my kid when +he was 15 (he is now 21), before he moved to a more fashionable model. I +noticed that without a SIM card, only on WIFI, the phone needed to be recharged +not after 1 or 2 days, but only after 2 weeks! So this small device, plugged to +a small solar panel, could be the perfect always-on personal web server. The +site that you are browsing right now is hosted on it. + +![The server with its solar panel, and a cat](server.jpeg) + +## Hardware + +The phone is an entry-level Motorola G7 Play, purchased in 2019 for 120€ or so, +worth nothing today. It was used by my son for less than 2 years, then dormant +since. The display is slighly shattered, but it doesn't matter, as I use it +headless. + +I bought a small solar panel on Amazon, 10W produced by 2 plates of 17x17 cm. +Cost: 28€. I could probably get something less expensive. + +And that's it. The solar panel is just suspended vertically at a south window. +The phone sits below, connected to the panel by a USB cable, in the shadow +(do not put the phone directly under the sun, or closed without fresh air). + +## Software + +The single purpose of this device is now to run a small standalone static web +server. By using termux on top of Android, I can run a ssh server for remote +access and Nginx, an efficient web server. I do not need to root the phone, as +port redirection from my internet router compensate for the restriction of not +using a port number below 1024. + +Nevertheless, I installed LineageOS on the phone, as it supports my model and +keeps the system updated. I could have kept the stock android image, at the +expanse of a less secure system. I could have gone further and install PostmarketOS +on it, to have a full unrestricted Linux machine, but I was both lazy and curious +to see what I could get from just Android. + +I then installed F-Droid, only to install Termux from it. Do not install Termux +from the Google Play Store, it is too limited. The version from F-Droid is fine. + +The phone connects to my internet box via WIFI and my internet service provider +allows me to have a static IP4 address at no additional cost. + +The last part is to configure the SSL certificate. I used Acme.sh, +downloaded directly from Github. + +## Operation + +It's too early to say. Lets see how it goes over time (a few months), and if a +relatively old phone can find a second life and be used as an autonomous web +server, running solely on free photons and electrons. + +But for now, we are in june and the battery level is almost always at 100%. diff --git a/this-server/index.html b/this-server/index.html new file mode 100644 index 0000000..019b7db --- /dev/null +++ b/this-server/index.html @@ -0,0 +1,48 @@ + + + +A web server on a solar phone + + + + + +Marc's Notes
+

A web server on a solar phone

+

I have this old low-cost phone which was the first one offered to my kid when he was 15 (he is now 21), before he moved to a more fashionable model. I noticed that without a SIM card, only on WIFI, the phone needed to be recharged not after 1 or 2 days, but only after 2 weeks! So this small device, plugged to a small solar panel, could be the perfect always-on personal web server. The site that you are browsing right now is hosted on it.

+

The server with its solar panel, and a cat

+

Hardware

+

The phone is an entry-level Motorola G7 Play, purchased in 2019 for 120€ or so, worth nothing today. It was used by my son for less than 2 years, then dormant since. The display is slighly shattered, but it doesn't matter, as I use it headless.

+

I bought a small solar panel on Amazon, 10W produced by 2 plates of 17x17 cm. Cost: 28€. I could probably get something less expensive.

+

And that's it. The solar panel is just suspended vertically at a south window. The phone sits below, connected to the panel by a USB cable, in the shadow (do not put the phone directly under the sun, or closed without fresh air).

+

Software

+

The single purpose of this device is now to run a small standalone static web server. By using termux on top of Android, I can run a ssh server for remote access and Nginx, an efficient web server. I do not need to root the phone, as port redirection from my internet router compensate for the restriction of not using a port number below 1024.

+

Nevertheless, I installed LineageOS on the phone, as it supports my model and keeps the system updated. I could have kept the stock android image, at the expanse of a less secure system. I could have gone further and install PostmarketOS on it, to have a full unrestricted Linux machine, but I was both lazy and curious to see what I could get from just Android.

+

I then installed F-Droid, only to install Termux from it. Do not install Termux from the Google Play Store, it is too limited. The version from F-Droid is fine.

+

The phone connects to my internet box via WIFI and my internet service provider allows me to have a static IP4 address at no additional cost.

+

The last part is to configure the SSL certificate. I used Acme.sh, downloaded directly from Github.

+

Operation

+

It's too early to say. Lets see how it goes over time (a few months), and if a relatively old phone can find a second life and be used as an autonomous web server, running solely on free photons and electrons.

+

But for now, we are in june and the battery level is almost always at 100%.

+
From: Marc Vertes, 20 june 2025 diff --git a/this-server/meta.sh b/this-server/meta.sh new file mode 100644 index 0000000..60682cc --- /dev/null +++ b/this-server/meta.sh @@ -0,0 +1,6 @@ +blog_title="Marc's Notes" +title="A web server on a solar phone" +author="Marc Vertes" +description="Hosting a web server on a solar powered phone" +date="20 june 2025" +date_rfc2822="Fri, 20 June 2025 12:00:00 +0200" diff --git a/this-server/server.jpeg b/this-server/server.jpeg new file mode 100644 index 0000000..e1a1427 Binary files /dev/null and b/this-server/server.jpeg differ -- cgit v1.2.3