enebular の ZIP デプロイチュートリアルを、CLI でやってみる

enebular の公式チュートリアル「ZIPファイルのクラウド実行環境へのデプロイ」では、Python や Node.js のコードを ZIP デプロイする手順が紹介されています。普段はブラウザでファイル登録画面とクラウド実行環境画面を行き来して操作しますが、ちょっと手間です。

今回は、この公式チュートリアルと同じことを、新しくリリースされた enebular CLI を使ってやってみます。

エディタとターミナルだけで完結するので、修正 → デプロイのサイクルが速くなります。

この記事では、enebular CLI を使って Python アプリケーションの ZIP ファイルをクラウド実行環境にデプロイする最短手順をご紹介します。

今回やること

ローカル PC のターミナルから、以下の 2 コマンドを実行してデプロイします。

  1. enebular add file で ZIP ファイルを enebular に登録する
  2. enebular deploy cloud でクラウド実行環境にデプロイする

全体像は次のとおりです。

ローカル PC                    enebular
┌─────────────┐                ┌─────────────────────┐
│ app.zip     │                │ ファイルアセット    │
│             │ ─ add file ─→  │ (登録)              │
│             │                │                     │
│             │                │ ↓ deploy cloud      │
│             │                │                     │
│             │                │ クラウド実行環境    │
│             │                │ (実行)              │
└─────────────┘                └─────────────────────┘

事前準備

この記事の手順を試す前に、以下を準備してください。

  • ZIP デプロイ用のクラウド実行環境(Python 3.13 / ARM64)
  • Node.js 22 以上の環境

クラウド実行環境は、enebular のプロジェクト画面から事前に作成しておいてください。また、HTTP トリガーをクラウド実行環境の設定タブから有効にして、URLを入力しておいてください。

enebular CLI をインストールする

enebular CLI は npm で公開されています。Node.js 22 以上の環境で、以下のコマンドを実行してください。

npm install -g @uhuru/enebular-cli

インストールが完了すると、enebular コマンドが利用できるようになります。バージョンを確認してみましょう。

enebular version

バージョン番号が表示されれば、インストールは成功しています。

アクセスキーを作成する

enebular CLI を使うには、アクセスキーとシークレットキーが必要です。enebular のアカウント設定画面から作成できます。

  1. 画面右上のユーザーメニューから「アカウント設定」を開く
  2. 「アクセスキー / シークレットキー」の項目で、説明文を入力して「作成」をクリック
  3. 表示されたアクセスキーとシークレットキーをコピーしておく

シークレットキーは作成時にしか表示されません。コピーするか、CSV ファイルとしてダウンロードして保管してください。

認証情報を設定する

作成したアクセスキーを enebular CLI に渡す方法は、いくつかあります。ここでは代表的な 2 つを紹介します。

方法 1 :環境変数で設定する

一番手軽なのは、環境変数として設定する方法です。一時的に試す場合や、CI / CD で利用する場合に向いています。

macOS / Linux の場合:

export ENEBULAR_ACCESS_KEY=<アクセスキー>
export ENEBULAR_SECRET_KEY=<シークレットキー>

Windows (PowerShell) の場合:

$env:ENEBULAR_ACCESS_KEY="<アクセスキー>"
$env:ENEBULAR_SECRET_KEY="<シークレットキー>"

方法 2 :設定ファイルで管理する

複数のアクセスキーを使い分ける場合や、毎回設定する手間を省きたい場合は、設定ファイルを使う方法が便利です。

以下のパスに credentials というファイル名で配置します。

  • macOS / Linux :~/.enebular/credentials
  • Windows :C:\Users\<ユーザー名>\.enebular\credentials

ファイルの中身は、以下の形式で記述します。

[default]
access-key=<アクセスキー>
secret-key=<シークレットキー>

設定ができたら、認証情報の解決は次の順序で行われます。

  1. コマンド引数の --access-key / --secret-key
  2. --profile で指定したプロファイル
  3. 設定ファイルの default プロファイル
  4. 環境変数 ENEBULAR_ACCESS_KEY / ENEBULAR_SECRET_KEY

ZIP ファイルを用意する

それでは、デプロイする ZIP ファイルを用意します。今回は Python のシンプルなサンプルアプリを使います。

任意の作業ディレクトリを作成し、以下の内容で lambda_function.py を作成します。

import json
from datetime import datetime


def lambda_handler(event, context):
    response = {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json'
        },
        'body': json.dumps({
            'message': 'Hello from enebular CLI!',
            'timestamp': datetime.now().isoformat()
        })
    }

    return response

これを ZIP ファイルにまとめます。

macOS / Linux の場合:

zip python-app.zip lambda_function.py

Windows の場合は、lambda_function.py を右クリックして「送る」→「圧縮 (zip 形式) フォルダー」を選択し、python-app.zip という名前で保存します。

ZIP ファイルのルートに lambda_function.py が直接配置されている必要があります。親フォルダーを含めて圧縮すると、デプロイ後に動作しないので注意してください。

1 コマンド目:ZIP ファイルを登録する

ここからが本題です。まず、作成した ZIP ファイルを enebular に登録します。

enebular add file \
  --project-id <プロジェクトID> \
  --file ./python-app.zip \
  --deploy-type cloud \
  --handler lambda_function.lambda_handler \
  --name "python-hello" \
  --detail "Python Hello World"

各オプションの意味は以下のとおりです。

  • --project-id :登録先のプロジェクト ID
  • --file :アップロードする ZIP ファイルのパス
  • --deploy-type :デプロイ先の種別。今回はクラウド実行環境なので cloud
  • --handler :ハンドラー名。<ファイル名>.<関数名> の形式で、今回は lambda_functionlambda_handler
  • --name :アセット名。1 〜 30 文字の英数字
  • --detail :アセットの説明

実行すると、確認プロンプトが表示されたあと、登録処理が進みます。完了すると、登録されたアセットの ID が表示されます。この ID は次のコマンドで使うので、メモしておいてください。

プロジェクト ID は、enebular の画面でプロジェクトの左側の設定メニューから確認できます。

2 コマンド目:クラウド実行環境にデプロイする

次に、登録したファイルをクラウド実行環境にデプロイします。

enebular deploy cloud \
  --project-id <プロジェクトID> \
  --cloud-id <クラウド実行環境ID> \
  --asset-id <先ほど登録したアセットのID> \
  --asset-type file

各オプションの意味は以下のとおりです。

  • --project-id :プロジェクト ID
  • --cloud-id :デプロイ先のクラウド実行環境 ID
  • --asset-id :1 コマンド目で登録したアセット ID
  • --asset-type :アセット種別。ZIP ファイルの場合は file

クラウド実行環境 ID は、enebular のクラウド実行環境画面で対象の環境を開き、設定タブで確認できます。実行が完了すれば、デプロイは完了です。

  プロジェクト: enebular-demo-ai(<プロジェクトID>)
  クラウド実行環境: cloud-app-20260512(<クラウド実行環境ID>)
  アセット: python-hello(<アセットID>)
  種別: ファイル
  クラウド実行環境へのアセットデプロイを実施します。
  実行してもよろしいですか? [y/N]
> y
成功しました
デプロイ先:
  プロジェクト: enebular-demo-ai(<プロジェクトID>)
  クラウド実行環境: cloud-app-20260512(<クラウド実行環境ID>)
  アセット: python-hello(<アセットID>)

動作を確認する

デプロイが完了したら、enebular の画面でクラウド実行環境を開き、デプロイ履歴に「デプロイ済み」のステータスが表示されていることを確認します。

HTTP トリガーを設定している場合は、設定画面に表示される URL にブラウザでアクセスすると、以下のような JSON レスポンスが返ってきます。

{
  "message": "Hello from enebular CLI!",
  "timestamp": "2026-05-07T12:34:56.789000"
}

HTTP トリガーがまだ設定されていない場合は、クラウド実行環境の設定タブから有効にしてください。

画面操作と比べてみる

普段の画面操作と、今回 CLI で行った手順を並べてみます。

画面操作の場合:

  1. ブラウザで enebular を開く
  2. プロジェクトに移動する
  3. ファイル画面を開いて ZIP をアップロードする
  4. アセット名、ハンドラー、説明を入力する
  5. クラウド実行環境画面に移動する
  6. 対象の環境を開く
  7. デプロイボタンをクリックする
  8. アセットを選んでデプロイする

CLI の場合:

  1. enebular add file で ZIP を登録する
  2. enebular deploy cloud でデプロイする

修正のたびに 8 ステップを 2 ステップにできるのは、思った以上に快適です。add file の代わりに update file を使えば、既存のアセットを上書きする形でも運用できます。

enebular CLI のコマンド一覧については @uhuru/enebular-cli – npm をご確認ください。

次のステップ

ここまでで、ローカル PC からコマンド一発で enebular にデプロイできるようになりました。

次のステップとしては、たとえば以下のような活用方法があるでしょう。

  • 今回の手順を GitHub Actions に載せて、Git にプッシュするだけでデプロイが走るようにする
  • データストアを使うアプリケーションを書いてみる

まとめ

今回は、enebular CLI を使って Python アプリケーションの ZIP ファイルをクラウド実行環境にデプロイする手順をご紹介しました。

add filedeploy cloud の 2 コマンドを覚えるだけで、普段の画面操作はターミナル 1 つで完結します。修正してデプロイし直すサイクルを何度も繰り返す開発フェーズでは、この差は意外と大きいです。

まずは手元の環境で 1 度試してみて、画面操作とのテンポの違いを体感してみてください。

おまけ

単にテキストが表示されるチュートリアルだと面白くないので、クラウド実行環境でアナログ時計を表示させてみましょう。

以下のコードをHTTPトリガーで実行すれば、指定したURLにアクセスするたびに現在時刻で時計が描画されます。サーバーサイドで処理が動いていることが視覚的に分かります。

from datetime import datetime, timezone, timedelta
import math

def lambda_handler(event, context):
    # 日本時間で現在時刻を取得
    jst = timezone(timedelta(hours=9))
    now = datetime.now(jst)
    h, m, s = now.hour % 12, now.minute, now.second

    # 針の角度を計算(12時が0度、時計回り)
    s_angle = s * 6
    m_angle = m * 6 + s * 0.1
    h_angle = h * 30 + m * 0.5

    def hand(angle, length, width, color):
        rad = math.radians(angle - 90)
        x = 100 + length * math.cos(rad)
        y = 100 + length * math.sin(rad)
        return f'<line x1="100" y1="100" x2="{x:.1f}" y2="{y:.1f}" stroke="{color}" stroke-width="{width}" stroke-linecap="round"/>'

    svg = f"""<html>
<head><meta charset="utf-8"><title>enebular clock</title></head>
<body style="background:#1a1a2e; display:flex; justify-content:center; align-items:center; height:100vh; margin:0;">
<svg width="220" height="220" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- 文字盤 -->
  <circle cx="100" cy="100" r="95" fill="#16213e" stroke="#e94560" stroke-width="3"/>
  <!-- 目盛り -->
  {''.join([
      f'<line x1="{100 + 80 * math.cos(math.radians(i * 30 - 90)):.1f}" '
      f'y1="{100 + 80 * math.sin(math.radians(i * 30 - 90)):.1f}" '
      f'x2="{100 + 90 * math.cos(math.radians(i * 30 - 90)):.1f}" '
      f'y2="{100 + 90 * math.sin(math.radians(i * 30 - 90)):.1f}" '
      f'stroke="#e94560" stroke-width="2"/>'
      for i in range(12)
  ])}
  <!-- 針 -->
  {hand(h_angle, 50, 5, '#ffffff')}
  {hand(m_angle, 70, 3, '#ffffff')}
  {hand(s_angle, 80, 1.5, '#e94560')}
  <!-- 中心点 -->
  <circle cx="100" cy="100" r="4" fill="#e94560"/>
  <!-- 時刻テキスト -->
  <text x="100" y="155" text-anchor="middle" fill="#aaaaaa" font-size="12" font-family="monospace">
    {now.strftime('%H:%M:%S')} JST
  </text>
</svg>
</body>
</html>"""

    return {
        'statusCode': 200,
        'headers': {'Content-Type': 'text/html'},
        'body': svg
    }

試し方

# ZIPを作る
zip clock-app.zip lambda_function.py

# enebularに登録(初回)
enebular add file \
  --project-id <プロジェクトID> \
  --file ./clock-app.zip \
  --deploy-type cloud \
  --handler lambda_function.lambda_handler \
  --name "python-clock" \
  --detail "SVG analog clock"

# デプロイ
enebular deploy cloud \
  --project-id <プロジェクトID> \
  --cloud-id <クラウド実行環境ID> \
  --asset-id <アセットID> \
  --asset-type file

実行結果