dockerでnginx+php-fpm+PostgreSQLの環境を作ってみる
![](https://www.logw.jp/wp-content/uploads/2019/01/logw_title_docker-530x250.png)
前回Docker+php-fpmの環境をAmazonLinux2023で作成しました。そのymlファイルを元にデータベースを追加してみたいと思います。データベースは皆大好きなMySQLではなくPostgreSQLとなります。
今回作るDocker環境
以下の構成とします
- ホストOS:AlamaLinux
- ベースイメージ:AmazonLinux2023
- WEBサーバー:nginx
- PHP:php-fpm
- PHPバージョン:8.2系
- nginxポート:80
- php-fpmポート:9000
- PostgreSQL:15
- phppgadmin:4
- ドキュメントルート:/var/www/html
phpinfoとphppgadminを表示する
今回のゴールはブラウザでphpinfoを表示するのと、phppgadminを表示することになります
phpinfoが表示されれば、nfinxとphp-fpmが問題なく連携できていることになります。ドキュメントルートをnginxのデフォルトではなく、アパッチと同じにしたのは普段からこっちを使っていて楽だからという理由になります。nginxのデフォルトが良い場合はパスを書き換えてください。
http://IPアドレス/info.php で見れるのとhttp://IPアドレス:8000でphppgadminが表示されるのを最終目標とします
※phppgadminはログインまでします
なぜポート80にする?
試験用とかなら、ポート番号を8080とかにしてhttp://IPアドレス:8080/info.phpなどにすることも考えられますが、本番を前提に構築するとしたら、本番環境でポート番号をうつというのはあり得ないことなので、今回は80番ポートにしてます。
あくまで本番を想定してとなります。ポート番号のありなしレベルでも初めてやる人とかには結構ハードルが高いので、最初からないようにしたほうが楽です。
前提条件
前提条件としては以下となります
- vagrant+VirtualBox
- Dockerインストール済み
- docker composeインストール済み
docker composeまでインストールが終わっていて起動している前提となります。WSLの環境でも問題ないですが、WSL上だとUbuntuやDebian等になってしまいます。なぜかOracleLinuxがいますが、これは未検証となります。なのでWSLは使っていないと考えてください。
nginx
nginxとphp-fpmは前回のコードと全く同じになります。
まずはnginxのコンテナを作ります。
構成図
ファイル構成図としては以下のようになります。
docker
│
├nginx
│ ├Dockerfile
│ └default.conf
こんな感じになります。Dockerfileがあるのはnginxのインストールから始めるためになります。
nginx-Dockerfile
中身はこのようになってます
FROM amazonlinux:2023 RUN dnf -y install nginx ;OS起動時に自動起動(サービス起動) CMD ["nginx", "-g", "daemon off;"]
必要なものだけをインストールしてます。default.confで設定は変えたりするのでここではインストールのみにしてます
default.conf
server { listen 80; listen [::]:80; server_name localhost;</p> <pre><code>root /usr/share/nginx/html; index index.html index.htm index.php; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { try_files $uri $uri/ /index.php$is_args$args; index index.html index.htm index.php; } location ~ \.php$ { root /usr/share/nginx/html; fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }</code></pre> <p>}
IPv6対策なのと、phpのサーバーを指定してますここでphp:9000というのはこれからやるphp-fpmの指定をしております。
nginxの指定はこれで終わりになります。次はphp-fpmとなります。
php-fpm
次に行うのはphp-fpmとなります。php-fpmのほうはphp-fpmだけをインストールします。基本的にミドルウェアをインストールしたりはしません。
構成図
ファイル構成図としては以下のようになります。
docker
│
├nginx
│ ├Dockerfile
│ └default.conf
-↑↑↑ここまでは前回作った。↓↓↓ここから-
├php
│ ├Dockerfile
│ └www.conf
phpというフォルダを作り二つのファイルがあります。
Dockerfile-php-fom
今回はベースイメージがAmazonLinux2023なので、Dockerfileから作成をします。
FROM amazonlinux:2023 RUN dnf update -y RUN dnf install -y php php-fpm php-pgsql php-json php-devel php-gd git g++ php-pear libzip libzip-devel php-intl git zip unzip RUN mkdir -p /run/php-fpm COPY ../php/www.conf /etc/php-fpm.d/www.conf RUN chown nginx:nginx /var/lib/php/session ;composerをインストールしておく COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
php-fpm以外にも、もし必要なモジュールがああれば一緒にインストールをします。
ビルドしたときに一緒にwww.conf
を埋め込むようにしておきます。個人的にはymlで送るより埋め込んでおくほうがなぜか確実だなと思って安心します。
php-fpmのフォルダないと起動時にエラーとなるため、ここでは作成をしておきます。phpのsessionフォルダの所有者も一緒に変えておきます。
もしcomposerを使いたい方がいたら、ここで一緒にCOPYコマンドでいれておくと良いです。
起動コマンドがない
気づいた方もいると思いますが、php-fpmのほうには起動コマンドがありません。起動コマンドはymlファイルに記述するのでここでは不要となります。
www.conf
www.conf
の中身はこんな感じです
[www] user = nginx group = nginx listen = 9000 ; or listen = 0.0.0.0:9000 pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 slowlog = /var/log/php-fpm/www-slow.log php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = files php_value[session.save_path] = /var/lib/php/session php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
nginxを所有者とグループにしているのと、外部からのアクセスとかも許可している形になります。ブリッジ接続の場合はこれがないとエラーとなります。
ymlファイルを作成
コンテナ二つ分はできました。最後にymlファイルを書いていきます。
構成図
ファイル構成図としては以下のようになります。
docker
│
├nginx
│ ├Dockerfile
│ └default.conf
├php
│ ├Dockerfile
│ └www.conf
-↑↑↑ここまでは前回作った。↓↓↓ここから-
├share
│ ├index.html
│ └info.php
│
└docker-compose.yml
ymlファイルの中身
実際にファイルの中身を書いていきます
services:
amazonlinux2023:
container_name: "al2023"
build:
context: .
dockerfile: ./nginx/Dockerfile
volumes: #ホストにあるファイルをマウント
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./nginx/log:/var/log/nginx/
- ./share:/var/www/html
tty: true # ← これがないとコンテナにログインできない
ports:
- 80:80 #80ポート
environment:
TZ: Asia/Tokyo
#PHPイメージ。
php:
container_name: "php"
build:
context: .
dockerfile: ./php/Dockerfile
working_dir: /var/www/html
command:
php-fpm -F
volumes:
- ./share:/var/www/html
- ./php/log:/var/log/php-fpm
tty: true
デフォルトネットワーク内でコンテナが見える
DockerではComposeはネットワークが1つ生成され、各コンテナがネットワークに参加した状態となっています。
そのため、以前はlinks
とかをつかってりんくしていたのが、現在は不要となってますlinksを使っている方はlinksを削除するだけで使えるようになります。
ymlでphp-fpmを実行
docker composeでコマンドを実行することができます。これをすることでphp-fpmの稼働ができます。default.confのfastcgi_pass php:9000;
はphpのサービス名のとこをさしてます。
確認
確認方法は簡単です。
- http://IPアドレス/info.php で表示
- docker psコマンドで確認
437d70538e1e local_workspace-amazonlinux2023 "nginx -g 'daemon of…" 3 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp al2023 31bc8dece27b local_workspace-php "php-fpm -F" 3 seconds ago Up 3 seconds php
こんな感じで起動していたら、成功です
shareフォルダにあるファイル
shareフォルダには以下のファイルが置いてあります
- index.html
- info.php
php-fpmを使うとウエルカムページが403エラーとなってしまうため、index.htmlを置いています
データベースを追加する
ここから追記する場所になります。前回の記事ではphpinfoが表示できました。今回はPostgreSQLとphppgadminをインストールしていきます。
なぜPostgreSQL?
MySQLの情報はその辺に沢山あるので、なさそうなこっちにしてみました。
構成図
ファイル構成図としては以下のようになります。
docker
│
├nginx
│ ├Dockerfile
│ └default.conf
├php
│ ├Dockerfile
│ └www.conf
├share
│ ├index.html
│ └info.php
-↑↑↑ここまでは前回作った。↓↓↓ここから-
├postgresql
│ └Dockerfile
└docker-compose.yml
PostgreSQLの情報
PostgreSQLは公式イメージを使います
- バージョン15
- 日本語:UTF-8
Dockerfileの作成
公式で配布されているPostgreSQLでは日本語の利用ができないため、日本語用に一度作る必要があります。
FROM postgres:15 RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \ && localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8 ENV LANG ja_JP.utf8
バージョン15にしているのは、AWSで提供されているバージョンが15までだからになります。DockerのPostgreSQLはja_JP.utf8ロケールをサポートしていません。そこで日本語ロケールを追加してます。これをすることで日本語を使うことができます。
ymlに追記
Dockerファイルを作成したので、ymlに追記したいと思います
#Databaseイメージを取得する。ここではpostgressqlをしようする
postgres:
container_name: "postgres_pta"
build:
dockerfile: ./postgresql/Dockerfile
ports:
- 5432:5432
volumes:
- PGDATA:/var/lib/postgresql/data
environment:
POSTGRES_USER: 'admin'
POSTGRES_PASSWORD: 'admin'
POSTGRES_INITDB_ARGS: "--locale=ja_JP.utf8"
POSTGRES_DB: "postdb"
PGDATA: /var/lib/postgresql/data/pgdata
restart: always
コンテナの名前をpostgres_pta
としてます。日本語UTF-8を使うことができたので、これで完了です。
GUIツールをインストール
MySQLの場合はphpmyadminをインストールしてます。PostgreSQLの場合はphpPgAdminというのがあります。これをymlに追記します
ymlに追記
#phppgadminのコンテナ
pgadmin4:
image: dpage/pgadmin4:8
container_name: "pgadmin4"
ports:
- 8000:80
volumes:
# - pgadmin4_data:/var/lib/pgadmin
- ./postgresql/pgadmin:/var/lib/pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: test@logw.jp
PGADMIN_DEFAULT_PASSWORD: root
hostname: pgadmin4
depends_on:
- postgres
restart: always
volumes:
PGDATA:
バーションは4.8の最新版を使います。ポートは8000番にしているので、IPアドレス:8000で接続できるようになります。
確認画面
起動成功したらpgpPgAdminを表示してログインしてみます
ログイン画面
Dockerの起動が成功するとこのようにログイン画面がでます。ymlの設定ファイルにあるログインアドレスをとパスワードをいれることでログインできるようになります
phpPhAdminでは4.8を使用すると、IDではなくメールアドレスとなります。間違いに注意してください。
ログイン後
ログイン成功すると、このような画面になります。後はDBを選択することで使えるようになります。
個人支援・寄付について
サイトラボでは個人支援・寄付を受けております。ご協力いただける方はお願いいたします。当サイトではビットコインで受け付けております。
- ビットコイン:3LHnADwZwUbic2L45EnVJEykiG6KfbqrwS