Google Chromeは動かない

はじめに WebアプリケーションのテストにHeadless Chromeを使いたいと思いました。 Lambdaで動かせると安いし起動も早いかなぁと思ってたのですがどうも動かないようです。 考えていた構成としてコンテナにChromeをインストールしてlambdaでコンテナを起動するというものでした。 結論 lambdaでは /tmp 以外が読み書きできないのでChromeが動かないようです。 具体的には /dev/fd とか /run に書き込めないって怒られます。 回避策 結局やりたかったことは手軽にheadlessをserverless環境で動かしたいということなのでECS Fargateの上で動かしました。 lambdaに比べると起動時間がだいぶ遅くなりましたが我慢しました。 EC2にECS clusterを構築すると多少早くはなりますが、ずっと起動しておくものでもないのでコスト的にFargateを利用しています。 参考 最新のGoogle Chromeとchromedriverを動かすDockerfile例 FROMdebian:latestWORKDIR/tmpRUN set -e \ && apt-get update \ && apt-get upgrade -y \ && sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ && apt-get install -y wget gnupg unzip \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && apt-get update \ && apt-get install -y google-chrome-stable udev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && CHROME_VERSION=$(google-chrome --version | awk '{print $3}' ) \ && echo "Chrome version: ${CHROME_VERSION}" \ && wget -q -O /tmp/chromedriver....

10月 20, 2023

Go 1.20でlambdaで動くプログラムを書いてlocalビルドしてデプロイしたら死んだ

タイトルの通りでプロセスが死にました。 ログはこのような感じです。 2023-02-07T19:39:42.063+09:00 INIT_START Runtime Version: go:1.v13 Runtime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2023-02-07T19:39:42.090+09:00 /var/task/main: /lib64/libc.so.6: version `GLIBC_2.32' not found (required by /var/task/main) 2023-02-07T19:39:42.090+09:00 /var/task/main: /lib64/libc.so.6: version `GLIBC_2.34' not found (required by /var/task/main) 2023-02-07T19:39:42.090+09:00 2023/02/07 10:39:42 exit status 1 glibcの依存で周りで死んでるようですね。 わざわざlambda上にインストールするまでもないのでCGO_ENABLED=0をつけてstatic buildしてしまえば解決です。 $ CGO_ENABLED=0 go build -o main main.go

2月 7, 2023

lambda function URLsのeventをプロキシしてhttp apiに流す

小規模なSlack BotはAWS lambda functions URLsに作ると楽だった の話の続きです. 先日lambda function URLsを利用してhttp apiのような実装を記述する方法を紹介しました. 今回は httpadapter と net/http/httputil を利用してlambda function URLsをリバースプロキシとして動かしてbackend apiに流す方法です. 概略図 実装 普通のリバースプロキシを実装するときはhttputil.ReverseProxyを定義してserverを作って待ち受けるわけですが、 今回の場合はhttputil.ReverseProxyを定義した後httpadapter.NewV2に食わせるだけですね. 次の例はlambdaのeventを受け取ったあとlocalで8080ポートで待ち受けるhttp serverにリクエストを流すproxyの例です. func main() { director := func(req *http.Request) { req.URL.Scheme = "http" req.URL.Host = ":8080" } rp := &httputil.ReverseProxy{Director: director} lambda.Start(httpadapter.NewV2(rp).ProxyWithContext) } すべてlambda関数上で完結させたい場合は func init() などでapiを予め立ち上げた後プロキシしてあげると良いと思います. github.com/ieee0824/le2hp ではそのような実装にしました.

2月 2, 2023

小規模なSlack BotはAWS lambda functions URLsに作ると楽だった

はじめに ここで言う小規模なSlack Botというのは個人で使うようなBotやチームレベルで使う書き捨てレベルのようなもののことです. このような想定のBotを実装するときそこまでちゃんとインフラコストをかけたくありません. 自前でサーバーを用意したとして処理内容と維持管理費用が割に合わないのです. 無料でhttp serverを立ち上げることができるけど定期的にリクエストを送っておかなければプロセスがkillされるようなサービスもあります. そのようなサービスを使う場合定期的にリクエストを送るか立ち上がるまで待った後Botのためのリクエストを送らないと機能しない問題があります. それらの問題を解消するのにlambda functions URLsは要件にあってそうだなぁと思いました. lambda function URLsはlambdaなので課金が発生する時間単位が短いのでたまにしか実行されないようなものでもサーバーを立てて実現するよりお金がかからないです. またlambda function URLsにリクエストを投げるとlambdaのeventが発火して即時にlambda関数が実行されるので待ち時間も発生しません. 一つ問題があるとしたらlambdaのeventとして作成したプログラムから見えるので普段Botをhttpのapiとして実装している場合はhttp requestとlambdaのeventとのギャップを埋める必要があるということです. とはいえそこまで大きな問題にはならないと思います. 特にGo言語の場合は github.com/awslabs/aws-lambda-go-api-proxy/httpadapter を利用するとほとんどhttp serverと同じような実装でアプリケーションを作ることができます. Goでlambda function URLsを使ってリクエスト受ける例 github.com/awslabs/aws-lambda-go-api-proxy/httpadapter を利用した実装例を上げておきます. frameworkを利用しない例 frameworkを利用しない例です. 生のGo言語でhttp serverを実装したことがある人なら雰囲気が解ると思います. package main import ( "io" "net/http" "github.com/aws/aws-lambda-go/lambda" "github.com/awslabs/aws-lambda-go-api-proxy/httpadapter" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "It Works!") }) // lambda function URLsはapi gateway v2と同じeventなのでv2にする必要がある lambda.Start(httpadapter.NewV2(http.DefaultServeMux).ProxyWithContext) } Ginを利用した例 frameworkを利用することもできます. 例えばGinを利用する場合は次のように記述ができます. package main import ( "context" "net/http" "github....

1月 31, 2023