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

Docker環境を使っていると公式のイメージを使う事が多いと思います。

  • nginx
  • php-fpm
  • mysql
  • php-apache

等など、沢山の公式イメージがあります。

殆どがDebian系

公式イメージの多くはDebian系をベースイメージにしてます。これはDebian系が軽いため、ちょっとでもDockerイメージを軽くしようと思って起きている事かもしれません。

待って、RedHat系もいるんだ

最近ではアルパインも登場してより軽くなってきました。Dockerは軽さが一つの売りなので軽いことは良いのですが、RedHat系もいるんだよなーと思ったりしております。

コマンドが違う

Debian系とRedHat系はコマンドが違うため、Dockerになってからapt get を覚えるという人もいると思います。DockerならDebian系でもいいじゃん?って思うかもしれませんが、もし本番環境がRedHat系ならどうでしょう?ベースがそもそも違うという事になります。

大まかな点ではRedHat系もDebian系も大きな違いなどはないかもしれませんが、細かい点で拡張機能のインストールの仕方が違うなどは起きたりするかもしれません。例えばAWSを使っている場合はAmazonLinux2023をEC2で使っているけど開発ではDockerでベースイメージがDebian系というのは、考えられます。

それって本当にいいのですか?と思ったりします。

ベースイメージも揃えたい

僕個人としては、RedHat系でサーバーを動かすならDocker出開発するにしてもベースイメージは揃えたいというのが本音でございます。なんとなく本番と開発が違うのは気持ち悪いっていうのもあります。しかし多くはDebian系のベースイメージでDockerなど検索しても多くは公式イメージからダウンロードしてくる方法が多いです。

というわけで勝手に作っていって見たいと思います。

今回作るDocker環境

以下の構成とします

  • ホストOS:AlamaLinux
  • ベースイメージ:AmazonLinux2023
  • WEBサーバー:nginx
  • PHP:php-fpm
  • PHPバージョン:8.2系
  • nginxポート:80
  • php-fpmポート:9000
  • ドキュメントルート:/var/www/html

ベースイメージはRockyでもよいですが、なんとなくAmazonLinux2023にしてみました。やることはあまり変わらないので気が向いたらミドルウェアをアパッチにしたり、ベースイメージをRockLinuxにしたバージョンも展開してみたいと思います。

ただAlamaLinuxやRockyLinuxにする場合は、こんな回りくどいやり方よりもsupervisorを使った方がコンテナも一つですんで良いと思います。

phpinfoを表示する

今回のゴールはブラウザでphpinfoを表示するというのになります。

phpinfoが表示されれば、nfinxとphp-fpmが問題なく連携できていることになります。ドキュメントルートをnginxのデフォルトではなく、アパッチと同じにしたのは普段からこっちを使っていて楽だからという理由になります。nginxのデフォルトが良い場合はパスを書き換えてください。

http://IPアドレス/info.php で見れるのを最終目標とします

なぜポート80にする?

試験用とかなら、ポート番号を8080とかにしてhttp://IPアドレス:8080/info.phpなどにすることも考えられますが、本番を前提に構築するとしたら、本番環境でポート番号をうつというのはあり得ないことなので、今回は80番ポートにしてます。

あくまで本番を想定してとなります。ポート番号のありなしレベルでも初めてやる人とかには結構ハードルが高いので、最初からないようにしたほうが楽です。

前提条件

前提条件としては以下となります

  • vagrant+VirtualBox
  • Dockerインストール済み
  • docker composeインストール済み

docker composeまでインストールが終わっていて起動している前提となります。WSLの環境でも問題ないですが、WSL上だとUbuntuやDebian等になってしまいます。なぜかOracleLinuxがいますが、これは未検証となります。なのでWSLは使っていないと考えてください。

nginx

まずは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を置いています

動画

実際にDockerで実行しているのを上げておきます

個人支援・寄付について

サイトラボでは個人支援・寄付を受けております。ご協力いただける方はお願いいたします。当サイトではビットコインで受け付けております。

  • ビットコイン:3LHnADwZwUbic2L45EnVJEykiG6KfbqrwS