search
LoginSignup
5

More than 1 year has passed since last update.

posted at

updated at

SAM CLI の Docker内(--use-container) ビルドをProxy環境下で実施する方法

2017年頃からサーバレスに浸っている、小西啓介です。

image.png

SAM CLIでは、Lambdaに近い環境でビルドできる

SAM(Serverless Application Model) CLI のビルドコマンド(sam build)には、
Lambda用の npmpip などで、アーキテクチャ(WindowsかLinux等)に依存するモジュールが有る場合に対応する
オプション (--use-container)がある。

このオプションを使用すると、通常、実行環境(windows等)で行うビルド処理を、Lambda(Amazon Linux) に近い
Docker環境内で行うようなるため、コンパイルを伴うような場合でも問題なく(※文末参照 2020/07/10追記)、Lambda用のリソースを作成することが可能となる。

Proxyの憂鬱

ここにも、毎度おなじみのProxyの憂鬱がある。

PS C:\Users\komikoni\workspace\sam app> sam build --use-container

Building function 'NodeFunc'
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine

Fetching lambci/lambda:build-nodejs12.x Docker container image......
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine

Build Failed
Error: NodejsNpmBuilder:NpmInstall - NPM Failed: npm ERR! code ENOTFOUND
npm ERR! errno ENOTFOUND
npm ERR! network request to https://registry.npmjs.org/jsonwebtoken failed, reason: getaddrinfo ENOTFOUND registry.npmjs.org
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'

npm ERR! A complete log of this run can be found in:

実行環境が、Proxy経由でインターネットに繋がっている場合、
当然、Docker内からもProxy経由でしかインターネットに繋ぐことが出来ない為、
Docker インスタンスに対して、環境変数等でProxy設定を与えてあげる必要がある。

しかし、SAM のビルドコマンド(sam build)で、実行する場合、動的にDockerインスタンスを作成し
ビルドが終了すると自動的に削除される為、Proxyを与えることが難しかった。

※Docker Desktopのproxy設定は、Docker Imageをダウンロードする際に使用するProxy設定で、Docker Image内には適用されない。

この課題は、以下のIssueに上がっている。

そこで、SAM では、 Docker SDK >= 3.7.0 でサポートされた、global docker configuration file. 機能を使って、
外部からProxy設定を可能となるよう対応が行われた。

既に、上記のPull Request は、マージされてReleaseされているですが、
特にドキュメント上には、記載がなさそうなので、ここに書き残したいと思います。

global docker configuration file の設定

設定方法は、以下の記事 @2fbCvmiYKX さんの記事や Dockerのドキュメントが詳しいが、

%USERPROFILE%\.docker\config.json の編集し

変更前
{
  "auths": {
    "https://index.docker.io/v1/": {}
  },
  "credsStore": "desktop",
  "experimental": "enabled",
  "stackOrchestrator": "kubernetes"
}

を以下のように修正する

変更後
{
  "auths": {
    "https://index.docker.io/v1/": {}
  },
  "credsStore": "desktop",
  "experimental": "enabled",
  "stackOrchestrator": "kubernetes",
  "proxies": {
    "default": {
      "httpProxy": "http://proxy.example.com:8080",
      "httpsProxy": "http://proxy.example.com:8080",
      "noProxy": "no_proxy.example.com"
    }
  }
}

これで、以下の通り、Proxy環境下であっても、SAM CLI の Docker内(--use-container) ビルドを実施することが、可能となる。

PS C:\Users\komikoni\workspace\sam app> sam build --use-container

Starting Build inside a container
Building function 'AuthFunc'
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine

Fetching lambci/lambda:build-nodejs12.x Docker container image......
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'NodeFunc'

Fetching lambci/lambda:build-nodejs12.x Docker container
image..............................................................................................................................................................................................................
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'PythonFunc'
//./pipe/docker_engine
//./pipe/docker_engine

Fetching lambci/lambda:build-python3.6 Docker container image..............................................................................................................................................................................................................
Mounting C:\Users\komikoni\workspace\sam app\python-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine

Build Succeeded

Built Artifacts  : .aws-sam\build
Built Template   : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided

Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
PS C:\Users\komikoni\workspace\sam app> 

実行ファイルのパーミッションについて (2020/07/10追記) → (2020/10/30解消)

一点書き忘れました、 --use-container を利用した場合、コンパイルを伴うビルドも可能ですが、実行ファイルに関しては、問題があります。
基本的に、Windowsでは、パーミッション設定が行えずZip化する場合もパーミッションが付与されない為、Lambda内で実行する際にパーミッションエラーとなります。

上記の通り、Issueが上がっていますが、2020/07/10現在まだマージされておらず、
以下のいずれかの方法を取る必要があります。

  1. Windowsから、--use-containerを使うのではなく、LinuxにSAM を入れでビルドを行う。
  2. sam build 、 sam deploy やcfn deploy を使わず、自分でZip化し、パーミッションを設定する。
  3. Lambda上で、パーミッションを変更する。

3. について、Zipで上げたファイルの自体は、領域としてパーミッション変更できない為、
一度 /tmp にコピーしてからパーミッションを変更して、実行する必要があります。

早くIssueが取り込まれることを期待したいですね。

ついに取り込まれて解消しました。

SAM CLI Release 1.7.0
2020/10/30に解消しました。

7d5101a - Fix: Missing Unix Permission Bits for Artifact ZIP Created in Windows (#2193)

と記載がある通り、上記Issueが解消しました。(実際は別Issue のGo周りの対応で解消された)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5