Запускаем Linux в браузере. Часть 1

Как вам идея запустить настоящий Debian 11 в вашем браузере? Нет, не тонкий клиент на какой-то сервер, а целую операционную систему, которая работает оффлайн прямо у вас в браузере!

Часть 1: Предисловие

Я пишу курс по работе в терминалом и искал способы, как можно сделать этот курс интерактивным, чтобы читатель мог не меняя контекста сразу пробовать команды и получать ответ.

xTerm

Первым в поиске мне попался xterm - JS пакет, который “рисует” привычную оболочку на HTML и CSS. Выглядит очень достойно и на нём можно симулятор эмулятора терминала, который бы выдавал заранее заготовленные ответы на введённые команды. Но это скучно и не интересно.

В примерах использования был ttyd - утилита командной строки, которая демонстрирует возможность подключения xterm к работающему серверу. Уже интереснее.

У меня есть VPS, можно развернуть там виртуалку (для пущей безопасности), а внутри запускать по docker-контейнеру под каждого читателя… Дороговато. Может быть один на всех “гостей”, а для зарегистрированных пользователей отдельную среду? Нужно было бы сделать систему распределения ресурсов… Но сколько таких контейнеров выдержит моя VPS’ка? Наверно на 10 уже начнёт загибаться. Сложно, дорого и нежизнеспособно, ищем дальше.

WASM

Как уважающий себя инженер я оставил проблему мариноваться на неопределённый срок.

Третьего дня я, как обычно, сёрфил ютубчик и решил посмотреть выступление про перспективы Web Assembly.

Рассказывать что такое WASM выходит за рамки этой статьи, но если вкратце: код на языках высокого уровня (C, C++, Rust и даже PHP) можно скомпилировать в web assembly, что позволит запустить его внутри современных браузеров.

Очень меня впечатлил и вдохновил этот доклад и я вспомнил про свою проблему. Запуск кода на C в браузере? Linux написан на C? Что если скомпилировать Linux в WASM?

Естественно, если бы я поискал готовые решения по запросу linux wasm, я бы сразу нашел, например, webvm, но вместо этого я начал искать самый маленький вариант ядра Linux на котором можно поэкспериментировать. Ядро бы я наверно не скомпилировал в WASM, но я вспомнил про другой мини-linux.

Что у нас используется, когда нужен очень маленький linux? Конечно, Busybox - набор всеми нами любимых утилит типа cat, ls, vi, скомпилированных в один файл, который весит меньше мегабайта. Отличный кандидат!

По запросу busybox webasm первый результат вёл на ишью, буквально, с заголовком Crazy idea: compile busybox to WebAssembly, boot a Linux VM to it, где в ответ выдали ссылку на…

JSLinux

Как обычно, я только задумываюсь о чём-то, а гиганты мысли уже давным-давно развивают эту идею на практике.

Итак, JSLinux - эмулятор Linux, основанный на TinyEMU, скомпилированном в WASM, который позволяет запускать различные x86 системы, в том числе и linux.

Вот вам полноразмерный Alpine Linux в браузере с интернетом через вебсокеты и виртуальной сетевой файловой системой. Звучит! То что нужно? Почти.

Я придираюсь, но для меня было пару нюансов. Оболочка терминала под этот эмулятор была самописная, хоть и отлично выполненная, но не xterm. Не очень много документации: сам JSLinux было очень просто накатить и поиграться, но как мне его менять? И как собирать свои образы? В общем, вариант, но ищем ещё варианты. Благо, внизу страницы были ссылки на другие эмуляторы.

v86

Например, v86. Он эмулирует ЦПУ (на уровне 3 пентиума) и железо в браузере, а все софтовые вызовы на лету компилирует в WASM. Пушка-гонка. Проект живее всех живых, документация побогаче, есть пример как собрать образ Debian! Плюс, показывают в базовой сборке как подцепить xterm.

Наш вариант!

Btw в примерах есть Arch linux, хоть по умолчанию и без сети.

В следующей серии

Будем собирать и запускать образ Debian 11 под v86. Спойлер - самый маленький образ у меня получился 350 метров + 150 метров созранённого контекста для моментального запуска. Под уроки терминала тяжеловато, но поиграться с этим было очень интересно!