Ubuntu Weekly Recipe

第925回UbuntuでセルフホストFaaS「Orva」使ってみよう

AWS LambdaやCloudflare WorkersのようなFaaS(Functions as a Service)を使うと、サーバーそのものを構築することなく、ちょっとしたプログラムを「関数」として実行できます。たとえば「HTTPリクエストを受け取ったら処理を行い、結果をJSONで返したい」⁠定期的にAPIを呼び出して、その結果を保存したい」といった処理のためだけに、Webサーバーを1台用意するのは少々大げさですし、面倒くさいでしょう。FaaSではこうした処理を関数単位でデプロイし、必要なときだけ実行できます。

ただしAWS Lambdaのようなサービスは、当然ながらクラウド上で動作します。⁠同じようなものを自宅サーバーや社内サーバーで動かせたら便利なのに」と思うこともあるでしょう。そこで今回は、セルフホスト可能なFaaSであるOrvaをUbuntu上で動かしてみます。

Orvaとは

Orvaは、セルフホストできるオープンソースのFaaSです。⁠自宅に置けるAWS Lambda+API Gateway」のようなものだと考えるとわかりやすいでしょう。開発元はOrvaを「ホームラボやオンプレミス向けの、セルフホスト可能なFaaS」と説明しており、自宅サーバー、VPS、ベアメタルサーバーなどでの利用を想定しています。Python、JavaScript、TypeScriptに対応しており、デプロイされた関数はnsjailを利用したサンドボックス内で実行されます。またHTTP経由で呼び出せるエンドポイントを自動的に用意してくれるため、Webブラウザやcurlから関数を実行できます。

Orvaを使うメリット

単純にPythonのスクリプトを実行するだけなら、Ubuntu上で以下のようにコマンドを叩けば済む話です。

$ python3 script.py

しかし外部システムと連携し、HTTP経由でAPIからそのスクリプトを呼び出したいのであれば話が変わります。専用のHTTPサーバーを用意したり、Dockerfileを書いてコンテナをビルドしたり、場合によってはリバースプロキシも用意したくなるでしょう。ほんの数十行のスクリプトを動かしたいだけなのに、その周囲に必要なインフラのほうが大げさになってしまいます。

ですがOrvaを使えば、Webブラウザから実行したいコードを関数として登録するだけです。そのスクリプトのためだけにインフラを用意する必要がなくなる上、Orvaはその関数を呼び出すためのHTTPエンドポイントまで用意してくれます。さらにOrvaには、関数ごとのKVストア、cronによるスケジュール実行、Orva内での関数同士の呼び出し、実行履歴やトレーシング、コーディングとデプロイをサポートするAIアシスタントといった機能も組み込まれています。HTTPから呼び出したい簡単なスクリプトの集積場所として、非常に便利なプロダクトだと言えるでしょう。

ただし注意点もあります。Orvaは2026年に登場したばかりの非常に新しいプロジェクトです。そのため公式にも、現時点ではホームラボやサイドプロジェクト、社内向けツールなどでの利用を想定し、顧客向けの本番サービスにはまだ推奨しないと明記されています。そのためまずは、自宅サーバーなどで試してみるのがよいでしょう。

Orvaのインストール

Orvaも今時のアプリの例に漏れず、Docker Composeで動かすのが簡単です。あらかじめ以下のコマンドで、DockerとComposeをインストールしておいてください。

$ sudo apt install -U -y docker.io docker-compose-v2
$ mkdir ~/orva
$ cd ~/orva

続いてcompose.yamlを以下の内容で作成してください。

services:
  orva:
    image: ghcr.io/harsh-2002/orva:latest
    container_name: orva
    restart: unless-stopped

    ports:
      - 8443:8443

    cgroup: host
    pid: host

    cap_add:
      - SYS_ADMIN

    security_opt:
      - seccomp=unconfined
      - apparmor=unconfined
      - systempaths=unconfined

    devices:
      - /dev/net/tun:/dev/net/tun

    volumes:
      - ./orva-data:/var/lib/orva
      - /sys/fs/cgroup:/sys/fs/cgroup:rw

    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8443/api/v1/system/health"]
      interval: 30s
      timeout: 5s
      start_period: 15s
      retries: 3

前述の通り、Orvaはnsjailを使って関数を隔離実行します。コンテナの中でさらにサンドボックスを作る必要があるため、通常のWebアプリケーションと比較して、かなり強い権限を要求します。上記のcompose.yamlを見るとわかりますが、一般的なコンテナとは大きく異なる設定となっています。特にSYS_ADMINケイパビリティや、ホストのPID/cgroupへのアクセスが必要となる点は注意してください。そのため共用環境などで実行することは避け、Orva専用の仮想マシンを用意することをお勧めします。

compose.yamlを作成できたら、次のように起動します。

$ sudo docker compose up -d

Webブラウザから、⁠http://サーバーのIPアドレス:8443/」にアクセスしてください。初回アクセス時には管理者アカウントを作成するためのオンボーディング画面が表示されます。なお8443番という番号からHTTPSを想像するかもしれませんが、標準構成ではHTTPです。

図1 初回アクセス時の画面

ユーザー名とパスワードを設定すると、Orvaのダッシュボードが表示されます。

図2 Orvaのダッシュボード

関数の作成とデプロイ

それでは実際に関数を作ってみましょう。今回は、実行環境のシステム情報をJSONで返す簡単なPythonスクリプトを作成します。まず左ペインにある「Functions」をクリックしてください。関数の一覧画面が表示されます。最初の関数を作成するため、右上にある「New Function」をクリックします。

図3 新しい関数を作成する

関数の作成画面に遷移します。左上に表示されているのが関数名です。ランダムな名前がつけられますので、わかりやすい名前に変えておきましょう。ここでは「system-info」としました。テキスト編集エリアに、デフォルトのエントリーポイントであるhandler.pyが入力されています。これを以下のコードに書き換えてください。

import os
import platform

def handler(event): 
    return {
        "hostname": platform.node(),
        "system": platform.system(),
        "release": platform.release(),
        "machine": platform.machine(),
        "python": platform.python_version(),
        "cpus": os.cpu_count(),
    }
図4 関数名を設定し、コードを記述する

ランタイムにはPythonを選択してください。デフォルトでPythonが選択されているはずですが、Node.jsと切り替えたい場合は「config⁠⁠→⁠settings」から行えます。

図5 ランタイムを切り替える

ここまでの入力が完了したら、関数をデプロイします。右上にある「Deploy」をクリックしてください。

図6 デプロイが完了した状態。関数一覧にsystem-info関数が登録されている

デプロイした関数を実行してみましょう。Functionsの画面から、system-info関数の編集アイコンをクリックして、編集画面に遷移します。ここでウィンドウ下部にある「Run」をクリックしてください。関数が実行され、その結果が表示されます。

図7 system-info関数を実行した例。RESPONSEに実行結果のJSONが表示されている

なお繰り返しになりますが、Orvaの関数はnsjailによって隔離された環境内で実行されます。そのためこのsystem-info関数が表示しているのは、Orvaを動かしているUbuntuホストやOrvaコンテナの情報ではなく、Orvaによって作成されたサンドボックス環境の情報になります。この例は実際のホスト情報を調べるのが目的ではなく、あくまでOrvaの関数がどのように動作しているかを確認するサンプルであることをご了承ください。

APIから関数を呼び出す

Orvaが単なるスクリプト置き場と管理UIではなく、FaaSであることをもっとも実感できるのが、作成した関数をHTTPから直接呼び出せる点です。Orvaではそれぞれの関数にUUIDが自動的に割り当てられ、⁠http://OrvaのIPアドレス:8443/fn/関数のUUID」というURLで関数を呼び出せます。たとえば筆者の環境で、先ほど作成したsystem-info関数のUUIDは「01a04b0f-cc3a-7ac3-a71e-0e2b9c8f2554」でした。そのためこの関数は「http://OrvaのIPアドレス:8443/fn/01a04b0f-cc3a-7ac3-a71e-0e2b9c8f2554」というURLで呼び出せるのです。以下は試しにcurlから実行してみた例です。

図8 curlから作成した関数を呼び出してみた例。レスポンスがJSONのため、jqにパイプして見やすく整形している

これで、HTTPリクエストを受けてJSONを返すサービスが完成しました。見ての通りOrva上にPythonのコードをデプロイしたのみで、nginxもApache HTTP ServerもFlaskも必要ありません。もちろんOrvaの裏側にはHTTPサーバーやサンドボックスが存在します。ですがこれらはOrva側がまとめて用意してくれるため、利用者は実行したい関数のみを意識すればよいのです。これはまさに、AWS LambdaをはじめとするFaaSが便利な理由そのものです。

関数に任意のパスを割り当てる

UUIDはお世辞にも、人間にとって使いやすい形式ではありません。UUIDのままでは、関数のURLを覚えることは難しいでしょう。そこでOrvaには自動で割り当てられるUUID以外に、任意のURLを関数へ割り当てる機能が用意されています。例として先ほどのsystem-info関数に、⁠/system-info」というURLを対応させてみましょう。

関数の編集画面に入ったら、右上の「Config⁠⁠→⁠Settings」を開きます。表示されるダイアログを下までスクロールすると、⁠CUSTOM ROUTES」という項目があります。ここに「/system-info」と入力して「add」をクリックします。

図9 関数に割り当てるURLを入力する
図10 URLが割り当てられた状態

カスタムルートの追加が完了したら「Done」をクリックします。これで「http://OrvaのIPアドレス:8443/system-info」で先ほどと同じ関数をコールできるようになりました。

図11 カスタムルートで関数を呼び出す例

圧倒的にわかりやすいため、よく使う関数にはカスタムルートを設定することをお勧めします。

AIを使ったコーディング

最近は、簡単なスクリプトなどはAIに作らせてしまうのも一般的になりました。Orvaもその例に漏れず、AIアシスタント機能が搭載されています。OrvaにOpenAIやAnthropicなどのLLMを接続し、ダッシュボードから自然言語でOrvaを操作できます。AIからOrvaの機能を操作できるようになっており、関数の作成やデプロイ、実行、ログの確認、シークレットの管理なども、AIに任せることが可能です。OrvaはこのためのMCPサーバーも内蔵しています。ここでは例として、OpenAIを利用して関数の実装とデプロイを行ってみましょう。なお本手順を実行するには、あらかじめOpenAI PlatformからAPIキーを発行しておいてください[1]

まず左ペインから「Settings」を開き、⁠AI assistant」の欄の「Add provider」をクリックします。するとAIプロバイダを追加する項目欄が開くので、⁠PROVIDER」「openai」にした上で、⁠API KEY」にAPIキーを入力してください。⁠Save provider」をクリックすると、OpenAIがAIプロバイダーとして登録されます。

図12 OpenAIをAPプロバイダーとして登録する

左ペインから「Chat」をクリックしてください。AIとのチャットインターフェイスが開きます。プロンプト入力エリアの下側をクリックすると、使用するモデルを選択できます。

図13 モデルを選択する

ChatGPTなどとチャットする感覚で、挨拶を返す関数を実装するよう指示してみました。するとAIがOrvaの機能を呼び出し、実際に関数の作成を開始します。ただし関数を作成したりコードをデプロイしたりといった「書き込み」を伴う操作については、実行前にApproveを求められます。ここでは「create_function」が実行され、⁠こういう仕様で関数を作ってよいか」についてApproveを求められています。確認の上、特に問題がなさそうでしたら「Approve」をクリックします。

図14 実装して欲しい関数をAIに指示してみた

続いて「deploy_function_inline」が実行されます。⁠code」内が、実際に実行されるコードになります。確認の上、問題がなさそうであれば「Approve」をクリックしてください。関数のデプロイが行われます。

図15 コードレビューをした上で、AIが作った関数をデプロイする

デプロイが完了すると、AIがその旨のメッセージを返します。実際に関数を実行したレスポンスも表示されますので、確認しておきましょう。

図16 デプロイが完了した

デプロイした関数は、先ほどと同じようにHTTPから呼び出せます。

図17 curlから関数を呼び出した例。きちんとランダムな挨拶が返されていることがわかる

「AIにコードを書かせる」だけであれば、現在ではさほど珍しくないでしょう。しかしOrvaではAIがコードを書くだけでなく、そのコードを実行する環境そのものまで操作できるところが面白いポイントです。⁠こんなAPIが欲しい」と指示するだけで、関数を作り、デプロイし、HTTPから利用できるところまで持っていけるわけです。しかもユーザーはLLMのAPIキーを指定するだけでよく、エージェントのセットアップが不要な点も魅力です。

もちろん、AIが生成したコードを無条件に信用するのは危険です。特にネットワークアクセスやシークレットを利用する関数を作成する場合は、生成されたコードとAIが実行しようとしている操作を、きちんとコードレビューしてからApproveするようにしましょう。


Webサービスを作るほどでもないものの、⁠Webhookを受け取って処理したい」⁠JSONを返す小さなAPIが欲しい」⁠定期的にスクリプトを実行したい」といった要望は、自宅サーバーや社内環境でも意外と多いものです。とはいえそのためだけにDockerコンテナを作ったり、Webサーバーをデプロイするのは面倒でしょう。ですがOrvaという「関数を置く場所」をひとつ用意すれば、必要になった処理を関数単位で追加していけます。しかも各関数はHTTPエンドポイントを持てるため、自宅ネットワーク内から簡単に利用できる、疎結合なサービスを手軽に実装できるのです。

Orvaはまだ非常に新しいプロジェクトであり、本番用途に使うかどうかは、慎重に判断する必要があるでしょう。とはいえ「この処理のためだけにコンテナを1個作るのは面倒だな」と感じる場面では非常に有用な、なかなか興味深いソフトウェアだと言えそうです。

おすすめ記事

記事・ニュース一覧