尝试使用Docker构建Nginx和PHP-FPM环境
用Docker構建nginx和php-fpm环境,并从Dockerfile启动容器。
操作步骤的序列
-
- 创建docker映像的目录
-
- 准备nginx和php-fpm的配置文件等
-
- 创建Dockerfile
-
- 设置docker网络
-
- 创建和启动nginx和php-fpm容器
-
- 确认与nginx的连接
-
- 确认已导入nginx和php-fpm的文件
- 停止和删除容器
创建docker镜像的目录
首先,准备创建Docker镜像所需的目录。目录名称可以是任意的。此次我们将在nginx和php-fpm之间通过TCP通信,所以我随意给目录取名为php-tcp。
$ mkdir -p ~/works/docker-sample/php-tcp
$ cd ~/works/docker-sample/php-tcp
准备nginx和php-fpm的配置文件。
在创建Docker镜像时,准备必要的配置文件来使nginx和php-fpm能够运行和协同工作。
准备php-fpm的配置文件。
在php-fpm镜像中包含的php.ini-production中使用配置文件。
不要修改此配置文件,而是将附加配置编写为外部文件,并在创建docker镜像时导入,以便php-fpm可以读取。
$ mkdir -p php/settings
$ echo "[PHP]\ndate.timezone = \"Asia/Tokyo\"" > settings/php.ini
$ cat settings/php.ini
[PHP]
date.timezone = "Asia/Tokyo"
并且,还需要准备好用于确认操作的文件。
$ mkdir -p php/src/
$ touch php/src/index.php
$ vim php/src/index.php
$ echo '<?php phpinfo(); ?>' > php/src/index.php
$ cat php/src/index.php
<?php phpinfo(); ?>
准备nginx的配置文件
将与php-fpm的协作所需的配置写入外部文件,并让nginx加载该文件到配置中。在nginx的文档根目录中,当前没有放置任何文件。
$ mkdir -p nginx/settings/
$ touch nginx/settings/default.conf
$ vim nginx/settings/default.conf
$ cat nginx/settings/default.conf
server {
listen 80;
root /usr/share/nginx/html;
location / {
index index.php index.html index.htm;
# php-sample:9000 の php-sample は php-fpm のコンテナ名を指定している
fastcgi_pass php-sample:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
制作 Dockerfile
准备一个包含nginx和php-fpm的Dockerfile。
准备一个用于 php-fpm 的 Dockerfile
$ touch php/Dockerfile
$ vim php/Dockerfile
$ cat php/Dockerfile
FROM php:8.1.4-fpm-alpine
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
COPY php/settings/php.ini /usr/local/etc/php/conf.d/php.ini
COPY src /usr/share/nginx/html
使用 COPY 命令引用的相对路径根目录将变为 Dockerfile 所在的目录。
准备好nginx的Dockerfile。
$ mkdir nginx
$ touch nginx/Dockerfile
$ vim nginx/Dockerfile
$ cat nginx/Dockerfile
FROM nginx:1.21.6-alpine
COPY settings/default.conf /etc/nginx/conf.d/default.conf
目前文件的位置状态
$ pwd
$HOME/works/docker-sample/php-tcp
$ tree
.
├── nginx
│ ├── Dockerfile
│ └── settings
│ └── default.conf
└── php
├── Dockerfile
├── settings
│ └── php.ini
└── src
└── index.php
5 directories, 5 files
Docker的网络配置。
为了实现nginx和php-fpm容器之间以及外部的通信,需要进行网络配置。
$ docker network create --driver bridge sample_nw
使用docker-compose创建和启动容器后,此配置将变得不再需要。(docker-compose命令将自动生成网络)
创建并启动nginx和php-fpm容器
首先,创建一个 Docker 镜像。
$ docker build --no-cache -t php/sample:20220327 php/
$ docker build --no-cache -t nginx/sample:20220327 nginx/
$ docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx/sample 20220327 6ee198feefa2 4 seconds ago 23.4MB
php/sample 20220327 8ab121bef960 3 minutes ago 73.4MB
然后,将先前创建的网络sample_nw绑定到nginx和php-fpm的docker镜像上,并启动。
$ docker run --detach --net=sample_nw --name php-sample php/sample:20220327
6bfa5e297b13777617b8fb70a2e7451139b434851be3ebd077dfbdc32435ffc5
$ docker run --detach --net=sample_nw -p 80:80 --name nginx-sample nginx/sample:20220327
5e5327b192cd3adbc7d3b050086a466d03b73a0d433912300e044869785c5aae
在本地主机的80端口上建立连接并转发到容器的80端口(nginx),用于运行docker run –detach –net=sample_nw -p 80:80 –name nginx-sample nginx/sample:20220327的设置。
确认启动。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e5327b192cd nginx/sample:20220327 "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp nginx-sample
6bfa5e297b13 php/sample:20220327 "docker-php-entrypoi…" 3 minutes ago Up 3 minutes 9000/tcp php-sample
确认与Nginx的连接
可以从命令行和网络浏览器中尝试进行操作确认。
可以通过nginx获取到php-fpm的响应。
$ curl -I -s localhost:80
HTTP/1.1 200 OK
Server: nginx/1.21.6
Date: Sun, 27 Mar 2022 04:30:08 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/8.1.4
用网页浏览器访问本地主机,并确认phpinfo()的执行结果被显示出来。
确认已经被nginx和php-fpm接收的文件。
首先要确认两个容器的 ID。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7eb6af2f944 php-tcp_nginx-sample "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp nginx-sample
def5d6b848a6 php-tcp_php-sample "docker-php-entrypoi…" 3 hours ago Up 3 hours 9000/tcp php-sample
然后,尝试登录到php-fpm容器中。
$ docker exec -i -t def5d6b848a6 /bin/sh
# ls -l /usr/local/etc/php/
total 220
drwxr-xr-x 1 root root 4096 Mar 27 04:12 conf.d
-rw-r--r-- 1 root root 72908 Mar 27 04:12 php.ini
-rw-r--r-- 1 root root 72762 Mar 23 19:57 php.ini-development
-rw-r--r-- 1 root root 72908 Mar 23 19:57 php.ini-production
# head /usr/local/etc/php/php.ini-production
[PHP]
;;;;;;;;;;;;;;;;;;;
; About php.ini ;
;;;;;;;;;;;;;;;;;;;
; PHP's initialization file, generally called php.ini, is responsible for
; configuring many of the aspects of PHP's behavior.
; PHP attempts to find and load this configuration from a number of locations.
; The following is a summary of its search order:
#
# head /usr/local/etc/php/php.ini
[PHP]
;;;;;;;;;;;;;;;;;;;
; About php.ini ;
;;;;;;;;;;;;;;;;;;;
; PHP's initialization file, generally called php.ini, is responsible for
; configuring many of the aspects of PHP's behavior.
; PHP attempts to find and load this configuration from a number of locations.
; The following is a summary of its search order:
# head /usr/local/etc/php/conf.d/php.ini
[PHP]
date.timezone = "Asia/Tokyo"
# exit
$
登录到Nginx容器中。
$ docker exec -i -t b7eb6af2f944 /bin/sh
# ls -l /etc/nginx/
total 36
drwxr-xr-x 1 root root 4096 Mar 27 04:15 conf.d
-rw-r--r-- 1 root root 1077 Jan 25 15:26 fastcgi.conf
-rw-r--r-- 1 root root 1007 Jan 25 15:26 fastcgi_params
-rw-r--r-- 1 root root 5349 Jan 25 15:26 mime.types
lrwxrwxrwx 1 root root 22 Mar 23 17:15 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root 648 Jan 25 15:26 nginx.conf
-rw-r--r-- 1 root root 636 Jan 25 15:26 scgi_params
-rw-r--r-- 1 root root 664 Jan 25 15:26 uwsgi_params
# head /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
# ls -l /etc/nginx/conf.d/
total 4
-rw-r--r-- 1 root root 324 Mar 27 04:51 default.conf
# head /etc/nginx/conf.d/default.conf
server {
listen 80;
root /usr/share/nginx/html;
location / {
index index.php index.html index.htm;
fastcgi_pass php-sample:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# exit
$
确认可以看到已经将在Dockerfile中描述的文件成功导入镜像中。
停止和删除容器。
$ docker stop nginx-sample
nginx-sample
$ docker stop php-sample
php-sample
$ docker rm php-sample
php-sample
$ docker rm nginx-sample
nginx-sample
从Dockerfile创建docker-compose.yaml的内容。