Logicky Blog

Logickyの開発ブログです

Tiltを使ってみる

k8sを使うとローカルでの開発がめんどくさくなりました。毎回ビルドしたりdeploymentを削除したりしないといけないからです。HotReload機能的なものは標準ではついていないそうです。 そこで、Tiltを使うと差分チェックして、最小限のビルド処理を自動で実行してくれて、ログとかもブラウザでいい感じに見られるようになるらしいので、使ってみたいと思います。

TiltをScoopでインストール

> scoop bucket add tilt-dev https://github.com/tilt-dev/scoop-bucket
> scoop install tilt
> tilt version
v0.33.22, built 2025-01-03

FastAPIのプロジェクトを作る

ためしにFastAPIで簡易的なプロジェクトを作ります。

> mkdir tilt-1
> cd tilt-1
> poetry init
> poetry add fastapi uvicorn
> mkdir app
> touch app/main.py

main.py

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"message": "Hello, Tilt + FastAPI!"}


@app.get("/ping")
def ping():
    return {"pong": True}

Dockerfileを作成

> touch Dockerfile

Dockerfile

# ベースイメージ
FROM python:3.12-slim

# Poetryをインストールするために必要なパッケージ等を追加
RUN apt-get update && apt-get install -y curl git

# Poetryのインストール (最新版の公式推奨スクリプト)
# バージョンは必要に応じて固定しても良い
RUN curl -sSL https://install.python-poetry.org | python3 -

# Poetry がインストールされたパスを通す
ENV PATH="/root/.local/bin:${PATH}"

# 作業ディレクトリ作成
WORKDIR /app

# ホスト側の pyproject.toml / poetry.lock をコピー
COPY pyproject.toml poetry.lock /app/

# Poetryで依存関係をインストール (--no-root でプロジェクト本体はインストールしない)
RUN poetry install --no-root

# ソースコードをコピー
COPY . /app

# プロジェクト本体をインストール (必要に応じて)
# RUN poetry install

# FastAPIを起動するコマンド
CMD ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

k8sのDeployment, Serviceのyamlファイルを作成

touch deployment.yaml
touch service.yaml

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-tilt-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-tilt-app
  template:
    metadata:
      labels:
        app: my-tilt-app
    spec:
      containers:
        - name: my-tilt-app
          image: my-tilt-app-image:latest
          ports:
            - containerPort: 8000

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-tilt-app-service
spec:
  selector:
    app: my-tilt-app
  ports:
    - port: 80
      targetPort: 8000
      protocol: TCP
  type: NodePort

Tiltflieを作る

# Tiltfile

# 1. Dockerイメージのビルド設定
docker_build(
  'my-tilt-app-image',  # イメージ名。deployment.yaml で参照
  '.',
  dockerfile='Dockerfile',
  live_update=[
    sync('.', '/app'),  # ホストの現在ディレクトリをコンテナの /app に同期
    run('poetry install --no-root', trigger=['pyproject.toml', 'poetry.lock'])
  ],
)

# 2. k8s マニフェストの読み込み
k8s_yaml('k8s/deployment.yaml')
k8s_yaml('k8s/service.yaml')


# 3. ポートフォワード設定(Service を利用しない場合や補助的に使う場合)
#   Service: NodePort でアクセス可能なら必須ではありませんが、補助的に設定する例
k8s_resource(
  'my-tilt-app',
  port_forwards=8000  # 例:ローカルホストの 8000 番を Pod の 8000 番にフォワード
)

# 4. 推奨: Tilt が実行されたら Minikube コンテキストを自動的に使用する
#   事前に `kubectl config use-context minikube` しているなら省略可。
#   参考: https://docs.tilt.dev/api.html#tilt_set_team   (最新版のAPIをご確認ください)

tilt upする

> tilt up
Tilt started on http://localhost:10350/
v0.33.22, built 2025-01-03

(space) to open the browser
(s) to stream logs (--stream=true)
(t) to open legacy terminal mode (--legacy=true)
(ctrl-c) to exit
Opening browser: http://localhost:10350/

tiltのコンソールを開く

上記のhttp://localhost:10350を開くと下記のような画面になりました。

http://localhost:8000でFastAPIのエンドポイントにアクセスできました! しかも、main.pyを変更すると、即座に変更が反映されました!

感想

超便利。Tiltを使わない場合、docker buildしてもminikubeで使えなくてminikube loadしないといけなかったり、色々deployment側で設定を追加していないとminikubeのリポジトリを見てくれなかったりしました。また、修正したらビルドし直しで、差分チェックとかしない場合、再ビルドにものすごく時間がかかります。あと、Windows11の場合だけかもしれませんが、NodePortで30080とか指定しても、直接アクセスできず、minikube service xxxxみたいなやつを使わないとアクセス可能なurlが取得できませんでした。これを使うとportがランダムになったりしました。ということで、何しろ結構めんどくさかったです。Tiltを使うと、Tiltfileにビルド内容を書くだけで、tilt upでビルドしてくてれて、自動的にMinikubeのイメージに入りました。port_forwards設定をすると、minikube service xxxxとかやらずに、直接localhost:8000でアクセスできました。しかも、main.py修正すると一瞬でHot Reloadされます!まあ、Tiltを使わない場合でも、もっと便利なやり方はあるとは思いますが、Tiltを使うことで超便利になってよかったです。

作った内容(リポジトリ)

github.com