dockerでnginx+php-fpm+PostgreSQLの環境を作ってみる

前回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のサービス名のとこをさしてます。

確認

確認方法は簡単です。

  1. http://IPアドレス/info.php で表示
  2. 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