Windows に Docker の開発環境を構築する

# Windows に Docker の開発環境を構築する
Windows に Docker の開発環境を構築する場合、通常は「Docker Desktop for Windows」を利用することになると思いますが、一定の条件を満たす場合は有償ライセンスを購入しなければならないようです。

- 公式ページ：https://www.docker.com/ja-jp/pricing/faq/

ただ、調べてみると、Docker Engine 自体が有償化されたということでは無いようですので、「Docker Desktop for Windows」を使わずに、Windows に Docker の開発環境を構築する方法を調べて実践することにしました。

## 今回のゴール
- 筆者の環境（Windows11）に Docker Engine および Docker Compose の開発環境を構築する
- Docker Compose を起動し、PostgreSQL コンテナが起動することを確認する

## 手順
### WSL2 のインストール
1. Ubuntu のインストール
    Docker Engine をインストールする環境として、WSL2（Windows Subsystem for Linux 2）上に Ubuntu 22.04 をインストールします。
    ```shell:PowerShell
    wsl --install -d Ubuntu-22.04
    ```

    下記のように出力されれば成功です。
    ```shell:PowerShell
    インストール中: Ubuntu 22.04 LTS
    Ubuntu 22.04 LTS がインストールされました。
    Ubuntu 22.04 LTS を起動しています...
    Installing, this may take a few minutes...
    Please create a default UNIX user account. The username does not need to match your Windows username.
    For more information visit: https://aka.ms/wslusers
    ```
    <br>

1. ユーザ情報の設定
    Ubuntu のユーザID とパスワードを聞かれますので入力します。
    今回のユーザID は```appuser```とします。
    ```shell:PowerShell
    Enter new UNIX username: appuser
    New password: ****
    Retype new password: ****
    ```

    下記のように出力されれば成功です。
    ```shell:PowerShell
    passwd: password updated successfully
    Installation successful!
    To run a command as administrator (user "root"), use "sudo <command>".
    See "man sudo_root" for details.
    
    Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.153.1-microsoft-standard-WSL2 x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/pro
    
     System information as of Mon Oct  7 01:20:24 JST 2024
    
      System load:  0.94                Processes:             51
      Usage of /:   0.1% of 1006.85GB   Users logged in:       0
      Memory usage: 9%                  IPv4 address for eth0: 172.18.47.243
      Swap usage:   0%
    
    
    This message is shown once a day. To disable it please create the
    /home/appuser/.hushlogin file.
    ```
    <br>

1. Ubuntu を起動
    Windows のアプリから「Ubuntu 22.04.5 LTS」を探して起動します。
    ターミナルが開き、下記のように出力されれば成功です。
    ```shell:WSL2 Ubuntu
    To run a command as administrator (user "root"), use "sudo <command>".
    See "man sudo_root" for details.
    
    appuser@XXXXXXXX:~$
    ```

### Docker Engine および Docker Compose のインストール
1. Docker Engine のインストール
    Ubuntu に Docker Engine をインストールします。
    ```shell:WSL2 Ubuntu
    sudo apt install ca-certificates curl gnupg lsb-release -y
    sudo apt update -y
    sudo apt upgrade -y
    curl --insecure -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    sudo apt update -y
    sudo apt upgrade -y
    sudo apt install docker-ce docker-ce-cli containerd.io -y
    sudo usermod -aG docker $USER
    ```

    下記のように出力されれば成功です。
    ```shell:WSL2 Ubuntu
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    lsb-release is already the newest version (11.1.0ubuntu4).
    lsb-release set to manually installed.
    ～～～～～～～～～～
    Setting up docker-ce (5:27.3.1-1~ubuntu.22.04~jammy) ...
    Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /lib/systemd/system/docker.service.
    Created symlink /etc/systemd/system/sockets.target.wants/docker.socket → /lib/systemd/system/docker.socket.
    Processing triggers for man-db (2.10.2-1) ...
    Processing triggers for libc-bin (2.35-0ubuntu3.8) ...
    ```
    <br>

1. Docker の自動起動設定
    Ubuntu 起動時に、Docker が自動起動するように、```~/.bashrc```ファイルに設定を追記します。
    ```shell:WSL2 Ubuntu
    cat << EOF >> ~/.bashrc
    # Automatically start the Docker service.
    sudo /etc/init.d/docker start
    EOF
    ```
    <br>

1. Docker Compose のインストール
    Ubuntu に Docker Compose をインストールします。
    ```shell:WSL2 Ubuntu
    sudo curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
    sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
    sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
    ```
 
    下記のように出力されれば成功です。
    ```shell:WSL2 Ubuntu
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
      0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
    100 56.8M  100 56.8M    0     0  5678k      0  0:00:10  0:00:10 --:--:-- 4043k
    update-alternatives: using /usr/sbin/iptables-legacy to provide /usr/sbin/iptables (iptables) in manual mode
    update-alternatives: using /usr/sbin/ip6tables-legacy to provide /usr/sbin/ip6tables (ip6tables) in manual mode
    ```
    <br>

1. 起動確認
Docker Engine の起動確認を行います。
    ```shell:WSL2 Ubuntu
    sudo service docker start
    sudo service docker status
    ```

    下記のように出力されれば成功です。
    ```shell:WSL2 Ubuntu
    ● docker.service - Docker Application Container Engine
         Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
         Active: active (running) since Mon 2024-10-07 01:39:12 JST; 19min ago
    TriggeredBy: ● docker.socket
           Docs: https://docs.docker.com
       Main PID: 1707 (dockerd)
          Tasks: 9
         Memory: 23.3M
         CGroup: /system.slice/docker.service
                 └─1707 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
    
    Oct 07 01:39:11 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:11.621541113+09:00" level=info msg="Loading containers: start."
    Oct 07 01:39:11 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:11.982773484+09:00" level=info msg="Loading containers: done."
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001453932+09:00" level=warning msg="WARNING: No blkio throttle.read_bps_device support"
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001510074+09:00" level=warning msg="WARNING: No blkio throttle.write_bps_device support"
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001516351+09:00" level=warning msg="WARNING: No blkio throttle.read_iops_device support"
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001519672+09:00" level=warning msg="WARNING: No blkio throttle.write_iops_device support"
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001534576+09:00" level=info msg="Docker daemon" commit=41ca978 containerd-snapshotter=false storage-driver=overlay2 version=27.3.1
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.001720657+09:00" level=info msg="Daemon has completed initialization"
    Oct 07 01:39:12 XXXXXXXX dockerd[1707]: time="2024-10-07T01:39:12.057976730+09:00" level=info msg="API listen on /run/docker.sock"
    Oct 07 01:39:12 XXXXXXXX systemd[1]: Started Docker Application Container Engine.
    ```

### 動作確認
1. ```docker-compose.yaml```ファイルの作成
    ワークスペースディレクトリを作成し、```docker-compose.yaml```ファイルを作成します。
    ```shell:WSL2 Ubuntu
    cd ~
    mkdir workspace
    cd workspace/
    touch docker-compose.yaml
    ```
    <br>

1. ```docker-compose.yaml```ファイルの修正
    vim で```docker-compose.yaml```ファイルを開きます。
    ```shell:WSL2 Ubuntu
    vim docker-compose.yaml
    ```

    下記を入力して保存します。今回は、PostgreSQL コンテナを起動するものとします。
    ```yaml:docker-compose.yaml
    version: '3'
    services:
    
      ##############################################################################
      # PostgreSQL container
      ##############################################################################
      postgres:
        tty: true
        ports:
          - "5432:5432"
        image: "postgres:13.8-bullseye"
        environment:
          - "POSTGRES_PASSWORD=appuserpw"
        container_name: "postgres"
    ```
    <br>

1. Docker Compose の起動
    Docker Compose を起動します。
    ```shell:WSL2 Ubuntu
    docker-compose up -d
    ```

    下記のように出力されれば成功です。（筆者の環境で発生したエラーへの対応は後述）
    ```shell:WSL2 Ubuntu
    [+] Building 0.0s (0/0)      docker:default
    [+] Running 2/2
     ✔ Network workspace_default  Created     0.0s
     ✔ Container postgres         Started     0.0s
     ```

    下記のエラーが出た場合は、Ubuntu のターミナルを再起動した上でもう一度実施します。
    ```shell:WSL2 Ubuntu
    permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.config-hash%22%3Atrue%2C%22com.docker.compose.project%3Dworkspace%22%3Atrue%7D%7D": dial unix /var/run/docker.sock: connect: permission denied
    ```

    下記のエラーが出た場合は、Docker Engine を再起動した上でもう一度実施します。
    ```shell:WSL2 Ubuntu
    [+] Building 0.0s (0/0)      docker:default
    [+] Running 1/0
     ✘ Network workspace_default  Error     0.0s
    failed to create network workspace_default: Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-02b5175441f5 -j RETURN: iptables: No chain/target/match by that name.
     (exit status 1))
    ```

    再起動コマンドは下記です。
    ```shell:WSL2 Ubuntu
    sudo systemctl restart docker
    ```
    <br>

1. 起動状態確認
    コンテナの起動状態を確認します。
    ```shell:WSL2 Ubuntu
    docker-compose ps -a
    ```

    下記のように出力されれば、コンテナの起動に成功しています。
    ```shell:WSL2 Ubuntu
    NAME       IMAGE                    COMMAND                  SERVICE    CREATED         STATUS         PORTS
    postgres   postgres:13.8-bullseye   "docker-entrypoint.s…"   postgres   4 seconds ago   Up 3 seconds   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp
    ```

## 最後に
今回は PostgreSQL コンテナの起動までですが、Vue.js を使った Webアプリケーションコンテナを起動することにも成功しています。
引き続き、手順をアップしていこうと思います。