nginx、php-fpm 与 docker

7

看完 docker 官方教程,想搭个本地 php 开发环境,可搜了一圈,也没找到特别满意的文章,顺手总结一个。

假设

  • 你知道 nginx、php-fpm 是什么
  • 你了解 docker 的基本命令

运行环境

MacBook Pro,OSX 10.11.5

启动 php-fpm

解释执行 php 需要 php-fpm,先让它运行起来:

docker run --name dream-php -d \
    -v ~/Workspace/tmp/www:/var/www/html:ro \
    php:7.1-fpm

说明:

  • dream-php 是容器的名字。
  • ~/Workspace/tmp/www 是本地 php 文件的存储目录,/var/www/html 是容器内 php 文件的存储目录,ro 表示只读。

编辑 nginx 配置文件

本地存储路径:

~/Workspace/tmp/docker/nginx/conf.d/default.conf

配置文件内容:

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;
        include        fastcgi_params;
    }
}

说明:

  • php:9000 表示 php-fpm 服务的 URL,下文还会提及。
  • /var/www/html 是 dream-php 中 php 文件的存储路径,经 docker 映射,变成本地路径 ~/Workspace/tmp/www(可以再看一眼 php-fpm 启动命令)

启动 nginx

docker run --name dream-nginx -p 80:80 -d \
    -v ~/Workspace/tmp/www:/usr/share/nginx/html:ro \
    -v ~/Workspace/tmp/docker/nginx/conf.d:/etc/nginx/conf.d:ro \
    --link dream-php:php \
    nginx

说明:

  • -p 80:80 用于添加端口映射,把 dream-nginx 中的 80 端口暴露出来。
  • ~/Workspace/tmp/www 是本地 html 文件的存储目录,/usr/share/nginx/html 是容器内 html 文件的存储目录。
  • ~/Workspace/tmp/docker/nginx/conf.d 是本地 nginx 配置文件的存储目录,/etc/nginx/conf.d 是容器内 nginx 配置文件的存储目录。
  • --link dream-php:php 把 dream-php 的网络并入 dream-nginx,并通过修改 dream-nginx 的 /etc/hosts,把域名 php 映射成 127.0.0.1,让 nginx 通过 php:9000 访问 php-fpm。

测试结果

在 ~/Workspace/tmp/www 下放两个文件:

index.html

<html><body><h1>Hello World</h1></body></html>

phpinfo.php

<?php phpinfo();

接下来看结果吧:

如果看到 Hello World 和熟悉的 phpinfo,那么大功告成。

访问 index.html 时,nginx 读的是 /usr/share/nginx/html/index.html,这个路径经 dream.nginx 转换变成本地的 ~/Workspace/tmp/www/index.html。

访问 phpinfo.php 时,nginx 让 php-frm 执行 /var/www/html/phpinfo.php,这个路径经 dream.php 转换成 ~/Workspace/tmp/www/phpinfo.php。

FAQ

怎样观察容器内文件系统:

docker exec -it dream-nginx bash

你可能感兴趣的

15 条评论
khs1994 · 2016-10-09

请问你设置了php-fpm的配置文件了吗,listen.allowed这里不设置,貌似也报错

回复

edwingeng 作者 · 2016-10-10

php-fpm 用的默认配置。我在苹果笔记本上运行的,没碰到其它问题

回复

jetlag · 2016-10-15

你好,我按照你的教程去部署后访问ip会显示No input file specified. 请问这是为什么呢?

回复

0

nginx配置文件的各location的root请改为/var/www/html

Aceslup · 2017-04-14
edwingeng 作者 · 2016-10-16

可以参考这个帖子:https://blog.gesha.net/archiv...

回复

jetlag · 2016-10-16

我很疑惑,nginx的拥有者已经改为www-data,php默认是,宿主机的web目录也是,也具有755权限,路径也对,不对就会显示file no found,也排除了文章的另外几个因素,但就是不行。我之前尝试过在宿主机部署nginx,在docker容器部署php,还是会出现这样的问题。在网上找的都是雷同的解决方法,不起作用。https://segmentfault.com/q/10...

回复

0

应该是读取不到index.php吧?

Aceslup · 2017-04-14
edwingeng 作者 · 2016-10-16

你先确认这两件事:1)执行 docker exec -it dream.php bash,到 php 存放目录看看,如果看不到你的文件,目录映射多半有问题;2)确认 fastcgi_param 设置的路径,先配成绝对路径(如上文)试试。

回复

jetlag · 2016-10-16

映射没问题,在容器里ls命令可以看到宿主机web目录的文件;我一开始就已经将fastcgi_param的设置路径设置为文章上面的绝对路径,另外,加个root改为$document_root$···得到也是相同的结果。

回复

edwingeng 作者 · 2016-10-17

你再这样试试,在 nginx 配置文件里加上:

location ~ \.php$ {
    return 200 /var/www/html/$fastcgi_script_name;
}

访问 php 文件时,nginx 会返回 php 文件的实际路径,如果这个路径在 dream.php 里真实存在,那问题多半出在访问权限上了。

回复

jetlag · 2016-10-17

刷新变成下载一个文件了,打开文件只有/var/www/html/index.php这句话。

回复

edwingeng 作者 · 2016-10-17

嗯,进入容器 dream.php(也就是 php-fpm),只要能打开 /var/www/html/index.php,那就说明目录映射、nginx fastcgi_param 配置都没问题。

回复

jetlag · 2016-10-17

那为什么还是会出现No input file specified.这问题的呢?我实在是找不出到底是哪里出现问题了,权限也对呀,拥有者也相同,会是系统问题吗?我的宿主机是是阿里云的debian8系统

回复

0

index参数请加上index.php

Aceslup · 2017-04-14
edwingeng 作者 · 2016-10-17

这两处都对,我也没法简单猜测哪出问题了。也许你可以试着换个环境,或者弄个虚拟机,弄一遍没问题的,再对比着找现在的问题。

回复

载入中...