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のサービス名のとこをさしてます。
確認
確認方法は簡単です。
- 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を置いています
動画
実際にDockerで実行しているのを上げておきます
個人支援・寄付について
サイトラボでは個人支援・寄付を受けております。ご協力いただける方はお願いいたします。当サイトではビットコインで受け付けております。
- ビットコイン:3LHnADwZwUbic2L45EnVJEykiG6KfbqrwS