Docker で PHPRedis を使う

PHP でセッションを管理する Web アプリを制作しているが、セッション情報はサーバーの再起動などで揮発してしまう。そこで、セッション情報を DB で管理する方法として PHPRedis を試してみる。

設定

ディレクトリー構成

1
2
3
4
5
6
7
8
- / 
+- .env
+- docker-compose.yml
+- php
| +- Dockerfile
| +- php.ini
+- src
+- session.php

docker-compose.yml

とりあえず、クライアント側の PHP とセッションサーバーの Redis のコンテナを用意する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
version: "3.0"
services:
php:
build:
context: ./php
volumes:
- "./src:/root/src:rw"
ports:
- "3000:3000/tcp"
redis:
image: redis:alpine3.12
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "${REDIS_PORT}:${REDIS_PORT}"

.env

Redis 関連の設定値を環境変数で持たせる。Redis サーバーのホスト名もここで持たせるべきかも。

1
2
REDIS_PORT=6379
REDIS_PASSWORD=password

php/Dockerfile

(今回のはまりどころ→)PHPRedis のソースがALpine Linux のイメージに含まれていないので、docker-php-ext-install する前に git clone する必要がある。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FROM php:7.2-cli-alpine
ENV COMPOSER_ALLOW_SUPERUSER 1
COPY ./php.ini /usr/local/etc/php/php.ini
WORKDIR /root/src
RUN apk add --update --no-cache tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
echo "Asia/Tokyo" > /etc/timezone && \
apk del tzdata && \
rm -rf /var/cache/apk/*
RUN apk add --update --no-cache \
git \
&& rm -rf /var/cache/apk/*
RUN git clone https://github.com/phpredis/phpredis.git /usr/src/php/ext/redis \
&& docker-php-ext-install redis
EXPOSE 3000
CMD ["php", "-S", "0.0.0.0:3000"]

php/php.ini

セッションの管理方法として Redis を指定する。

1
2
3
4
5
6
7
8
9
10
[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

extension=redis.so
session.save_handler = redis
session.save_path = "tcp://redis:6379?auth=${REDIS_PASSWORD}"

src/session.php

動作確認用にセッション情報を保存するスクリプト。

1
2
3
4
5
6
7
8
<?php
session_start();

echo 'save_handler: ', ini_get('session.save_handler'), PHP_EOL;
echo 'save_path: ' , ini_get('session.save_path'), PHP_EOL;
echo 'session_id: ' , session_id(), PHP_EOL;

$_SESSION['libname'] = "PhpRedis';

確認

まず、現在のセッション管理状態は管理しているセッションがないので、redisの中は空であることが確認する。

1
2
3
4
# apk add redis
# redis-cli -h redis -a ${REDIS_PASSWORD}
redis:6379> keys *
(empty list or set)

次に、実際にセッションの管理を行ってみる。

1
2
3
4
# php /root/src/session.php
save_handler=redis
save_path=tcp://redis:6379?auth=password
session_id=42a33c87fb832e3267d14397xxxxxxxx

セッション情報が Redis に格納されたことを確認する。

1
2
3
# redis-cli -h redis -a ${REDIS_PASSWORD}
redis:6379> keys *
1) "PHPREDIS_SESSION:42a33c87fb832e3267d14397xxxxxxxx"

保存されてるようだ。