Open7

コンテナ

Tomoki OtaTomoki Ota

devcontainer

codespacesを使ったらより高速に開発できるけど、有料。

https://scrapbox.io/shimizukawa/devcontainerでDocker_in_Docker環境を構築しCodespacesからhttps転送する

simpleなdevcontainer.json

以下はubuntuにgoを入れたときのデフォルトのdevcontainer.jsonである。

devcontainer.json
{
	"name": "Ubuntu",
	"dockerFile": "Dockerfile",
	"image": "mcr.microsoft.com/devcontainers/base:jammy",
	"features": {
		"ghcr.io/devcontainers/features/go:1": {},
	}
}

dockerfile

dockerfileでimageを指定してみる。

Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu
RUN apt-get update

そして、以下のようにimageの行を消してbuildを追加する。

devcontainer.json
{
	"name": "Ubuntu",
	"runArgs": ["--name=ubuntu"],
	"build": {
        "dockerfile": "Dockerfile"
        },
	"features": {
		"ghcr.io/devcontainers/features/go:1": {},
	}
}
Tomoki OtaTomoki Ota

devcontainerでsam環境構築

.devcontainer/devcontainer.json
{
	"name": "Ubuntu",
	"image": "mcr.microsoft.com/devcontainers/base:jammy",
	"features": {
		"ghcr.io/devcontainers/features/aws-cli:1": {
			"version": "latest"
		},
		"ghcr.io/devcontainers/features/go:1": {
			"version": "latest"
		},
		"ghcr.io/customink/codespaces-features/sam-cli:1": {
			"version": "latest"
		}
	}
}

上記のようにすると

$ go version
go version go1.21.4 linux/arm64
$ aws --version
aws-cli/2.14.5 Python/3.11.6 Linux/6.4.16-linuxkit exe/aarch64.ubuntu.22 prompt/off
$ sam --version
rosetta error: failed to open elf at /lib64/ld-linux-x86-64.so.2
 Trace/breakpoint trap

エラーが出た。
samだけx86-64になってる。
devcontainerで提供されているcustominkのsamはアーキテクチャが異なる。公式によると、現在Linuxのarm64のインストールはpipのみなので、Pythonをインストールしてscriptでインストールする。

.devcontainer/devcontainer.json
{
    "name": "sam-expt",
    "dockerComposeFile": "docker-compose.yml",
    "service": "sam-app",
    "workspaceFolder": "/workspace",
    "features": {
		"ghcr.io/devcontainers/features/aws-cli:1": {
			"version": "latest"
		},
		"ghcr.io/devcontainers/features/go:1": {
			"version": "latest"
		},
        "ghcr.io/devcontainers/features/python:1": {
			"version": "latest"
		}
    }
}
docker-compose.yml
version: '3'
services:
  sam-app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ../workspace:/workspace:cached
      - ../.devcontainer:/.devcontainer:cashed
    tty: true # port設定してないので、これがなかったら落ちる
Dockerfile
ARG VARIANT="jammy"
FROM mcr.microsoft.com/vscode/devcontainers/base:${VARIANT}
RUN apt-get update && apt-get install -y vim
terminal
$ uname -m
aarch64
$ go version
go version go1.21.4 linux/arm64
$ aws --version
aws-cli/2.14.5 Python/3.11.6 Linux/6.4.16-linuxkit exe/aarch64.ubuntu.22 prompt/off
$ pip install --upgrade aws-sam-cli
$ sam --version
SAM CLI, version 1.103.0
Tomoki OtaTomoki Ota

docker間でmysql接続

terminal
$ mysql -h mysql -uuser -ppass

goose接続

terminal
$ goose mysql "$DB_USER:$DB_PASS@tcp($DB_HOST)/$DB_TABLE?parseTime=true" status
Tomoki OtaTomoki Ota

Docker ベストプラクティス

image sizeの削減

apt-get install を使用すると、特定のパッケージ マネージャーがデフォルトで推奨パッケージ、依存関係、およびデバッグ パッケージ をインストールしますが、これらはイメージにとって必要ではない、または役に立たない可能性があります。その場合、一部を削減できます。フラグを追加するだけでサイズを変更できる。
— no-install-recommendsをつけるだけ

before
RUN apt-get -y update &&  \
    apt-get install -y python
after
RUN apt-get -y update &&  \ 
    apt-get install --no-install-recommends  \
    -y python

イメージ内に残る可能性のあるキャッシュされたデータを削除する

RUN apt-get -y update && \ 
    apt-get install --no-install-recommends \ 
    -y python && \ 
    rm -rf /var/lib/apt/lists/*

以下コマンドで依存関係と推奨パッケージを確認できる

apt-cache depends (PACKAGE)

RUNコマンド

複数のパッケージをインストールする時はRUNコマンドを使う。
不必要なイメージの追加レイヤーが作成されるのを防ぐことができる。
長い命令や複雑な命令をバックラッシュ () で分割することで、ファイルの読みやすさと保守性を高めることができる。

RUN apt-get -y updater && apt-get install -y \
  ca-certificates \
  coreutils \
  curl \
  openjdk11 \
  tzdata

キャッシュの問題を避けるために、常に apt-get update を使用し、同じコマンドで一緒にインストールする。これはキャッシュバスティングと呼ばれる。

FROM ubuntu:23.10
RUN apt-get update (CACHED)
RUN apt-get install -y curl (CACHED)

Docker best practices. TL: DR | by Fsegredo | Medium

Tomoki OtaTomoki Ota

devcontainer

settings

editor.codeActionsOnSave

ESLint の自動修正を保存時に自動的に適用するための設定

:::message warn
以前はbool値だったが、以下3つの設定値になった。
:::

  • explicit : 保存されたときにアクションを実行、以前のtrueと同じ
  • always : 保存、ウインドウ変更、フォーカス変更時にアクションを実行
  • never : 保存されたときにアクションを実行しない、以前のfalseと同じ
Tomoki OtaTomoki Ota

host.docker.internal

ホスト上で内部の IP アドレスで名前解決できる、特定の DNS 名 host.docker.internal を使用することで、コンテナからホスト上のサービスにアクセスすることができる

localhost

コンテナ内だとlocalhostが0.0.0.0になることがある。
コンテナ上での localhost はコンテナ自身を参照してしまうので、意図した動作はしない。

$ curl http://localhost:3000/v1/health
curl: (7) Failed to connect to localhost port 3000 after 0 ms: Couldn't connect to server
Tomoki OtaTomoki Ota

devcontainerの中でgit(push)とかを使えるようにする。

# devcontainerの中でgitを使えるようにする。
if [ -z "$SSH_AUTH_SOCK" ]; then
   # Check for a currently running instance of the agent
   RUNNING_AGENT="`ps -ax | grep 'ssh-agent -s' | grep -v grep | wc -l | tr -d '[:space:]'`"
   if [ "$RUNNING_AGENT" = "0" ]; then
        # Launch a new instance of the agent
        ssh-agent -s &> $HOME/.ssh/ssh-agent
   fi
   eval `cat $HOME/.ssh/ssh-agent`
fi