Rancher Desktopを使ってAzure functionsをローカルで動かす(Docker編)

# Rancher Desktopを使ってAzure functionsをローカルで動かす(Docker編)
## ゴール
Azure functionsを使ったWebApiで、Azureのアカウント無いけど（無料で）ソースコードの開発を試したいと思った時用に、ローカルMacのDocker環境で動作させてみました。
## 環境
環境は、Mac book、Rancher Desktop、Python(バージョン管理はpyenv)を使います。

## 準備
### 前提条件
pyenvが入ってる、Rancher Desktop(Docker)が動いている。

### Pythonのバージョン設定
今回はpythonを使ったweb apiを作成するため、pythonの準備をします。
Pythonは[3.7以上をサポート](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-reference-python?pivots=python-mode-configuration&tabs=asgi%2Capplication-level#python-version)しているということなので、3.9を設定しました。
```
#まずはインストール可能なバージョンの確認
$ pyenv install --list
#今回は、3.9.13 を使用します。
$ pyenc install 3.9.13
#3.9.13に設定する
$ pyenv global 3.9.13
#バージョン確認
$ python --version
#3.9.13に設定されてること確認
```

### Azure function core toolのインストール
azure functions をローカル コンピューター上のターミナルから開発するための[Azure function core tool](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=v4%2Cmacos%2Ccsharp%2Cportal%2Cbash)をインストールして`func`コマンドを使える用にします。

公式サイトの通り以下でインストール
```
$ brew tap azure/functions
$ brew install azure-functions-core-tools@4
#インストールの確認
$func --version
#今回は 4.0.5148がインストールされました。
```

# Dockerコンテナを使って動作確認

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-create-function-linux-custom-image?pivots=programming-language-python&tabs=in-process%2Cbash%2Cazure-cli%2Cv1#create-and-test-the-local-functions-project

ほぼこの通りに試しました。
まずは、ローカル環境にテスト用のディレクトリを作成した状態で、コマンドを実行していきます。

## functionを作成する
```
func init --docker
```
--docker オプションを付けることでdockerファイルが作成されます。
runtimeを選択するように言われるので、4のpythonを選択
```
Select a number for worker runtime:
1. dotnet
2. dotnet (isolated process)
3. node
4. python
5. powershell
6. custom
Choose option:
```
`Choose option: 4`
`Dockerfile`等が自動で作成されます。python appservice用のimageを使って、`wwwroot`にカレントディレクトリをコピーするようなDockerfileになってました。

新しいfunctionsを追加します。テンプレートは、[`HTTP trigger`](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-http-webhook-trigger?pivots=programming-language-python&tabs=python-v2%2Cin-process%2Cfunctionsv2)を選択して基本的なweb apiを作成します。
`--authlevel anonymous` は関数への[認可レベルの設定](https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-http-webhook-trigger?pivots=programming-language-python&tabs=python-v2%2Cin-process%2Cfunctionsv2#http-auth)で、アクセスキーが不要な設定とします。
```
func new --name HttpExample --authlevel anonymous
```
以下の通りテンプレートが選択できるため、`Choose option: 9`を入力します。
```
Select a number for template:
1. Azure Blob Storage trigger
2. Azure Cosmos DB trigger
3. Durable Functions activity
4. Durable Functions entity
5. Durable Functions HTTP starter
6. Durable Functions orchestrator
7. Azure Event Grid trigger
8. Azure Event Hub trigger
9. HTTP trigger
10. Kafka output
11. Kafka trigger
12. Azure Queue Storage trigger
13. RabbitMQ trigger
14. Azure Service Bus Queue trigger
15. Azure Service Bus Topic trigger
16. Timer trigger
Choose option:
```
`HttpExample`ディレクトリが作成されて、`__init__.py`でnameパラメータがリクエストされると`Hello {name}`がレスポンスされるコードが生成されます。
``` __init__.py
    if name:
        return func.HttpResponse(f"Hello, {name}. This HTTP triggered function executed successfully.")
```
また、`--authlevel anonymous`オプションを設定したことで、`HttpExample/function.json`ではauthLevelが `Anonymous`に設定されていることを確認ください。
これがデフォルトの`function`　に設定されていると、401(Unauthorized)エラーとなってしまうことがあります。

## Dockerイメージを作成して動作確認する
まずは、Rancher Desktopを動作させておきましょう。
以下のコマンドでdocker imageの作成します。
```
$ docker build --tag azurefunctionsimage:v1.0.0 .
```
確認すると無事image作成されます。
```
docker images
REPOSITORY                                TAG                    IMAGE ID       CREATED              SIZE
azurefunctionsimage                       v1.0.0                 53246a83b58d   About a minute ago   1.49GB
```
続けて、作ったimageをrunさせます。
```
docker run -p 8080:80 -it azurefunctionsimage:v1.0.0
```
ブラウザから`http://localhost:8080/api/HttpExample?name=Functions`にアクセスすると
`Hello, Functions. This HTTP triggered function executed successfully.`と表示され無事ローカルから動作確認できました。
これでローカル環境でも複数コンテナを利用した、マイクロサービスの環境なども作れそうです。

次は、kubernetesでも動作確認を行ってみたいと思います。