Firecracker で任意のコマンドを実行できる API を実装してみた

Firecracker は AWS Lambda や AWS Fargate でも使われている OSS の仮想化技術です。

先日 Twitter にこの Firecracker を使って、AI エージェントの動作基盤を開発しているスライドが流れてきました。

これを見て大学生の頃に任意コマンドを実行できる Slack Bot を作って、大学のサークルの Slack に放流していたことを思い出しました。

speakerdeck.com

きっと同じものをまた作れるのでは?と思い、実装してみました。

github.com

PoC というか hobby use 用のコードです。

動作

例えば以下のような Python コードを用意して

print("Hello World! from Python")


def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)


print(fib(10))

curlAPI を叩くと実行結果が返ってきます。

$ curl -X POST http://localhost:3000/run -H 'Content-Type: multipart/form-data' -F file=@./examples/example.py -F 'payload={"environmentName": "python"};type=application/json'
{"stdout":"Hello World! from Python\n55\n","stderr":""}

仕組み

KVM + Firecracker で立てた microVM の中で任意のコマンドを実行してその結果を返しています。

  1. API サーバ: ユーザーのコードを受け付ける
  2. API サーバ: python -c 形式のコマンドに変換
  3. API サーバ: Firecracker の管理を行うプロセスに microVM の起動を依頼
  4. Firecracker Manager: microVM を起動して、VM 内と通信ができる UNIX ドメインソケットを返す
  5. API サーバ: VM 内のプロセスに対してコマンドを送信
  6. VM 内のプロセス: コマンドを実行して結果を返す

という流れになっています。

今回はただ動くものを実装するのが目的だったので、全部を Node.js で実装してます。多分ちゃんと運用するなら VM 内のプロセスは、シングルバイナリにできる Go とかで書いたほうがいい気がします。

Tips

実装する中で気づいた知見について紹介します。

.ext4 ファイルは Docker イメージから生成できる

microVM のディスクファイルとして、.ext4 ファイルを用意する必要があります。

docker export を使うとコンテナのファイルシステムを書き出すことができるので、これを使うのが楽でした。各言語のセットアップなどは有名な Docker イメージを利用できるのが便利です。

github.com

ゲストのプロセスとの通信は vsock 経由で行う

vsock は VM とホストマシンが通信するためのアドレスファミリーです。Firecracker 独自の仕組みではなくて、VM 全般で利用される仕組みのようです。

ただ自分はこのことを知らなかったので、以下のドキュメントで初めて知りました。

github.com

ホスト側はソケットが生えるだけなので、便利な仕組みだなと思いました。

microVM 内でループバックアドレスを up する必要がある

Node.js は vsock をネイティブにサポートしていません。

なので今回は socat を使って、vsock を TCP に proxy することにしました。

具体的には microVM の起動時に以下のコマンドも実行しています。

$ socat VSOCK-LISTEN:8000,fork TCP:127.0.0.1:8080

こうすれば 8080 ポートで HTTP サーバを立てるだけで済むので実装の難易度が下がります。

ただ初期状態の microVM ではループバックアドレスが down していたので、以下のエラーが発生しました。

# 2025/11/25 15:34:53 socat[248] W connect(5, AF=2 127.0.0.1:8080, 16): Network is unreachable
2025/11/25 15:34:53 socat[248] E TCP:127.0.0.1:8080: Network is unreachable

これを解決するために、起動時に ip link set lo up も実行してます。

余談

実装にあたって仮想化や Linux 周りの知識が不足していたのを ChatGPT にかなり助けてもらいました。昔だったらもっと時間がかかっていた気がします。

これを本番環境で稼働させるための調査や追加の実装はさらに時間が必要になると考えてます。

さっと動くものは簡単に作れるけど、ちゃんと動くものまでの距離は依然遠いままだな〜と感じました。

JSConf JP 2025 に参加してきました

JSConf JP 2025 に参加してきました。 jsconf.jp

所属のLINEヤフー株式会社がカンファレンスのスポンサーをしていたため、スポンサーチケットがあったのでこちらを使っての参加でした。

jsconf.jp

以下印象に残ったセッションなどを書いていきます。

What's New in ECMA-402

jsconf.jp

ECMA-402 はあまり馴染みのない言葉でしたが、i18n のための API に関する標準仕様のことでした。

i18n に関する仕様や実装は階層構造になっていることを示したスライドが一番強く記憶に残っています (セッションでは i18n stack と呼ばれていた)。
普段利用している i18n のライブラリは最上位に位置していて、下層の仕組みを正しく理解すると i18n 関係の実装を行うときにより手札が増えて良さそうだなと思いました。

From Chaos to Harmony: A History of JavaScript(混沌から調和へ ― JavaScriptの歴史)

jsconf.jp

キーノートでしたが、一番面白かったセッションでした。

自分がフロントエンドに入門した頃は ES6 が登場しつつあり、babel?というやつを使うと ES5 になっていろんなブラウザで動かせて便利!という世界観のタイミングでした。
ES5 以前の ES4 は提案だけされたもののまとまらなかった話は、聞いたことがない話だったので大変面白かったです。先人たちの議論や試行錯誤の上に今日の JavaScript や Web が存在すると考えると感慨深いです。

ちなみにこのセッションで初めて JavaScript と同い年なことを知りました。

サイボウズブース

ブースに行くとマネジメントの話ができるとのことだったので、30分ぐらいおぐえもんさんと会話させていただきました。なかなかこういう機会はないので貴重でした。

大規模プロダクトで実践するAI活用の仕組みづくり

jsconf.jp

個人で AI は活用できるけどチーム単位で活用できているか?という課題感を持っていたので、ここに刺さる実践的なセッションでした。

やっぱもっと AI を活用していきたいよね〜という気持ちになりました。

Media Capture and Streams: W3C仕様と現場での知見

jsconf.jp

仕事で MediaStream を使った Webアプリをメンテナンスしているので、なんとなく使い方や API は知っていました。しかしフルスクラッチでその Web アプリを書き上げたわけではないので、全体像については曖昧な状態でした。

このセッションでは実際に MediaStream を使う中でハマった事例が複数紹介されていました。そのため次にコードを書くときに自分の中で気をつけるべきポイントを増やすことができて有意義なセッションだと感じました。

MediaStream を始めとしたネイティブの機能が絡む Web API は、簡単でもいいので実際に Web アプリを開発して自分の手で触らないと正しい使い方がわからないので難しい、とも感じました。

大規模モノレポの秩序管理 失速しない多言語化フロントエンドの運用

jsconf.jp

仕事でコンポーネントライブラリに含まれる以下のようなパッケージを

  • 1つの i18n 用のパッケージ
    • i18n 用のインタフェース (t(key) みたいなやつ)
    • 他のパッケージで使うための i18n リソース

以下のように整理したことがありました

  • i18n 用のインタフェースは廃止
    • Web アプリ側で導入されている i18next や vue-i18n などを使ってもらう
    • i18n のリソースは、それぞれのパッケージから直接提供

なので発表の内容にはとても共感ができました。

GraphQL の例が紹介されていましたが、データに対する操作とそのデータ自体は分けるほうがきれいに整理ができるパターンだと感じました

終わりに

今年の JSConf JP も楽しく参加できました。

スポンサーセッションでは実務に寄った話が多くこれはこれで参考になりますし、他のセッションでは JavaScript 自体の話や規格の話もあったので、バランスが良かったなと感じました。

運営の方々や登壇された方、ありがとうございました。来年も開催されれば参加したいと思いました。

line-developers-mcp-server を開発したときの気付き

LINE Developers を検索してくれるMCPサーバを少し前に開発したときに気付いたことを残しておきます。

github.com

開発途中の作業ログは Zenn に置いています。 zenn.dev

ドキュメント検索系のMCPサーバは検索の品質が本質になる

結局はMCPサーバは単なるプロトコルです。なのでプロトコルの中で高品質な機能を提供する必要があります。

今回開発したドキュメント検索系のMCPサーバは、LLMとのやり取り部分のプロトコルが決まっているRAGといえます。なのでより便利なツールにするには検索部分の品質を高める必要があります。

line-developers-mcp-serverではサイトに実装されている検索機能をPlaywrightを使うことで検索を実現しています。
この検索機能は改善の余地があります。例えば LINE Login 概要 ではなく LINEログインの概要 で検索しないと LINEログインの概要 | LINE Developers がヒットしない点です。ドキュメントがヒットしないのでLLMが何度か検索ワードを変えて検索している場面が何度かありました。

単語の表記揺れに設定を入れたり、ベクトル検索を導入するなどの改善点が考えられます。

ドキュメント検索に特化したMCPサーバのOSSが出てきそう

VitePressMarkdownファイルから人間の向けのドキュメントサイトを構築するOSSです。
これと同じ構図で、Markdownファイルから検索エンジン付きのMCPサーバを構築するOSSが出てきそうな気がしていました。

自分の観測範囲では実際にそれ用のVite Pluginが公開されていました。

qiita.com

あとは https://gitmcp.ioリポジトリ上にMarkdownファイルがあるなら同じような使い方ができると思います。

Webに公開されているドキュメントならGooglesite:検索を使うほうがお手軽かもしれない

https://developers.line.biz/ja/ はWebに公開されているドキュメントです。

なので site: https://developers.line.biz/ja/ ${検索ワード}Googleで検索すれば精度高く関連ドキュメントを見つけることができます。この方法だと LINEログインLINE Login の表記揺れなどにも強いです。

一番の理想はGoogle自身が site: 検索をするMCPサーバを提供してくれることです。しかしこれは検索結果画面の広告で収益を得ていることを考えると実現する可能性は低いと考えています。Playwrightで検索する方法も考えられますが、Googleの利益に相反することなのでいつまで利用可能かわかりません。

2024年 ふりかえり

去年のやつ

odan3240.hatenablog.com

OSS 関係

今年は https://oss.odan.dev/ を作ったので、ここから振り返ることができます。

印象深いやつをいくつかピックアップします。

happy-dom

仕事でエッジケースなテストを書いていて、その中で happy-dom にフィードバックできそうな挙動があったので issue を立ててプルリクまで作る、ということをしていました。
happy-dom はレスポンスが早いしすぐリリースもされるので、この部分の開発者体験は良かったです。

github.com

github.com

nivo

副業先で nivo のバージョンを上げると Next.js 上で build エラーになっていて困っているという話がありました。これを解決するタスクが自分にアサインされたのがきっかけです。
最初は workaround をいくつか試していましたが、やっているうちに「なんで世界中の開発者がこんな作業を強いられているんだろう...??」という気持ちになってしまいました。nivo が正しく ESM 対応すれば何も困らない話なので、方針を相談して nivo 自体を修正することにしました。

まだプルリクはマージされていませんが、来年にはマージされることを祈っています。

github.com

Open Collective

去年に続いて ESLint、typescript-eslint、Prettier、core-js に毎月10ドルずつ寄付しています。

opencollective.com

来年はもう1つか2つぐらい寄付先を増やしたいなと考えています。

仕事

本務

チームごと別部署に移動したりして色々ありましたが、去年と変わらず LIFF やLINEログインなどの開発者向けのプロダクト開発に関わっています。

そんな中で今年はインターンを受け入れました。これまでインターンを受け入れたことがなかったので、準備や期間中の対応など慣れない部分が多かった記憶があります。

当初予定していた開発が無事完了しただけでなく、ポッドキャストへの出演やインターンレポートの執筆までできたのはかなり良かったなと考えています。

techblog.lycorp.co.jp

uit-inside.linecorp.com

兼務

また春から別のチームに兼務がつきました。

兼務先では機会に恵まれて、技術カンファレンスに関する仕事をしています。

techblog.lycorp.co.jp

techblog.lycorp.co.jp

来年以降も技術カンファレンスのスポンサーや社内向けの支援を継続していければなと考えています。

副業

去年から続いて同じところで副業を続けています。

本業が開発者向けのプロダクトなため、なかなか王道なフロントエンドのコードを書く機会が少ないです。そんな中で今年も副業先でモダンフロントエンドなプロジェクトに関わることができました。ここでの経験値や気付きは本業にも活かせている感覚があります。

登壇

TSKaigi 2024 と Vue Fes Japan 2024 と JSConf JP 2024 にプロポーザルを出して、Vue Fes Japan 2024 に LT で登壇することができました。

odan3240.hatenablog.com

odan3240.hatenablog.com

兼務先で技術カンファレンスのスポンサー関係の業務に関わっているので、来年はより強く登壇を狙っていきたいと考えています。

まとめ

今年は新しく技術カンファレンス関係の仕事に関わるようになったのがアップデートでした。

OSS への関わり方や仕事の内容には満足しているので、このまま継続して来年も動き続けたいと考えています。

Vue Fes Japan 2024 に参加してきました

タイトルの通り Vue Fes Japan 2024 に参加してきました

vuefes.jp

今回はLTのスピーカー参加でした

vuefes.jp

以下はスライドです。

speakerdeck.com

LT を出した背景

今年はカンファレンスへの登壇をできたらいいなと考えていて、TSKaigi や JSConf JP に CfP を出していました。

ただ春先に TSKaigi はセッションの CfP を出して落選していたので、競争率が低いであろう LT の CfP を出す戦略に切り替えていました。

odan3240.hatenablog.com

LT のネタをどうするかは少し悩みました。なぜなら普段仕事では Vue.js を書く機会はあるものの、頻度も量も多くはないため CfP として書けるほどのネタを持ち合わせていなかったからです。
唯一ネタになりそうな今年の年始に行った Vue2 => Vue3 のマイグレーションは、昨年末で Vue2 は EOL になったので旬が過ぎている気がして諦めました。1

公式サイトの CfP の募集要項をよく読むと Vite や unjs 関係のパッケージやコミュニティに関するトークでも OK と書いていました。そのため当時 Vitest Browser Mode についてサーベイしていたのもあって、このネタで LT に応募しました。

カンファレンスの感想

昨年の会場よりも広く気になるセッションが満席で中に入れない、ということがなく快適でした。

また、Evan をはじめとする Vue.js や Vite や unjs のコミッターが実際に日本に来て会えるのはいい機会だと思いました。実際に懇親会で pi0 と少し話すことに成功しました。

LT はほどよく緊張感を持って挑めたので、個人的にはうまく発表できた気がしています。テスト戦略の Testing Trophy や Vitest Browser Mode に関する知識を聞いている方に持ち帰ってもらえるといいなと考えていました。LT の中で「これらのことを知っている人〜?」問いかけたところ、大体半分の人が手を挙げていました。なのでレベル感としても程よかったのかなと感じています。

自分の LT の順番待ちやスポンサーブース巡りの影響で、昼過ぎのセッションをあまり聞けなかったのが少し心残りでした。カンファレンスの時間配分は難しいですね。

来年の意気込み

今年は縁があり LT で登壇することができました。ただ当日の参加者の熱量的に通常のトークでの登壇のほうが注目度は高いので、来年はトークでの登壇を目指したいです。そのために CfP は複数出して当選率を上げる戦略が大事なのかなと思いました。

あと海外の方も参加されるカンファレンスなので資料は英語で作ったほうが良かった、と資料が完成してから後悔しました。特にトークだと海外の方が来る可能性が高まるので、来年はなおさら英語での準備をしたいと考えています。

そのためにも来年までに Vite や unjs 周りについて見識を深めて、可能ならコントリビュートしていこうかなと考えています。

終わりに

楽しいカンファレンスでした。スタッフ及びスポンサーの方々、ありがとうございました!


  1. ただ今回の会場で聞いた話だと Vue2 のまま Never-Ending Support を受けている企業がいくつかありました

TSKaigi 2024にプロポーザルを提出して落ちてました

tskaigi.org

TSKaigi 2024のトーク枠のセッションにプロポーザルを提出してましたが、今日当落発表があり落ちていました。

落ちてしまったので、ここにプロポーザルの内容を公開して供養します。

プロポーザルの内容

背景

ECMAScript の Decorator は長い標準化の道のりの末、2022年3月に Stage 3 に昇格しまし、この進展を受けて TypeScript 5.0 ではこの仕様が実装されました。 更に、Decorator をさらに強化する Decorator Metadata も2023年6月に Stage 3 に昇格して、TypeScript 5.2 で実装されました。 Decorator Metadata は Lit などの Decorator を活用するライブラリに必要な仕様です。Lit の ES Decorator 対応は Decorator Metadata が Stage 3 に昇格するのを待ってから、2023年10月に対応版の Lit 3.0 がリリースされました。

問題提起

しかし、ECMAScript の Decorator が TypeScript の tsc に実装されたことで、すべての TypeScript ユーザーが直ちにこれらの機能を利用できるようになったわけではありません。現在、babel、esbuild、swc など複数の TypeScript 処理系が存在し、これらのツール全てが新しい Decorator 仕様をサポートしているわけではないため、追加の設定なしに利用することができません。

本発表の目的

トークでは、まず TypeScript の各処理系における Decorator と Decorator Metadata のサポート状況を解説します。次になぜ処理系によっては Decorator の実装が進んでいないかを解説します。そして ECMAScript の Decorator を今すぐにでも利用したい開発者のための具体的な workaround を紹介します。

反省

TypeScript の Decorator に関する発表だけだとアピールする文章になっているのが良くないかなと提出後に思いました。この話の面白さは「現代の TypeScript は新しい構文が tsc に実装されても他の処理系でも実装されていなければ実際には使えない」というギャップの部分だと思っています。なのでこれを主題にして Decorator はその話を裏付ける一例として使うほうが、Decorator に興味がない層にもリーチができるのでもっと良いプロポーザルにできたのかなと反省してました。

今後

最近は大きめなイベントが復活しているので、またプロポーザルを出して登壇のチャンスを掴みたいです。そのためにも今後も継続的に知識を学習していつでもプロポーザルを出せる状態を維持していけたらなと考えてます。

2023年 ふりかえり

去年のやつ

odan3240.hatenablog.com

OSS 関係

作ったプルリク

https://github.com/issues?q=author%3Aodanado+archived%3Afalse+-user%3Aodanado+-user%3Aodan-sandbox を眺めて思い出深いやつをピックアップ

yhatt/jsx-slack

今年の2月頃は Slack Bot を作成する機会がありました。その中で色々なライブラリを試しているときに TypeScript の moduleResolution が node16 の場合にエラーになることを見つけたので、修正するパッチを作成しました。

github.com

nodejs/docker-node

普段から Node.js を使っているけど nodejs の org にコントリビュートしたことがないことに気付いたので、何か自分でもできそうな issue がないか探しました。その中でも docker-node リポジトリは Node.js 自体の知識が不要で Docker の知識があれば自分にも対応できる issue がありだと考えました。探したところ、GitHub Actions に関する help wanted な issue があったので、これに挑戦しました。

レビューが爆速で返ってきて感心した記憶があります。

github.com

Open Collective

今年から普段使用している OSS に寄付することを意識しました。

opencollective.com

ESLint、typescript-eslint、Prettier、core-js に毎月10ドルずつ寄付しています。

また cpprefjp に50ドルの投げ銭を6月に行いました。

仕事

転職して丸1年が過ぎました。

仕事での目に見えるアウトプットとしては UIT Meetup の幹事の担当やアドベントカレンダーに参加しました。

engineering.linecorp.com

techblog.lycorp.co.jp

会社にもだいぶ慣れてきたのもあってプロジェクトの状況や会社での立ち位置を把握して、自分の興味のある範囲とやる必要があることを認識して仕事を進められるようになってきました。

副業

今年は知り合い経由で色々副業に挑戦しました。

Testing Library など触ったことのないライブラリを触りつつ開発ができてて楽しいです。

ただ副業をすると趣味や OSS へのコントリビュートする時間が減るのが悩みのタネでもあるなと感じた一年でした。

まとめ

転職して仕事にも慣れてきた1年でした。

ただアウトプットの数は減ってしまったので、来年は仕事で成果出しつつその結果をアウトプットに繋げられたらな〜と考えてます。