PHP Slim 環境構築(3) RedisとMySQLとPostgreSQL

# PHP Slim 環境構築(3) RedisとMySQLとPostgreSQL

## Introduction

[前回](https://qiita.com/dynamitecoolguy/items/2083c8801504bf9f0bfc)は、単純なHello, WorldサイトをSSL化し、Xdebugでデバグ可能にしました。

今回は、よく使用するredisとMySQLとPostgreSQLをDockerに追加してみます。(4)で、実際にslimフレームワークを使ってこれらにアクセスしてみることにします。

## docker-compose

docker-composeファイルに、どーんとRedis, MySQL, PostgreSQL用の記述が追加されます。
それぞれ、portsを指定してホスト側からもアクセスできるようにしていますが、セキュリティ上の懸念がある場合は記述を外してください。
また、volumes:によって、データが永続化されるようにしています。

```yml:/compose/docker-compose.yml
version: '3'

services:
  web_front:
    build:
      context: ./web_front
    links:
      - web_hoge
    ports:
      - "80:3128"
      - "443:8443"
    volumes:
      - ../certs:/etc/certs:ro
    container_name: web_front
    networks:
      - local_net

  web_hoge:
    build:
      context: ./web_hoge
      args:
        - environment=local
    environment:
      XDEBUG_CONFIG: "remote_host=172.17.0.1"
      PHP_IDE_CONFIG: "serverName=hoge.localhost"
    domainname: localhost
    volumes:
      - ../src/hoge:/var/www/hoge
      - ../src/vendor:/var/www/vendor
    container_name: web_hoge
    networks:
      - local_net

  redis:
    build:
      context: ./redis
    volumes:
      - redis-data:/var/lib/redis
    ports:
      - "16379:6379"
    sysctls:
      - net.core.somaxconn=1024
    container_name: redis
    networks:
      - local_net

  mysql:
    build:
      context: ./mysql
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - "13306:3306"
    container_name: mysql
    networks:
      - local_net

  postgresql:
    build:
      context: ./postgresql
    volumes:
      - postgresql-data:/var/lib/postgresql
    ports:
      - "15432:5432"
    container_name: postgresql
    networks:
      - local_net

volumes:
  redis-data:
  mysql-data:
  postgresql-data:

networks:
  local_net:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/24
```

## MySQL

MySQL用のDockerファイルと、初期投入用のSQLを作成します
(MySQLと言いながらMariaDBですが・・)。

```dockerfile:/compose/mysql/Dockerfile
FROM mariadb:10.4.8

ENV MYSQL_ROOT_PASSWORD hogehoge
ENV MYSQL_ROOT_HOST 172.28.0.1

ENV MYSQL_DATABASE userdb
ENV MYSQL_USER scott
ENV MYSQL_PASSWORD tiger

COPY init.d/* /docker-entrypoint-initdb.d/

EXPOSE 3306

CMD ["--sql-mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION", \
 "--skip-character-set-client-handshake", \
 "--default-time-zone=+00:00"]
```

init.dディレクトリ下に拡張子shまたはsqlのファイルを置いておくと、DB初期化時に実行されます。

```sql:/compose/mysql/init.d/00alterdb.sql
alter database default character set utf8mb4;
```

```sql:/compose/mysql/init.d/01createtable.sql
create table player (
  player_id int unsigned not null auto_increment,
  player_name varchar(255) not null,
  constraint player_pk primary key (player_id)
);
```


## PostgreSQL

MySQLと同様にPostgreSQLの設定を作成します。

```dockerfile:/compose/postgresql/Dockerfile
FROM postgres:10.10

ENV POSTGRES_PASSWORD hogehoge
ENV POSTGRES_USER root
ENV POSTGRES_DB logdb

COPY init.d/* /docker-entrypoint-initdb.d/

EXPOSE 5432
```

MySQLと同様に、init.d内にファイルを置くことで、初期化時のコマンド実行が行えます。

```sql:/compose/postgresql/init.d/01createtable.sql
create table if not exists player_created_log (
    player_id int,
    created_at timestamp
);
```


## Redis

Redis用の設定を作成します。

```dockerfile:/compose/redis/Dockerfile
FROM redis:5.0.5

#configuration
COPY redis.conf /usr/local/etc/redis/redis.conf

EXPOSE 6379

#command
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
```

redisの設定ファイルを指定できます。

```conf:/compose/redis/redis.conf
# redis.conf
...(ここに設定を書く)...
```

## 確認

それぞれの動作を確認してみます。docker-compose up -d でそれぞれのコンポーネントを起動します。

### mysql

mysqlクライアントで接続してみます。

```sh
$ sudo apt install mariadb-client  # mysqlクライアント未インストールの場合
$ mysql --user=scott --password=tiger --port=13306 --host=127.0.0.1 --database=userdb
MariaDB [userdb]> select * from player;
Empty set (0.000 sec)
```

(docker volume prune + docker-compose up とかした後には、うまく接続できない場合があるっぽいけどよく分からない・・)


### psql

psqlで接続して確認してみます。

```sh
$ sudo apt install postgresql-client-10   # psql未インストールの場合
$ psql --username=root --port=15432 --host=127.0.0.1 -W logdb
Password for user root:

logdb=# select * from player_created_log;
 player_id | created_at
---------+------------
(0 rows)
```

### redis

redis-cliで接続して確認してみます。

```sh
$ sudo apt install redis-tools    # redis-cli未インストールの場合
$ redis-cli -p 16379
127.0.0.1:16379> get hoge
(nil)
127.0.0.1:16379> set hoge 1
OK
127.0.0.1:16379> get hoge
"1"
127.0.0.1:16379> del hoge
(integer) 1
127.0.0.1:16379> get hoge
(nil)
```

### docker volume初期化

なお、mysql, postgresqlのDB初期化コマンドは初回起動時のみ実行されます。
初期化しなおしたい場合には、volumeを削除すれば良いのですが、以下のコマンドを実行すると安全に削除することができます(削除は自己責任でね!)。

```sh
$ docker-compose down
$ docker volume prune
```

## 変更履歴

- 2019/09/24

MySQLとPostgeSQL側で、"Player"と"User"で用語が一致していなかったので"Player"に統一