Server Web In 10 MB con BusyBox

2 Marzo 2025 di Daniele Frulla


Come sviluppatore mi chiedo perche’ la tecnologia e’ passata dall’usare qualche Mb di dati a qualche Tb di dati. I dati sono molti, ma spesso sono ridondanti.

La differenza la fa il software. Tanti piccoli aggiornamenti fanno diventare le applicazioni enormi, l’uso della grafica sempre piu’ spinto e controlli di sicurezza rendono le applicazioni davvero pesanti.

Se hai la necessita’ di creare un piccolo sito web anche non molto performante per uso casalingo in poco piu’ di 10 Mb lo puoi fare. Occorrono BusyBox e Docker.

Prima cosa da fare e’ installarsi Docker nel proprio sistema.

Il nostro web server e’ davvero semplice e permettera’ la visualizzazione di pagine web statiche.

Infatti con BusyBox hai a disposizione un server web Apache, con cui puoi scaricare pagine web, ma all’occorrenza potresti voler lanciare uno script che esegua qualche tuo comando shell.

Creare Il DockerFile

Il Dockerfile che crera’ il sito web e’ questo:

FROM busybox

COPY ./www /www

RUN chmod -R 755 /www && chmod +x /www/cgi-bin/*

EXPOSE 80

CMD [ "/bin/httpd","-f", "-p", "80", "-h", "/www", "-c", "/www/cgi-bin" ]

Il codice e’ semplice e di facile comprensione. Si copia il nostro sito web nel contentitore e si fa partire il servizio httpd sulla porta 80 con la cartella cgi-bin che contiene le nostre Content Gateway Interface.

Il Sito Web

Se il nostro sito web e’ solamente composto file html, allora le cgi non ci servono. Le cgi diventono indispensabile se nella risposta del web server devi inserire dei contenuti dinamici, o se devi gestire parametri.

Il nostro sito web mostra semplicemente ora e data locale.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Data e Ora Locale con Selettore Fuso Orario</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .container {
            text-align: center;
            background-color: #fff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1 {
            margin: 0;
            font-size: 6em;
            color: #333;
        }
        p {
            margin: 40px 0 0;
            font-size: 4.2em;
            color: #666;
        }
        select {
            margin-top: 20px;
            padding: 10px;
            font-size: 4.2em;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Data e Ora Locale</h1>
        <p id="localDateTime"></p>
        <select id="timezoneSelector">
            <option value="UTC">UTC</option>
            <option value="Europe/Rome">Europe/Rome</option>
            <option value="America/New_York">America/New_York</option>
            <option value="Asia/Tokyo">Asia/Tokyo</option>
            <!-- Aggiungi altri fusi orari secondo necessità -->
        </select>
    </div>
    <script>
        function updateDateTime() {
            const timezone = document.getElementById('timezoneSelector').value;
            const now = new Date().toLocaleString("en-US", {timeZone: timezone});
            document.getElementById('localDateTime').textContent = now;
        }

        document.getElementById('timezoneSelector').addEventListener('change', updateDateTime);

        updateDateTime();
        setInterval(updateDateTime, 1000);
    </script>
</body>
</html>

Aggiungiamo una CGI

Per la cronaca vediamo come aggiungere una CGI al codice che esegue un comando passato dal browser:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Data e Ora Locale con Selettore Fuso Orario</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        .container {
            text-align: center;
            background-color: #fff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
            width: 90%;
            max-width: 800px;
        }
        h1 {
            margin: 0;
            font-size: 3em;
            color: #333;
        }
        p {
            margin: 20px 0 0;
            font-size: 2em;
            color: #666;
        }
        select {
            margin-top: 20px;
            padding: 10px;
            font-size: 1.5em;
        }
        textarea {
            width: 100%;
            height: 150px;
            margin-bottom: 10px;
            font-size: 1.2em;
        }
        button {
            padding: 10px 20px;
            font-size: 1.2em;
        }
        pre {
            text-align: left;
            background-color: #eee;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
            font-size: 1.2em;
            max-height: 300px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Data e Ora Locale</h1>
        <p id="localDateTime"></p>
        <select id="timezoneSelector">
            <option value="UTC">UTC</option>
            <option value="Europe/Rome">Europe/Rome</option>
            <option value="America/New_York">America/New_York</option>
            <option value="Asia/Tokyo">Asia/Tokyo</option>
            <!-- Aggiungi altri fusi orari secondo necessità -->
        </select>
    </div>
    <div class="container">
        <h1>Shell Interattiva</h1>
        <textarea id="commandInput" placeholder="Inserisci un comando"></textarea>
        <button onclick="executeCommand()">Esegui</button>
        <pre id="output"></pre>
    </div>
    <script>
        function updateDateTime() {
            const timezone = document.getElementById('timezoneSelector').value;
            const now = new Date().toLocaleString("en-US", {timeZone: timezone});
            document.getElementById('localDateTime').textContent = now;
        }

        document.getElementById('timezoneSelector').addEventListener('change', updateDateTime);

        updateDateTime();
        setInterval(updateDateTime, 1000);
    </script>
    <script>
        function executeCommand() {
            const command = document.getElementById('commandInput').value;
            fetch('/cgi-bin/exec.cgi', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: `command=${encodeURIComponent(command)}`
            }).then(response => response.text())
              .then(output => document.getElementById('output').textContent = output);
        }
    </script>
</body>
</html>

Non dimentichiamoci del file exec.cgi:

#!/bin/sh

# Imposta l'intestazione del contenuto
echo "Content-Type: text/plain"
echo ""

# Funzione per decodificare URL
urldecode() {
    local url_encoded="${1//+/ }"
    printf '%b' "${url_encoded//%/\\x}"
}

# Leggi i dati inviati dal modulo
read -r input

# Estrai il comando dal parametro e decodifica l'URL
command=$(echo "$input" | sed 's/command=//')
decoded_command=$(urldecode "$command")

# Esegui il comando e cattura l'output
output=$(eval "$decoded_command" 2>&1)

# Stampa l'output
echo "$output"

Una volta che avrete costruito l’immagine container, notate le dimensioni della stessa con il comando docker images, veramente piccola. Se non sbaglio ve la siete cavata con appena 5MB!

Qui puoi trovare il codice sorgente di sito web min con 10MB.

Se sei interessato ad altri articoli condividi e chiedi, saro’ felice di aiutarti!

Related Posts


Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *


Copyright di Caterina Mezzapelle Part. I.V.A. 02413940814 - R.E.A. 191812