OCI Functionsで特定コンパートメントにイメージをpushする

# はじめに
OCI FunctionsはOracle Cloud Infrastructureが提供する、フルマネージド、高スケーラビリティ、実行時のみ課金のサーバレス実行環境（Function-as-a-Services）です。

https://docs.oracle.com/ja-jp/iaas/Content/Functions/Concepts/functionsoverview.htm

https://speakerdeck.com/oracle4engineer/functions-overview

## OCI Functionsがイメージをpushするコンパートメント
Fnコマンドでは通常、存在しないリポジトリの名前でFunctionsをデプロイした場合には、ルート・コンパートメントに新規レポジトリが自動的に作成されます。
> イメージをプッシュする場合は、通常、docker push <region-key>.ocir.io/<tenancy-namespace>/<repo-name>:<version>というフォーマットのコマンドを使用します。ただし、「ルート・コンパートメントの初回プッシュ時にリポジトリを作成」オプションを選択し、存在しないリポジトリの名前を含むコマンドを使用してイメージをプッシュすると、新規プライベート・リポジトリがルート・コンパートメントに自動的に作成されます。

https://docs.oracle.com/ja-jp/iaas/Content/Registry/Tasks/registrycreatingarepository.htm#top

また、Fn contextによるFunctionイメージのpush先のコンパートメントについてはこちらのドキュメントに詳細が記載されています。

https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionscreatefncontext.htm#Create_an_Fn_Project_CLI_Context_to_Connect_to_Oracle_Cloud_Infrastructure


OCI Fucntionsの入門的な手順を解説しているOCIチュートリアルではコンパートメントを指定していないため、上記のドキュメントの通りrootコンパートメントにリポジトリが作成され、Functionイメージがpushされます。

今回は、OCIチュートリアルの内容にコンパートメントの指定を加える形で任意のコンパートメントにFunctionイメージをpushする手順を解説します。

# 前提
- Functionイメージのデプロイに必要なコンパートメント、VCN、認証トークンは事前に作成済とする
- オブジェクト・ストレージ・ネームスペース、コンパートメントID、認証トークンの文字列は取得済とする
- 今回使用する各種情報
    - Compartment: functionsdemo
    - Functionsアプリケーション: helloworld-app
    - OCIRリポジトリ: demo-repo

VCNの作成や各種情報を取得する手順については今回省きますが、詳しく知りたい方はOCIチュートリアルをご参照ください。

https://oracle-japan.github.io/ocitutorials/cloud-native/functions-for-beginners/#2-4-oracle-functions%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90


# 手順

## 1. Functionsアプリケーションの作成
OCIコンソールから、OCIアプリケーションを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357379/1ddd9b5d-20bb-9980-afa8-25140c6c846e.png)



## 2. 特定のコンパートメントにFunctionイメージをpushする
Cloud Shellを利用して、Fn contextの設定およびFunctionの作成、デプロイをします。
4つ目のコマンドで`oracle.image-compartment-id`を設定することで、リポジトリのコンパートメントを指定できます。

```bash
# --- Fn Contextの設定、OCIRへのログイン ---
# 現在使用されているcontextを確認
fn list context

# 利用しているリージョンのconextを選択する（今回は東京リージョン）
fn use context ap-tokyo-1 

# FuncionがデプロイされることになるコンパートメントIDを設定する
fn update context oracle.compartment-id <compartment-ocid>

# この設定がOCIチュートリアルにはないので追加する
# OCI FunctionsがイメージのpushおよびpullするリポジトリのコンパートメントOCIDを設定する
fn update context oracle.image-compartment-id <compartment-ocid>

# OCIRを設定する
fn update context registry nrt.ocir.io/<オブジェクト・ストレージ・ネームスペース>/demo-repo

# OCI Functionsで使用するprofile名を設定する
fn update context oracle.profile "DEFAULT"

# contextの情報を確認する
fn list context

# OCIRへのログイン
docker login nrt.ocir.io

# --- Functionを作成、デプロイする ---
# 'helloworld-func'ボイラープレート・ファンクションを生成
fn init --runtime java helloworld-func

# cd hello-java
cd helloworld-func

# Functionをデプロイ
fn -v deploy --app helloworld-app

# Functionを呼び出す
fn invoke helloworld-app helloworld-func
```

Functionsアプリケーション、OCIRリポジトリの両方において、ちゃんと指定したコンパートメントにFunctionイメージがデプロイ出来ていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357379/2adbf82b-4b6c-72ca-19c0-a8e0c5ba4168.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2357379/658d5b1c-5e7f-6131-fb50-a5726c83e979.png)

# 参考
Fn Projectの各種コンテキストの設定やデプロイされるコンパートメントの解説はこちら

https://docs.oracle.com/ja-jp/iaas/Content/Functions/Tasks/functionscreatefncontext.htm#Create_an_Fn_Project_CLI_Context_to_Connect_to_Oracle_Cloud_Infrastructure

OCIチュートリアルでOCI Functionsの基本的なデプロイ方法が詳しく解説されています

https://oracle-japan.github.io/ocitutorials/cloud-native/functions-for-beginners/#2-4-oracle-functions%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E4%BD%9C%E6%88%90