DamienKarrus’s blog

プログラミングとクライミングの足跡

LAPP on コンテナ on WSL2

WSLを使って開発環境(LAPP)をコンテナで作ってみようと思う。 ホスト側環境は以下の通り

Windows11
WSL2 (Ubuntu-20.04)
Docker (20.10.14)

デバッグの効率性を考えて、PHPのソースはWindows上のフォルダに置き、それをUbuntuが勝手にマウントしてくれるので、そのUbuntuディレクトリをコンテナがbindして使う。

Windows:C:\Users\kakimoto\mpses
 ↓
Ubuntu:/mnt/c/Users/kakimoto/mpses

フォルダ構成

作業フォルダ(mpses)下にDBとウェブアプリ(apache+php)のサブフォルダを作って、イメージはそれぞれの中で作成定義しておき、全体をdocker-composeでコントロールする。

docker-compose.yaml
postgres/
web/

postgres

postgresフォルダ内は

Dockerfile
docker-entrypoint-initdb.d/

Dockerfileは

FROM postgres:14-alpine
ENV LANG ja_JP.utf8

docker-entrypoint-initdb.d には、データベースの初期データを data.out というファイル名でおいておくことにする(後ほどリストアして使用する)。
Postgresのデータはボリュームを作成しておきvolumeマウントして使う。

$ docker volume create --name mps-db-data

web

webフォルダは

Dockerfile
php.ini
apache2.conf
src/

apachephpの設定ファイルはbindして使用する。apacheはlatest、phpは7.4を指定した。srcはwindows上のソースファイルがあるフォルダ。
Dockerfileは

FROM debian
EXPOSE 80
RUN apt-get update
RUN apt-get install -y sudo
RUN apt-get install -y curl ca-certificates gnupg \
&& sudo apt-get install -y build-essential apt-transport-https \
&& sudo apt-get install -y php7.4 php7.4-intl php7.4-mbstring php7.4-pgsql php7.4-fpm php7.4-cli php7.4-zip \
&& sudo apt-get install -y apache2 libapache2-mod-php \
&& sudo apt-get install -y iputils-ping net-tools dnsutils \ ←疎通確認などに使用するツール
&& sudo apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm /var/www/html/index.html
COPY php.ini /usr/local/etc/php/
COPY apache2.conf /etc/apache2/
CMD /usr/sbin/apachectl -DFOREGROUND
STOPSIGNAL SIGWINCH

php.iniは

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

docker-compose

doker-compose.yaml

version: '3'
services:
  web:
    build: ./web
    volumes:
      - ./web/php.ini:/usr/local/etc/php/php.ini
      - ./web/src:/var/www/html
    ports:
      - 8080:80
  db:
    build: ./postgres
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: admin
    volumes:
      - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
      - mps-db-data:/var/lib/postgresql/data
volumes:
  mps-db-data:
    external: true

まずは疎通確認

# ping db
PING db (192.168.160.2) 56(84) bytes of data.
64 bytes from mpses_db_1.mpses_default (192.168.160.2): icmp_seq=1 ttl=64 time=0.081 ms
...(snip)...

では、webコンテナからdbコンテナに対してSQLを発行してみる。次のphpを作ってブラウザでアクセスしてみる。内容はテーブル一覧を表示するというもの。
mpses/web/src/test.php

<?php
        ini_set( 'display_errors' , 'On' );
        $str = "host=db port=5432 dbname=admin user=admin password=admin";
        $db = pg_connect( $str );
        if($db == FALSE):
                echo "DB connection failed DAME";
                exit;
        endif;
        $q = "select schemaname, tablename, tableowner from pg_tables where schemaname not like 'pg_%' and schemaname != 'information_schema'";
        $res = pg_query( $db , $q );
        $rows = pg_num_rows( $res );
        for( $i=0 ; $i<$rows ; $i++ ):
                $e = pg_fetch_array( $res , $i , PGSQL_ASSOC );
                print( "$i: {$e['schemaname']} , {$e['tablename']} , {$e['tableowner']} <br />" );
        endfor;
?>

1行目はエラーが出た場合にメッセージを画面に表示すための指定。 2行目がpg_connect()に渡すパラメータ。今回の接続内容は、

キー パラメータ 説明
host db postgresコンテナのホスト名=docker-compose.yaml内のdbコンテナのサービス名
port 5432 docker-compose.yaml内で指定した外向けport番号
dbname admin db名称:今回は明示的に指定しなかったので、USER名と同じ名称となっている
user admin docker-compose.yaml内で指定したユーザ名
password admin docker-compose.yaml内で指定したパスワード

ここまでで一応、apacheが動き、phpが動き、それぞれの設定ファイルを自由に設定でき、postgresのコンテナを分離でき、データベースクラスタ(物理的記憶領域)を外部のボリュームに逃がしてみることができた。基本的な開発環境としては最低限なところは構築できたと思う。

Windows10 Professionalの場合の構築方法

damienkarrus.hatenablog.com