takaya030の備忘録

PHP、Laravel、Docker などの話がメインです

WSL2 Ubuntu 22.04 に Docker をインストール

検証環境

Windows11 Home Edition (version 22H2)

D:\>wsl --version
WSL バージョン: 1.2.5.0
カーネル バージョン: 5.15.90.1
WSLg バージョン: 1.0.51
MSRDC バージョン: 1.2.3770
Direct3D バージョン: 1.608.2-61064218
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.1555

# installed ubuntu version
Ubuntu 22.04.2 LTS (Jammy Jellyfish)

古いバージョンのアンインストール

Docker がインストール済みの場合、古いバージョンをアンインストールする

$ sudo apt-get remove docker docker-engine docker.io containerd runc

リポジトリのセットアップ

$ sudo apt-get update -y

$ sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg

$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Docker エンジンのインストール

$ sudo apt-get update -y

$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

ユーザーのグループ追加

sudo なしで docker コマンドが実行できるようにユーザーを docker グループへ追加する

$ sudo gpasswd -a <username> docker

ログアウト後、再ログインすると設定が反映される

config ファイルの作成

$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo touch /etc/systemd/system/docker.service.d/options.conf
$ sudo echo '[Service]' | sudo tee /etc/systemd/system/docker.service.d/options.conf
$ sudo echo 'ExecStart=' | sudo tee --append /etc/systemd/system/docker.service.d/options.conf
$ sudo echo 'ExecStart=/usr/bin/dockerd -H unix://' | sudo tee --append /etc/systemd/system/docker.service.d/options.conf

$ sudo touch /etc/docker/daemon.json
$ sudo echo '{"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}}' | sudo tee /etc/docker/daemon.json
$ sudo chmod 600 /etc/docker/daemon.json

docker デーモンのリスタート

config ファイルを反映させるため docker デーモンをリスタートさせる

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

動作確認

$ docker -v
Docker version 23.0.4, build f480fb1

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:4e83453afed1b4fa1a3500525091dbfca6ce1e66903fd4c01ff015dbcb1ba33e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

$ docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    feb5d9fea6a5   19 months ago   13.3kB

参考サイト

docs.docker.com

takaya030.hatenablog.com

WSL2 Ubuntu 環境を D ドライブに移動

検証環境

Windows11 Home Edition (version 22H2)

D:\>wsl --version
WSL バージョン: 1.2.5.0
カーネル バージョン: 5.15.90.1
WSLg バージョン: 1.0.51
MSRDC バージョン: 1.2.3770
Direct3D バージョン: 1.608.2-61064218
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.1555

インストール済みディストリビューションの確認

wsl -l -v で現在の状態を確認

D:\>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Stopped         2

Stopped になっていない場合 wsl --shutdown で停止する

イメージのエクスポート

D:\>mkdir wsl
D:\>cd wsl
D:\wsl>wsl --export Ubuntu-22.04 ubuntu_2204.tar

移動前環境の削除

D:\>wsl wsl>wsl --unregister Ubuntu-22.04

イメージのインポート

先ほどエクスポートしたイメージをインポートする

D:\wsl>wsl --import Ubuntu-22.04 D:\wsl D:\wsl\ubuntu_2204.tar

正常にインポートできかた確認

D:\wsl>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Stopped         2

ログインユーザーの変更

インポート直後はログインユーザーが root になっているため変更する
PowerShell を起動して以下を入力 ( <username> は任意のユーザー名)

PS C:\> ubuntu2204 config --default-user <username>

動作確認

Ubuntu が起動してログイン可能か確認

D:\>wsl

参考サイト

zenn.dev

zenn.dev

Windows11 に WSL2 Ubuntu 環境構築

検証環境

Windows11 Home Edition (version 22H2)

WSL の有効化

PowerShell を管理者として実行
下記のコマンドを入力

PS C\> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

処理終了後、Windows を再起動

仮想マシンプラットフォームの有効化

チェックを入れて OK を押した後、再起動する

インストール可能なディストリビューション確認

PS C:\> wsl --list --online
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl --install -d <Distro>' を使用してインストールします。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_8_5                        Oracle Linux 8.5
OracleLinux_7_9                        Oracle Linux 7.9
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
openSUSE-Leap-15.4                     openSUSE Leap 15.4
openSUSE-Tumbleweed                    openSUSE Tumbleweed

Ubuntu のインストール

PowerShell を管理者として実行
下記コマンドを入力

PS C\> wsl --set-default-version 2

PS C\> wsl --install -d Ubuntu-22.04

インストール後、Ubuntu 起動時に下記エラーが発生した場合

WslRegisterDistribution failed with error: 0x800701bc

下記コマンドを入力することでエラーが解消する

PS C\> wsl --update

ログインユーザー登録

Ubuntu インストール後、初回起動時にログインユーザーを登録する

PS C:\> wsl --install -d Ubuntu-22.04
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
Enter new UNIX username: takaya030
New password:
Retype new password:
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.2 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage


This message is shown once a day. To disable it please create the
/home/takaya030/.hushlogin file.

/etc/wsl.conf の変更

デフォルトでは Windows のパス設定が PATH に追加されるのでそれを無効化する

/etc/wsl.conf を下記内容に変更する

[boot]
systemd=true

[interop]
appendWindowsPath=false

Ubuntu をログアウト後、PowerShell で下記コマンドを実行して Ubuntu を再起動する

PS C\> wsl --shutdown
PS C\> wsl

参考サイト

memoryclip.uchiida.com

leokun0210.hatenablog.com

minikube + skaffold でGo言語のアプリケーションを動かす

検証環境

Windows11 Home Edition (version 22H2)
VirtualBox 7.0.6
vagrant 2.3.4

# Docker Host OS
ubuntu 22.04.2 LTS

go version go1.20.3 linux/amd64
Docker version 23.0.3, build 3e7cbfd
minikube version: v1.30.1
skaffold v2.3.0

ファイル構成

helloecho フォルダを作成しその中に main.gohellomodules/hander.go を作成する

helloecho
├── hellomodules
│   └── handler.go
└── main.go
// main.go

package main

import (
    "github.com/labstack/echo"
    "github.com/takaya030/helloecho/hellomodules"
)

func main() {
    // Echoのインスタンス作る
    e := echo.New()

    // ルーティング
    e.GET("/hello", handler.MainPage())
    e.GET("/api/hello", handler.ApiHelloGet())

    // サーバー起動
    e.Start(":8080")
}
// hellomodules/handler.go

package handler

import (
    "net/http"

    "github.com/labstack/echo"
)

func MainPage() echo.HandlerFunc {
    return func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello World")
    }
}

func ApiHelloGet() echo.HandlerFunc {
    return func(c echo.Context) error {
        return c.JSON(http.StatusOK, map[string]interface{}{"hello": "world"})
    }
}

Go Modules の初期化

$ cd helloecho
$ go mod init github.com/takaya030/helloecho
$ go mod tidy

成功すると go.modgo.sum が作られる

helloecho
├── go.mod
├── go.sum
├── hellomodules
│   └── handler.go
└── main.go

Dockerfile の作成

下記の内容で Dockerfile を作成する

FROM golang:1.20 as build

WORKDIR /go/src/app
COPY go.mod go.sum /go/src/app/
RUN go mod download

COPY . /go/src/app
RUN go build -o /go/bin/app

FROM gcr.io/distroless/base-debian10
COPY --from=build /go/bin/app /
CMD ["/app"]

マニュフェストの作成

下記の内容で k8s-app.yaml を作成する

apiVersion: v1
kind: Service
metadata:
  name: sample-app
spec:
  selector:
    app: sample-app
  ports:
    - port: 80
      targetPort: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
spec:
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: sample-app
          # ビルドしたコンテナイメージ
          image: sample-app:latest
          imagePullPolicy: Never
          ports:
            - name: http
              containerPort: 8080

Skaffold 定義ファイルの作成

以下のコマンドで定義ファイルのテンプレートを作成

$ skaffold init --force

作成された skaffold.yaml を下記内容に変更
( portForward の設定を追加)

apiVersion: skaffold/v4beta4
kind: Config
metadata:
  name: helloecho
build:
  artifacts:
    - image: sample-app
      docker:
        dockerfile: Dockerfile
manifests:
  rawYaml:
    - k8s-app.yaml
portForward:
- resourceType: service
  resourceName: sample-app
  namespace: default
  port: 80
  address: 0.0.0.0
  localPort: 8080

最終的なファイル構成

helloecho
├── Dockerfile
├── go.mod
├── go.sum
├── hellomodules
│   └── handler.go
├── k8s-app.yaml
├── main.go
└── skaffold.yaml

動作確認

minikube を起動

$ minikube start --listen-address=0.0.0.0

dockerminikubeリポジトリを使用するように変更

$ eval $(minikube -p minikube docker-env)

helloecho フォルダに移動後、 skaffold dev を実行

$ cd helloecho
$ skaffold dev --port-forward

エラーが無ければ以下のように web サーバーが起動する

Starting deploy...
 - service/sample-app created
 - deployment.apps/sample-app created
Waiting for deployments to stabilize...
 - deployment/sample-app is ready.
Deployments stabilized in 3.224 seconds
Port forwarding service/sample-app in namespace default, remote port 80 -> http://0.0.0.0:8080
Listing files to watch...
 - sample-app
Press Ctrl+C to exit
Watching for changes...
[sample-app]
[sample-app]    ____    __
[sample-app]   / __/___/ /  ___
[sample-app]  / _// __/ _ \/ _ \
[sample-app] /___/\__/_//_/\___/ v3.3.10-dev
[sample-app] High performance, minimalist Go web framework
[sample-app] https://echo.labstack.com
[sample-app] ____________________________________O/_______
[sample-app]                                     O\
[sample-app] ⇨ http server started on [::]:8080

http://[minikubeのホスト]:8080/helloGET して Hello World が返れば成功

$ curl http://192.168.33.10:8080/hello
Hello World

このままの状態で hellomodules/handler.go を下記内容に変更

--- a/handler.go  2023-04-15 13:51:14.986453215 +0000
+++ b/handler.go  2023-04-15 13:52:29.530453215 +0000
@@ -8,7 +8,7 @@

 func MainPage() echo.HandlerFunc {
        return func(c echo.Context) error {
-               return c.String(http.StatusOK, "Hello World")
+               return c.String(http.StatusOK, "Hello Echo")
        }
 }

変更を保存すると自動でビルドが実行される

Generating tags...
 - sample-app -> sample-app:latest
Some taggers failed. Rerun with -vdebug for errors.
Checking cache...
 - sample-app: Not found. Building
Starting build...
Found [minikube] context, using local docker daemon.
Building [sample-app]...
Target platforms: [linux/amd64]
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile:
#1 transferring dockerfile: 32B 0.0s done
#1 DONE 0.1s

#2 [internal] load .dockerignore
#2 transferring context: 2B 0.0s done
#2 DONE 0.1s

#3 [internal] load metadata for gcr.io/distroless/base-debian10:latest
#3 DONE 0.0s

#4 [internal] load metadata for docker.io/library/golang:1.20
#4 DONE 0.0s

#5 [build 1/6] FROM docker.io/library/golang:1.20
#5 DONE 0.0s

#6 [stage-1 1/2] FROM gcr.io/distroless/base-debian10
#6 DONE 0.0s

#7 [internal] load build context
#7 transferring context: 610B 0.0s done
#7 DONE 0.1s

#8 [build 3/6] COPY go.mod go.sum /go/src/app/
#8 CACHED

#9 [build 2/6] WORKDIR /go/src/app
#9 CACHED

#10 [build 4/6] RUN go mod download
#10 CACHED

#11 [build 5/6] COPY . /go/src/app
#11 DONE 0.3s

#12 [build 6/6] RUN go build -o /go/bin/app
#12 DONE 30.3s

#6 [stage-1 1/2] FROM gcr.io/distroless/base-debian10
#6 CACHED

#13 [stage-1 2/2] COPY --from=build /go/bin/app /
#13 DONE 0.2s

#14 exporting to image
#14 exporting layers
#14 exporting layers 0.2s done
#14 writing image sha256:d01915d4980a60dfd909d4b7403ea1c41146f29e0a2841547fa2f4a4177886f2 done
#14 naming to docker.io/library/sample-app:latest done
#14 DONE 0.2s
Build [sample-app] succeeded
Tags used in deployment:
 - sample-app -> sample-app:d01915d4980a60dfd909d4b7403ea1c41146f29e0a2841547fa2f4a4177886f2
Starting deploy...
 - deployment.apps/sample-app configured
Waiting for deployments to stabilize...
 - deployment/sample-app is ready.
Deployments stabilized in 3.289 seconds
Port forwarding service/sample-app in namespace default, remote port 80 -> http://0.0.0.0:8080
Watching for changes...

ビルド終了後再度 http://[minikubeのホスト]:8080/helloGET すると変更が反映されている

$ curl http://192.168.33.10:8080/hello
Hello Echo

終了処理

Ctrl + Cskaffold を停止

minikube を停止

$ minikube stop

dockerリポジトリの向き先を戻す

$ eval $(minikube docker-env -u)

参考サイト

qiita.com

zenn.dev

developer.mamezou-tech.com

developer.mamezou-tech.com

skaffold.dev

ubuntu 22.04 にGo言語をインストールする

検証環境

Windows11 Home Edition (version 22H2)
VirtualBox 7.0.6
vagrant 2.3.4

# Guest OS
ubuntu 22.04.2 LTS

golang のダウンロード

$ curl -LO https://go.dev/dl/go1.20.3.linux-amd64.tar.gz

golang のインストール

$ sudo rm -rf /usr/local/go
$ sudo tar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz

GOPATH のフォルダ作成

$HOME/go フォルダを作成する

$ mkdir $HOME/go

環境変数の設定

$HOME/.bashrc の末尾に下記を追加する

export GOPATH=$HOME/go
export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin

$HOME/.bashrc の変更を反映

$ source $HOME/.bashrc

動作確認

go version でバージョン番号が表示されるか確認

$ go version

go version go1.20.3 linux/amd64

参考サイト

go.dev

tech.librastudio.co.jp

gcloud で minikube をインストールする

ubuntu に gcloud で minikube をインストールする手順メモ
gcloud SDK と docker はインストール済みの想定

検証環境

Windows11 Home Edition (version 22H2)
VirtualBox 7.0.6
vagrant 2.3.4

# Docker Host OS
ubuntu 22.04.1 LTS

Docker version 20.10.21, build baeda1f
Google Cloud SDK 425.0.0

kubectl , minikube のインストール

$ gcloud components install kubectl
$ gcloud components install minikube

minikube の config 設定

$ minikube config set driver docker
$ minikube config set memory 2500

minikube の起動

$ minikube start

クラスターが作成された後、ノード確認

$ kubectl get nodes

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   80s   v1.26.1

minikube の動作確認

テスト用のマニュフェストを作成

k8s-nginx-deployment.yaml

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

k8s-nginx-service.yaml

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  name: my-lb
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer
status:
  loadBalancer: {}

リソースを作成

$ kubectl apply -f k8s-nginx-deployment.yaml
$ kubectl apply -f k8s-nginx-service.yaml

リソースの確認

$ kubectl get pods

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-85996f8dbd-hmznb   1/1     Running   0          11m
nginx-deployment-85996f8dbd-zwbnh   1/1     Running   0          11m

$ kubectl get deployments

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           11m

$ kubectl get services

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP      10.96.0.1       <none>        443/TCP          1h50m
my-lb        LoadBalancer   10.105.114.49   <pending>     8080:31196/TCP   11m

ブラウザでのアクセス

Windows からアクセスできるようにポートフォワードする

$ kubectl port-forward service/my-lb 8888:8080 --address=0.0.0.0
Forwarding from 0.0.0.0:8888 -> 80

ブラウザで http://192.168.33.10:8888 を開いて以下の画面が表示されるか確認
( 192.168.33.10minikube が動作している ubuntu の IP アドレス)

リソースの削除

$ kubectl delete -f k8s-nginx-service.yaml
$ kubectl delete -f k8s-nginx-deployment.yaml

minikube の終了

$ minikube stop

VirtualBox + Vagrant で構築した Docker 環境で動作している Laravel Sail の Xdebug の設定について

vagrant を使って VirtualBox に構築した Linux VM 上の Docker で Laravel Sail を動作させているときの Xdebug 設定の備忘録

検証環境

Windows10 Home Edition (version 22H2)
VirtualBox 6.1.40
vagrant 2.3.4

# Docker Host OS
ubuntu 22.04.1 LTS

Docker version 20.10.21, build baeda1f

発生した問題について

上記 Docker 環境で動作している Laravel Sail に WindowsVSCode から Dev Container でアタッチしてデバッグしようとしたところ、ブレークポイントを設定しても停止しなかった
調査したところ xdebug.client_host が不正だったため VSCodeXdebug からの通知が届いていなかったことが原因と判明した

xdebug.client_host の設定値ついて

xdebug.client_host には Xdebug クライアント (今回は WindowsVSCode) の IP アドレスを設定する必要がある
WSL2 では自動的に host-gateway に設定されるが VirtualBox ではそのような変数はないため明示的に指定する

コンテナから Windows へのアクセス

コンテナから Windows へのアクセスはデフォルトルートを通じて行うことが可能
デフォルトルートは ubuntu 上で ip r と入力することで確認できる

$ ip r
default via 10.0.2.2 dev enp0s3 proto dhcp src 10.0.2.15 metric 100
10.0.2.0/24 dev enp0s3 proto kernel scope link src 10.0.2.15 metric 100
10.0.2.2 dev enp0s3 proto dhcp scope link src 10.0.2.15 metric 100
10.0.2.3 dev enp0s3 proto dhcp scope link src 10.0.2.15 metric 100
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/16 dev br-3c28ac761546 proto kernel scope link src 172.18.0.1 linkdown
172.19.0.0/16 dev br-95a8cdd8ea38 proto kernel scope link src 172.19.0.1
192.168.33.0/24 dev enp0s8 proto kernel scope link src 192.168.33.10

1行目の default がデフォルトルートで、この場合 IP アドレス 10.0.2.2 を使って Windows へアクセス可能となる

Laravel Sail の Xdebug 設定

.env に下記内容を追加する
.env

SAIL_XDEBUG_MODE=develop,debug
SAIL_XDEBUG_CONFIG="client_host=10.0.2.2"

devcontainer.json に下記内容を追加する
.devcontainer/devcontainer.json

         "forwardPorts": [
                9003
         ]

.vscode フォルダに launch.json を作成する
.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "stopOnEntry": true,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}"
            }
        }
    ]
}

コンテナイメージを再構築する

$ ./vendor/bin/sail build --no-cache

動作確認

コンテナを起動する

$ ./vendor/bin/sail up -d

VSCodeRemote SSHubuntu に接続した後、 Dev Container でコンテナにアタッチする

PHP Debug拡張機能をインストールする

Chrome でテストする場合は Xdebug helper エクステンションをインストールする

停止させたい箇所にブレイクポインタを設定する

デバッグ実行開始

Chromeデバッグ対象の URL を開く

Xdebug helper エクステンションのアイコンをクリックして Debug を選択

再度 URL を開くとブレイクポインタで停止することを確認する

参考サイト

readouble.com

xdebug.org

chrome.google.com