Chapter 02無料公開

Dockerの導入と各種設定

ArkBig
ArkBig
2022.05.14に更新

Docker便利ですよね。新しいソフトを試すとき、まずコンテナイメージがあるが調べちゃいます。

コンテナ環境としてDockerを利用しています。ホストマシンを汚さない点と可搬性を考えてできるだけコンテナでアプリケーションを起動したいです。
そのインストールと私が行った各種設定を説明していきます。

私の個人開発環境は、メインがMacでColimaをインストールしています。Colimaは内部でMac版WSL2みたいなLimaを使っています。
サブPCはWindows 10 HomeでWSL2にdocker engineをインストールしています。Docker Desktopは使っていません。

また仕事ではWindows 10 Proを開発に使っていますが、社内サービス提供用にUbuntuを扱うこともあります。

本章はarkbig/devbaseリポジトリのutilフォルダと、wsl2フォルダの説明も含まれます。

https://github.com/arkbig/devbase

本章で説明するファイル
📂 devbase/
├── 📂util/
│   ├── 📄colima_startup.sh        # MacのColima起動スクリプト
│   └── 📄docker_update_noproxy.sh # Docker用noproxy設定を環境変数に合わせて更新
└── 📂wsl2/
    ├── 📄:
    ├── 📄wsl_dockerd.bat           # WSL2のdockerd起動スクリプト
    ├── 📄wsl_port_forwarding.bat   # WSL2へのポートフォワーディング例
    ├── 📄wsl_sshd.bat              # ポートフォワーディング例で使うsshd起動スクリプト
    └── 📄:

🍎MacへのDockerインストール

MacでDockerを使うために、Colimaのインストールと起動方法について説明します。

【クリックで展開】Colimaのインストールとスタートアップ登録手順。

Colimaの関連図(私の認識)

Colimaのインストール

公式GitHubに記載の手順でインストールします。
Dockerもホスト上にインストールします。

brew install colima docker

これで、Colimaを起動するとホストのDockerコンテキストがVMに設定され、dockerコマンドがVM側で実行されます。
Colimaがdockerdの起動もしてくれているので、自分で起動しなくても大丈夫です。

Colimaの起動スクリプト

util/colima_startup.sh ※Shift+マウスホイールで横スクロール
#!/usr/bin/env sh
#====================================================================
# begin of 定型文
# このスクリプトを厳格に実行
set -eu
# set -eux
# 環境に影響を受けないようにしておく
umask 0022
# PATH='/usr/bin:/bin'
IFS=$(printf ' \t\n_')
IFS=${IFS%_}
export IFS LC_ALL=C LANG=C PATH
# end of 定型文
#--------------------------------------------------------------------

# variables
: "${COLIMA_CPUS:=8}"
: "${COLIMA_MEMORY:=8}"

# check already start?
result=0
colima status default || result=$?
if [ $result -eq 0 ]; then
  exit
fi

# start colima if stop.
result=0
colima start default --cpu "${COLIMA_CPUS}" --memory "${COLIMA_MEMORY}" || result=$?
if [ $result -eq 0 ]; then
  exit
fi

# force stop and start colima if error.
result=0
limactl stop colima -f
colima start default --cpu "${COLIMA_CPUS}" --memory "${COLIMA_MEMORY}"

このスクリプトを使って起動していないときだけ、colima startをするようにしています。まれに起動失敗することがあるので、limactl stop colima -fで強制終了しています。
ColimaはLimaのラッパー的なアプリケーションのため、このようにlimactlで操作が可能です。

このスクリプトをMac起動時に実行するようOSへ登録します。直接シェルスクリプトの実行方法がわからなかったのでターミナル経由で実行します。

  1. Macの「システム環境設定」

    • ユーザーとグループ > ログイン項目
    • 「ターミナル」を追加
  2. 「ターミナル」起動時に実行されるドットファイルへcolima_startup.shを追記

    • zshならHOME/.zprofileに、bashならHOME/.bash_profileに、下記を追加

      ~/.zprofile
      # 必要に応じて設定
      DEVBASE=your-devbase-dir
      COLIMA_CPUS=8
      COLIMA_MEMORY=8
      # 呼び出し
      ${DEVBASE}/util/colima_startup.sh
      
    • fishなら、$HOME/.config/fish/config.fishに下記を追加

      ~/.config/fish/config.fish
      if status --is-login
          # 必要に応じて設定
          DEVBASE=your-devbase-dir
          COLIMA_CPUS=8
          COLIMA_MEMORY=8
          # 呼び出し
          ${DEVBASE}/util/colima_startup.sh
      end
      
      • 以前はfishを使ってましたが、ワンライナーコマンドを使い始めたら、POSIX非互換はつらいのがわかった。(本書のワンライナー動かないものがある)

環境変数COLIMA_CPUSでVMの使用CPUコア数、COLIMA_MEMORYでVMの使用メモリを指定できます。上記スクリプトだと起動済みなら変更をしないので手動で以下コマンドを実行する。

colima start default --cpu "${COLIMA_CPUS}" --memory "${COLIMA_MEMORY}"

🪟WindowsへのDockerインストール

WindowsでDockerを使うために、WSL2へのインストールと起動方法について説明します。

【クリックで展開】WSL2とdocker-ceのインストールとスタートアップ登録手順。

WSL2の関連図(私の認識)

WSL2のインストール

古いWSL(2じゃない)だとDockerがうまく動きません。WSL2をインストールしましょう。(しばらくハマった)

公式のWSLのインストールの手順に従います。

管理者権限
wsl --install

うまくいかない場合は、公式の以前のバージョンの WSL の手動インストール手順を試してください。

以降の説明はLinuxディストリビューションとしてUbuntu 20.04 LTSを選択した場合の内容になっています。

Dockerのインストール

公式のUbuntu用Docker CEの入手の手順に従います。

コマンドだけ抜き出すと次のようになります。

# 古いバージョンのアンインストール
sudo apt-get remove docker docker-engine docker.io

# Docker CE のインストール
## リポジトリのセットアップ
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
## Docker CE のインストール
sudo apt-get update
sudo apt-get install docker-ce

デーモンの起動bat

wsl2/wsl_dockerd.bat
@echo off
setlocal
call "%~dp0wsl_env.bat"

@echo on
wsl -u root -- service docker start
@if errorlevel 1 wsl -u root -- service docker status
@if errorlevel 1 pause

WindowsホストからWSL2のdockerdを起動するバッチです。これをWindows起動時に実行するようOSへ登録します。
WSL2の場合、ほかにもいくつか起動時に実行したいのでまとめて設定したものを付録 WSL2スタートアップに記載しています。
ざっくり書くと、このbatを呼び出すwsl2/wsl_startup_helper.batを、タスクスケジューラへ最上位の権限で実行するよう登録します。

Composeインストール

docker composeサブコマンドを使えるように、composeプラグインをインストールします。
昔のdocker-composeコマンドではなく、V2のdocker compose(ハイフンなしサブコマンド)です。
(一部の機能がV2でしか動かないです)

https://docs.docker.com/compose/install/

compose Releasesから欲しいプラットフォームを選択してダウンロードし、実行権限を付与します。

インストール先は次のどれかです。

  • 個人環境なら、~/.docker/cli-plugins/docker-compose
  • 全ユーザーなら、
    • 🍎Mac: /usr/local/lib/docker/cli-plugins/docker-compose
    • 🪟WSL2: /usr/local/libexec/docker/cli-plugins/docker-compose
  • システムなら、
    • /usr/lib/docker/cli-plugins/docker-compose
    • /usr/libexec/docker/cli-plugins/docker-compose

全ユーザー向けの/usr/localにインストールでいいでしょう。libかlibexecはすでにdockerフォルダがあるほうを使います。

composeプラグインのインストール ※Shift+マウスホイールで横スクロール
# 2022-04現在の最新
COMPOSE_VERSION=v2.4.1
# インストール先(***どれかコメント解除、$HOMEならsudoを削除***)
## Macならおそらく
# COMPOSE_DEST=/usr/local/lib/docker/cli-plugins
## WSL2ならおそらく
# COMPOSE_DEST=/usr/local/libexec/docker/cli-plugins
# 対象プラットフォーム(***どれかコメント解除***)
## M1 Macなら、
# COMPOSE_PLATFORM=darwin-aarch64
## Intel Macなら、
# COMPOSE_PLATFORM=darwin-x86_64
## WSL2なら、
# COMPOSE_PLATFORM=linux-x86_64
sudo mkdir -p ${COMPOSE_DEST}
sudo curl -L https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-${COMPOSE_PLATFORM} -o ${COMPOSE_DEST}/docker-compose

# 実行権限付与
sudo chmod +x ${COMPOSE_DEST}/docker-compose

Dockerインストール後の作業

Dockerインストール後に行った作業を書いておきます。公式に書いてあるものの抜粋です。

https://docs.docker.jp/config/daemon/daemon.html

https://docs.docker.com/engine/install/linux-postinstall/

日本語だとこちら。

https://matsuand.github.io/docs.docker.jp.onthefly/engine/install/linux-postinstall/

Dockerルートフォルダ変更

Linuxマシンセットアップ時にディスク容量の関係でDockerルートフォルダを変更する必要がありました。
Dockerデーモンの起動引数に--data-rootを指定することで対応します。

以下はLinuxマシン(Ubuntu)での手順です。

  1. Docker停止

    sudo systemctl stop docker.socket
    sudo systemctl stop docker.service
    
  2. デーモンの設定編集
    オリジナル設定が/lib/systemd/system/docker.serviceにありコピー&ペーストして、--data-root=〇〇を追加します。
    sudo systemctl edit docker で設定を編集

    sudo systemctl edit docker ※Shift+マウスホイールで横スクロール
    [Service]
    # Allow reset and override.
    ExecStart=
    ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/mnt/data/docker-root
    

    設定は/etc/systemd/system/docker.service.d/override.confに書かれます。

  3. デーモンの再起動

    sudo systemctl daemon-reload
    sudo systemctl start docker
    

適用できたかはdocker volume inspect <ボリューム名>で実際の場所を確認できます。

プロキシ設定

Linuxマシンがプロキシ下だったので、設定を追加しました。
以下はLinuxマシン(Ubuntu)での手順です。

  • デーモンの設定

    1. Environment=の追記
      sudo systemctl edit docker

      sudo systemctl edit docker
      [Service]
      # 他にも必要ならカンマ,区切りで追加
      Environment='no_proxy=localhost'
      Environment='http_proxy=http://your-proxy:8080'
      # ここではhttpと同じにしているが、もしhttps用があるならそちらを指定
      Environment='https_proxy=http://your-proxy:8080'
      
    2. デーモン再起動

      sudo systemctl daemon-reload
      sudo systemctl restart docker
      
    3. 確認

      docker info | grep Proxy
      
  • コンテナ内用の設定

    1. ~/.docker/config.jsonに設定を書く

      ~/.docker/config.json
      {
        "proxies": {
          "default": {
            "noProxy": "localhost",
            "httpProxy": "http://your-proxy:8080",
            "httpsProxy": "http://your-proxy:8080"
          }
        }
      }
      
  • コンテナビルド中の設定
    デーモンの設定、コンテナ内の設定と面倒なことにコンテナビルド時の設定も必要なんです。

    • docker buildなら--build-argを使用

      docker build \
        --build-arg no_proxy=$no_proxy \
        --build-arg http_proxy=$http_proxy \
        --build-arg https_proxy=$https_proxy \
        ./
      
    • compose.yamlならargsを使用

      services:
        images:
          testapp:
            build:
              context: target/path
              args:
                no_proxy: ${no_proxy-}
                http_proxy: ${http_proxy-}
                https_proxy: ${https_proxy-}
      
  • no_proxy更新スクリプト
    環境変数no_proxyを変更した場合、Docker側の更新も必要です。
    次のスクリプトで上記設定を書き換えます。

    設定したパスが違う場合は適宜変更してください。

https://github.com/arkbig/devbase/blob/main/util/docker_update_noproxy.sh

ルートレスモード

sudoを使わずにdockerを実行するための設定です。

sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker

ログローテーション

コンテナの標準出力はDockerが回収して、docker [compose] logsで表示できます。
コンテナを長時間起動するとログが肥大化するので、ローテート設定します。

  1. ~/.colima/docker/daemon.json(WSL2,Linuxでは/etc/docker/daemon.json)に追記

    daemon.json
    {
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "10m",
        "max-file": "10"
      }
    }
    
  2. デーモン再起動
    Macはcolima stop; colima start、Linuxではsudo systemctl restart docker

ログ設定はコンテナ生成時に行われるのですでに起動済みのコンテナはdocker compose up -d --force-recreateで再生成します。

設定の確認はdocker inspect <コンテナ名> --format "{{.HostConfig.LogConfig}}"で見られます。

ポートフォワーディング

Windowsマシンでの話です。
外部のマシンからWSL2へ通信したい場合は、Windows側でポートフォワーディング設定とファイアウォールの解放が必要です。

例としてsshを載せます。先にsshdを起動しましょう。次のバッチをWindowsで実行します。(wsl_dockerd.bat同様スタートアップに登録しておくといい)

https://github.com/arkbig/devbase/blob/main/wsl2/wsl_sshd.bat

SSHの22番ポートを通すための設定はwsl2/wsl_port_forwarding.batに「22」を渡すことで可能です。

https://github.com/arkbig/devbase/blob/main/wsl2/wsl_port_forwarding.bat

Windowsホスト側で実行
./wsl2/wsl_port_forwarding.bat 22

ポートフォワードの設定はPC再起動でも消えませんが、IPアドレスを変えた時用にスタートアップで実行します。そのため、設定前に古いものを削除しています。
(もし-r or --rmオプションが指定されたら、対象ポート番号の古い設定を削除するだけで終了します)
バッチ中で%DNSMASQ_ADDR%となっている部分は、Dnsmasqの構築とOSへの登録で説明します。
一言で書くとWSL2側のeth0ネットワークインタフェースのIPアドレスです。

✔️本章の作業チェックリスト