Amplifyの開発をVSCode Remote containerで行う(その2)


前回は、その1を参照
その2では、Amplify SNS workshop とは別の視点で開発環境を作成する

その1と違う点

  • ワークショップ向けの設定なので、いくつか改変してみる
  • nodeのバージョン
  • amplifyのバージョン
  • コンテナからホスト側を使った開発 /hostdir を使う
  • プロファイル(aws、ssh)を使う、切替える

  • toriさんオリジナルの方では、speeeeedアップのため、コンテナ内での開発 /workspaces を使うようになっている

    • コンテナ内だと速さが段違いです。ホスト側を使うと遅いのは DockerとWSL2に起因する問題だと思われる、後述参照。

Dockerfile

FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-14

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get -y install --no-install-recommends java-common zip \
    && wget https://corretto.aws/downloads/latest/amazon-corretto-8-x64-linux-jdk.deb \
    && dpkg --install amazon-corretto-8-x64-linux-jdk.deb \
    && wget https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip \
    && unzip awscli-exe-linux-x86_64.zip \
    && ./aws/install \
    # Clean up
    && rm -f awscli-exe-linux-x86_64.zip \
    && rm -f amazon-corretto-8-x64-linux-jdk.deb \
    && apt-get autoremove -y \
    && apt-get clean -y \
    && rm -rf /var/lib/apt/lists/*
ENV DEBIAN_FRONTEND=dialog

WORKDIR /workspaces

WORKDIR は変更せず

Docker hub

mcr.microsoft.com/vscode/devcontainers/javascript-node:14
mcr.microsoft.com/vscode/devcontainers/javascript-node:16

があり、AmplifyはNode14対応なので、バージョンアップできる。
nodeを14使うように変更すると、2021-07-02時点でのコンテナイメージでは V14.17.1 になる。

devcontainer.jsonを変更

{
    "name": "AWS Amplify SampleSystem",

    "dockerFile": "Dockerfile",

    // Set *default* container specific settings.json values on container create.
    "settings": { 
        "terminal.integrated.shell.linux": "/bin/bash"
    },

    // Add the IDs of extensions you want installed when the container is created.
    // Git Extension Pack => "donjayamanne.git-extension-pack"
    // GraphQL => "graphql.vscode-graphql"
    // GraphQL for VSCode => kumar-harsh.graphql-for-vscode
    "extensions": [
        "dbaeumer.vscode-eslint",
        "mhutchie.git-graph",
        "eamodio.gitlens"

    ],

    // Mount ~/.aws directory for AWS Amplify CLI and AWS CLI access
    // Mount ~/.ssh directory for Git Repository GitHub, GitLab ...
    "mounts": [
        "source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws,target=/root/.aws,type=bind,consistency=cached",
        "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/root/.ssh,type=bind,consistency=cached"
    ],

    // Use in-container folder (not mounted host directory) as a workspace to speeeeeeed-up the `npx create-react-app` command. See https://github.com/toricls/aws-amplify-sns-workshop-in-vscode/pull/3.
    // {localWorkspaceFolder} is open folder host path.
    "workspaceMount": "source=${localWorkspaceFolder},target=/hostdir,type=bind,consistency=cached",
    "workspaceFolder": "/hostdir",
    "containerEnv": { 
        "MOUNTED_HOST_DIR": "${localWorkspaceFolder}",
        "MOUNTED_HOST_DIR_PATH_IN_CONTAINER": "/hostdir"
    },

    // Use 'forwardPorts' to make a list of ports inside the container available locally.
    // npm , amplify mock api , 62224 DynamoDB
    "forwardPorts": [3000,20002],

    // Use 'postCreateCommand' to run commands after the container is created.
    "postCreateCommand": "npm install -g @aws-amplify/[email protected]",

    // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root.
    // "remoteUser": "node"
     
    // docker container name (Identify Dev Containers)
    "runArgs": [
        "--name=dev_container"
    ]
}

name

"name": "${localWorkspaceFolderBasename}",
にすると、ディレクトリ名でよしなにやってくれる。Dockerのコンテナ名とは別。

extensions

  • VSCodeの拡張機能を指定する、Git連携するならばVSCodeからGit操作できる拡張機能を入れておく方が良い

mounts

  • AWSのクレデンシャルファイルをホスト側のマシンと共有する場合にマウントする
  • 案件・プロジェクトでクレデンシャルが異なる場合は、マウント場所を変えるか、マウントせずにコンテナビルド後にファイルを置く
- credentials :aws_access_key_idとaws_secret_access_keyが記載された重要なファイル
- config  :デフォルトの接続先リージョン
  • 例えば 以下のようにUSERPROFILEをカレントディレクトリにすれば、credentialsの切替えは楽になる

サンプル
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws,target=/root/.aws,type=bind,consistency=cached",

"source=./aws,target=/root/.aws,type=bind,consistency=cached",

に変更する


SSH

  • git接続等で使う、ssh key をホスト側と共有する場合にマウントする
    • コンテナ内で、ssh key 生成したものを、Windows側にもってきても使えなかった(そうなの? Mac使ってたから意識したことなかった)。
    • どうやらopen-ssh形式というのが関連している。これだからwindowsは・・・と、言われる。
  • 対応例 https://coffee-nominagara.com/2018-06-22-093801

  • コンテナ内で ssh key 作成する場合の例

Linux向けのssh key 作成例
cd ~/
~/.ssh $ ssh-keygen -t rsa -C "メールのアカウント@ドメイン"

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.


中身を確認
~/.ssh $ cat id_rsa.pub
~/.ssh $ cat id_rsa

pubの方をGithubに登録する

接続してみる
~/.ssh $ ssh -T [email protected]

Hi xxxxx! You've successfully authenticated, but GitHub does not provide shell access.

クローンしてみる
$ git clone [email protected]:xxxxxxx/xxxxxx.git



コンテナから見るホスト側(コンテナに対し、ホスト側を共有する)

    "workspaceMount": "source=${localWorkspaceFolder},target=/hostdir,type=bind,consistency=cached",
    "workspaceFolder": "/hostdir",
    "containerEnv": { 
        "MOUNTED_HOST_DIR": "${localWorkspaceFolder}",
        "MOUNTED_HOST_DIR_PATH_IN_CONTAINER": "/hostdir"
    },

上記の箇所が設定で、公式ドキュメントでは https://code.visualstudio.com/docs/remote/containers-advanced

workspaceMount

  • ホスト側の場所を、コンテナ内のどのディレクトリをtargetとし、ホストをsourceとしてマウントする設定になる。
  • ホスト側は、「.devcontainer」フォルダのある場所(.devcontainerと同じディレクトリ)がカレントディレクトリになり、コンテナ内の /hostdirがその場所になる。
  • コンテナ内で cd /hostdir して、ls すると、(.devcontainerと同じディレクトリにある)ホスト側のファイルが見られる

workspaceFolder

  • VSCodeでコンテナ内に接続した時のデフォルトの場所、ホスト側と共有した場所がVSCodeで開いたときの最初の場所になる、
  • デフォルトがホスト側の場所にしたい場合は "workspaceFolder": "/hostdir",を指定する。
  • デフォルトが コンテナ内の/workspacesが良い場合はそれを指定する。

コンテナビルドで入れている Amplifyのバージョンを最新に変更

  • バージョンは 2021-06-30では 5.0.2、2021-07-01に、Amplify-cliはV5.1.0がリリースされた
    "postCreateCommand": "npm install -g @aws-amplify/[email protected]",
  • ビルド後の処理 devcontainer.jsonpostCreateCommand ビルド後の処理が設定できる。ここで個人ごとに設定を行うことも可能。

runArgsでコンテナの識別、name指定することでコンテナ名をわかりやすくする

    "runArgs": [
        "--name=project_dev_container"
    ]

実際の開発で使った場合

  • 注意事項、/hostdir はWindows側をマウントしておりwsl2の場合はファイルアクセスが非常に遅いです
  • コンテナ初期化したらいったんVSCodeを閉じて、VSCodeを新規起動する
  • ホスト側で VSCode で コンテナの元になっているディレクトリを開くと、workspaceFolderの場所になるので、VSCode -> ツールバー の Terminal -> New Terminal で開くと、/hostdir をデフォルトで開く、そしてそこはコンテナの元になっているディレクトリになり、ホスト側の場所でもある。 (ホスト側の場所:docker-composeでvolumesでホスト側をマウントしたときと同じような場所)
  • Terminalを開いて、以下のコマンド実行

    コマンド実行例
    root ➜ /hostdir $ mkdir amplify-sns-workshop
    root ➜ /hostdir $ cd amplify-sns-workshop/
    root ➜ /hostdir/amplify-sns-workshop $ npx create-react-app boyaki
    npx: installed 67 in 2.912s
    
    Creating a new React app in /hostdir/amplify-sns-workshop/boyaki.
    
    Installing packages. This might take a couple of minutes.
    Installing react, react-dom, and react-scripts with cra-template...
    
    ....
    
    root ➜ /hostdir $ mkdir amplify-sns-workshop
    root ➜ /hostdir $ cd amplify-sns-workshop/
    root ➜ /hostdir/amplify-sns-workshop $ npx create-react-app boyaki
    npx: installed 67 in 2.912s
    
    Creating a new React app in /hostdir/amplify-sns-workshop/boyaki.
    
    Installing packages. This might take a couple of minutes.
    Installing react, react-dom, and react-scripts with cra-template...
    
    root ➜ /hostdir/amplify-sns-workshop/boyaki (master) $ amplify init
    root ➜ /hostdir/amplify-sns-workshop/boyaki (master) $ yarn start
    

  1. 問題なく動いて、
    • /hostdir/amplify-sns-workshop/boyaki で進められる。
    • ホスト側の場所でもあるため、
      /hostdir
      C:\usr\aws-tutorial\vsremote-20210703-compose\ ディレクトリだとすると
      C:\usr\aws-tutorial\vsremote-20210703-compose\amplify-sns-workshop\boyaki となり。
    • ファイルはコンテナ内でもホスト側でも編集できる。
    • ホスト側のSourceTreeやGitHubDesktop等のGitのGUIクライアントを使うことができる。
  2. yarn start | npm start はけっこう時間かかる、処理が終われば http://localhost:3000/ でReactの画面が表示される

(番外編)自分自身の環境

dockerコンテナ内のファイルを使う場合とWindows側のホストのファイルを使う場合

  • コンテナ側 /workspaces と ホスト側 /hostdir
  • 自身のがdocker desktop で wsl2 Ubuntuでないためか npx のコマンドで10倍以上 yarn startでも10倍以上の差があり、/hostdir がかなり遅い。
  • 自身の環境では、dockerでホスト側を共有したvolumeの速度はwsl1の時相当になっているため非常に遅い(WSL2 の仮想マシンとして Docker サーバーが動くようになっている、wsl2 Ubuntuは動いていない)
  • 自身のDocket desktop の設定では
    General -> Use the WSL2 based engine はチェックON(後述の画面キャプチャ参照)、
    Resources -> WSL Integration では Ubuntuが表示されていなかった(マイクロソフトストアからUbuntsを入れていない状態)
     なお、最新の自身の環境ではUbuntuがインストール失敗しないようになったため、Ubunts入れたが、Ubunts-20.04は有効にしていない(後述の画面キャプチャ参照)、

  • 自身の設定をコマンドプロンプトで見ると

    • Ubunts 20.04 入れる前
    >wsl -l -v
    NAME                   STATE           VERSION
    * docker-desktop-data    Running         2
      docker-desktop         Running         2
    
    • Ubunts 20.04 入れた後
    wsl -l -v
    NAME                   STATE           VERSION
    * docker-desktop-data    Running         2
      docker-desktop         Running         2
      Ubuntu-20.04           Running         2
    
  • Dockerの設定画面

    • General -> Use the WSL2 based engine
    • Resources -> WSL Integration Ubunts-20.04は有効でない(無効)

WSL2でのコンテナ-ホスト間の速度改善 を行うには(速くなるのか不明) できなかった

Performance is much higher when files are bind-mounted from the Linux filesystem, 
rather than remoted from the Windows host. 
Therefore avoid docker run -v /mnt/c/users:/users (where /mnt/c is mounted from Windows).

とあり、windows側の/mnt/c/users/users にマウントするのは避けるって書かれてるな。
wsl2 Ubuntu内のファイルを使うしかないんだろうか・・・・

  • 以下、考えてみたがダメかな
  • 先に記載の、 Resources -> WSL Integration Ubunts-20.04を有効にする
  • wsl2 Ubuntuから見えるパスを使うようにする
    • 例えば、/mnt/c/usr/aws-tutorial のようなパス(wsl2がホスト側のCドライブのc:\\usr\aws-tutorialをよしなにやってくれる)
  • 参考

  • wsl2経由にすると
    おそらく
    コンテナ -> ホストOS -> Windowsの場所
    というアクセスから
    コンテナ -> WSL2 Ubunts -> WSL2から見たWindowsの場所 に変えればアクセス速度は少しは速くなると想定される(Linux、Ubunts等での通信になり、ホストOSを介さない) 速くならない

  • Windowsからwsl2 Ubuntuへのアクセスは、\\wsl$\Ubuntu-20.04\home\ のようにアクセスできる

    • PowerShellからwsl$ へのアクセス例
    • Windowsから WSL2 Ubunts内のファイルをVSCodeで開く(Ubuntu内で code . コマンド実行で良い) 、左下が「WSL:Ubuntu-20.04」になっていれば開けている

(番外編)docker-composeを使うようにした場合

  • リモートコンテナ利用でdocker-composeを使うように改変したもの、https://github.com/ssugimoto/aws-amplify-sns-workshop-in-vscode/tree/feature/use-docker-compose-forWindows

    • featureブランチに入れてます。forkしていますが、あくまでもサンプルです。
  • Windows向けで試したのみ、Mac,Linuxで動くかは不明です。

  • docker-composeのvolumesで、Windows側の環境変数指定ができず、.aws , .ssh 指定が絶対パスになり個人ごとに依存するため、カレントディレクトリに、aws, ssh のディレクトリを用意し、そのディレクトリをマウントするようにしてみた

  • コンテナが停止してしまうので、command: /bin/sh -c "while sleep 2000; do :; done" で対処した

  • /hostdir をワーキングディレクトリにした、コンテナ内の/workspacesも使える

  • docker コンテナ一覧では、どれなのか非常にわかりやすくなる、こんな感じに

  • amplify と nodeのバージョンアップした後のコンソール