きっかけ
ある日、AWS ベースイメージを使用してLambda関数を作成していました。
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
で動作確認をしていると
- コンテナイメージをビルドし直さないと変更が反映されない
-
VOLUME
が使えない???
-
-
console.log
で出力されない
というのが面倒だったので、
開発環境用にAWS Lambdaとは別にNode.js環境を作りました。
本番用には、通常通りAWS ベースイメージのDockerfileでビルドして、ECRにアップロードしたらよいので、簡単に切り分けられました。
やったこと
開発環境用のDockerfileを作成
まず開発環境用にAWS ベースイメージとは別のDockerfileを作成します。
ファイル名はDockerfile.dev
としています。
Dockerfile.dev
FROM node:20
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
開発環境用のcompose.yamlを作成
ここで開発環境用のDockerfileを読み込んでます。
開発環境用の環境変数もここで読み込むようにすると楽だと思います。
compose.yaml
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
tty: true
volumes:
- .:/usr/src/app
environment:
...
実行用シェルスクリプト作成
作成した関数を実行する用のシェルスクリプトを作成しました。動作確認用のパラメータをJSONファイルで渡せるようにしたり、
当時、コンテナイメージ内に複数の関数を持つようにしていたので、引数で対象のディレクトリを指定できるようにしました。
dev_run.sh
#!/bin/bash
# 引数で渡されたディレクトリを取得
TARGET_DIR="$1"
# 引数が指定されていない場合はエラーメッセージを表示
if [ -z "$TARGET_DIR" ]; then
echo "Usage: $0 <directory>"
exit 1
fi
FULL_PATH="$(pwd)/$TARGET_DIR"
# Node.jsスクリプトを実行 別ファイルに分けたっていい
node -e "
const path = require('path');
const fs = require('fs');
const handlerPath = path.join('$FULL_PATH', 'handler.js');
const jsonFilePath = path.join('$FULL_PATH', 'test_request.json');
let event = [];
if (fs.existsSync(jsonFilePath)) {
const json = fs.readFileSync(jsonFilePath, 'utf8');
event = JSON.parse(json);
}
const handler = require(handlerPath);
handler.handler(event).then(result => {
console.log(result);
}).catch(err => {
console.error(err);
});
"
おわりに
これでサクサク動作確認ができるようになりました。
後はこれにテスト実行用のシェルスクリプトも作れば、さらに効率的に開発が進められると思います。