表題の通り OCI の API Gateway と Functions と Object Storage で 静的なHTML を公開してみますやで。前回からの続編的な記事になります。
彡(^)(^)
前回と異なるのは PAR(pre-authenticated request) が不要な点です。PAR はランダムな文字列の URL ですが、その URL が知られて直接アクセスされると APIGW無しでアクセスできてしまいます。Functions を経由させることでこの欠点を補えます。
1. HTMLファイルと画像ファイルのアップロード
Object Storage に HTMLファイルをアップロードします。手順は簡単なので省略
アップロードしたHTML(index.html)ファイルは下記になります。懐かしの手組ページ
彡(^)(^)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AYU</title>
</head>
<body>
<h1>ワイがAYUや!</h1>
<p>これはシンプルな文字と画像だけのHTMLページです。</p>
<img src="AYU.png">
</body>
</html>
2. Functions の作成(Pythonスクリプト)
Object Storage のコンテンツを読み取ってレスポンスとして返す Functions を作成します。
Functions は複数の言語に対応していますが、今回は Python を選択します。
fn init --runtime python static-html
cd static-html
vi func.py
vi requirements.txt
import io
import json
import logging
import mimetypes
import oci
from fdk import response
# ログの設定
logging.basicConfig(level=logging.INFO)
def handler(ctx, data: io.BytesIO = None):
# 1. API Gateway から渡されたパスを取得
# 例: /v1/web/index.html -> index.html
path_parameters = ctx.RequestURL().split('/')
filename = path_parameters[-1] if path_parameters[-1] else "index.html"
# 2. リソース・プリンシパルによる認証
# Function 自体に付与された権限を使用して OCI サービスにアクセス
try:
signer = oci.auth.signers.get_resource_principals_signer()
client = oci.object_storage.ObjectStorageClient({}, signer=signer)
# 環境変数などからネームスペースとバケット名を取得(直接記述も可)
namespace = client.get_namespace().data
bucket_name = "AYU-OBJSTR1"
# 3. Object Storage からファイルを取得
get_obj = client.get_object(namespace, bucket_name, filename)
content = get_obj.data.content
# 4. Content-Type の自動判別
# 拡張子に基づいて適切な MIME タイプ(text/html, image/png 等)を設定
mime_type, _ = mimetypes.guess_type(filename)
if not mime_type:
mime_type = 'application/octet-stream'
return response.Response(
ctx,
response_data=content,
headers={"Content-Type": mime_type},
status_code=200
)
except oci.exceptions.ServiceError as e:
logging.error(f"Error fetching object: {str(e)}")
return response.Response(
ctx,
response_data=json.dumps({"error": "File not found or access denied"}),
headers={"Content-Type": "application/json"},
status_code=404
)
except Exception as e:
logging.error(f"Unexpected error: {str(e)}")
return response.Response(
ctx,
response_data=json.dumps({"error": "Internal Server Error"}),
headers={"Content-Type": "application/json"},
status_code=500
)
fdk>=0.1.109
oci>=2.120.0
コードを記述したらデプロイします。
fn --verbose deploy --app ayu-functions1
Deploying static-html to app: ayu-functions1
Bumped to version 0.0.4
Using Container engine docker
:
Writing manifest to image destination
Updating function static-html using image phx.ocir.io/xxxxxxxxxxxx/ayu-repo1/static-html:0.0.4...
Functions の環境構築や実行環境整備は下記記事等を参照してください。
3. APIGW Deployment の作成
APIGW自体の作成は前回記事を参照して下さい。デプロイメントの必要事項を記入して作成していきます。
名前…任意
Path…/
コンパートメント…任意ですがAPIGWと同一にしておきます。
その他はデフォルト(Rate limiting=流量制限くらいは入れても良いかもです)
認証は今回は無し。
ルートのPath…/{file*}
Methods…GET
Backend Type…Oracle Functions
Application in Compartment…Functionsを作成したコンパートメント
Function Name…先ほど作成したPythonのFunctionsを選択
確認画面
エンドポイントと共にAPIGWのデプロイメントが作成されます。
4. APIGW経由で静的コンテンツにアクセス
APIGW Deploymentのエンドポイントにアップロードしたファイル(index.html)を付与してアクセスしてみます。
ワイがAYUや!彡(^)(^)
5. まとめ
Object Storage にアップロードした静的なファイルを APIGW+Functions経由で公開できました。ちなみにワイは Python は全く書けないマンなので Functions の Python は全て AI様 にコーディングしていただきました。AIしゅごい……。
お仕事無くなるかもですね彡(^)(^) 恐怖に怯えながらキリキリ頑張りましょう。
おまけ
OCI でいにしえのホームページを再現や!
彡(^)(^)








