VSCodeのdevcontainerにAWS SAM CLIをインストールしてDockerを用いたlocal invokeもできるようにする。
VSCodeのRemote DevelopmentでSageMakerのコンテナ環境でモデルを開発する - sambaiz-net
HomebrewとSAM CLIのインストール
手順に従ってbrewでインストールする。
- Homebrewがsudoとgit、psを必要とするのでインストールする
- デフォルトのrootでHomebrewをインストールするとDon’t run this as root!になるので non-root userを作って そのユーザーで実行する
brew install aws-sam-cli
でsamはインストールできているのにexit 1
して失敗するのを握り潰している- 次にdockerが必要となるので入れている
FROM debian:buster
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
# Create the user
RUN groupadd --gid $USER_GID $USERNAME \
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
#
# [Optional] Add sudo support. Omit if you don't need to install software after connecting.
&& apt-get update \
&& apt-get install -y sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME
USER $USERNAME
WORKDIR /home/$USERNAME
# Install Homebrew & SAM CLI
RUN sudo apt-get update && sudo apt-get install -y curl git procps && \
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" && \
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv) && \
echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile && \
brew tap aws/tap && (brew install aws-sam-cli docker; true)
実行できるか確認したところnot foundになってしまいインストールに失敗したのかと思ったが、
PATHが通ってないだけで、-l
フラグを付けると~/.profile
などが読まれてコマンドが実行できるようになった。
$ docker build -t sam-image .
$ docker run sam-image sam --version
docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"sam\": executable file not found in $PATH": unknown.
$ docker run -it hogea /bin/sh -l -c "sam --version"
SAM CLI, version 1.6.2
ということでsettingsに次の項目を追加した。
{
"settings": {
...
"terminal.integrated.shellArgs.linux": ["-l"]
}
}
Docker in Dockerの設定
initしてローカルで実行したところ次のようなエラーが出た。SAM CLIはローカル実行や--use-container
でのビルドのためにDockerを用いる。
$ sam local invoke HelloWorldFunction --event events/event.json
...
Error: Running AWS SAM projects locally requires Docker. Have you got it installed and running?
そこでdevcontainer.json
のmountsにdocker.sockを追加し、コンテナ内からホストのDockerデーモンにアクセスできるようにする。
{
...
"mounts": [
"source=${localEnv:HOME}/.aws,target=/home/vscode/.aws,type=bind,readonly",
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"postCreateCommand": "sudo chown vscode /var/run/docker.sock"
}
Dockerコマンドでデーモンにアクセスできることを確認。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
...
Docker for MacでのMounts denied
sam local invoke
したところ次のエラーが出た。
$ sam local invoke
...
docker.errors.APIError: 500 Server Error: Internal Server Error ("b'Mounts denied: \nThe path /workspaces/*** is not shared from the host and is not known to Docker.\nYou can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.\nSee https://docs.docker.com/docker-for-mac for more info.'")
FILE SHARINGの設定に対象のパスを追加した。
/var/task/***: no such file or directory
再びsam local invoke
したところ次のエラーに変わった。sam build
は成功していて対象のパスにはファイルが存在する。
Mounting /workspaces/***/.aws-sam/build/*** as /var/task:ro,delegated inside runtime container
START RequestId: 79793925-12c5-175d-cfb4-5e1e0523f757 Version: $LATEST
fork/exec /var/task/***: no such file or directory: PathError
リモートのDockerを使う場合は、–docker-volume-basedirでリモート、つまりホストの方のパスを指定する必要がある。そこで次の環境変数を定義してホストのパスを渡せるようにした。
{
"remoteEnv": {
"HOSTPWD": "${localEnv:PWD}"
}
}
$ sam local invoke --docker-volume-basedir ${HOSTPWD}/.aws-sam/build