使用Docker搭建PHP环境

看了那么多Docker搭建PHP环境的文章 总想自己也写个弄个练练手 过年的时候终于有空完成了 感谢 白总 指导的 Dockerfile


创建数据卷

为了在本地配置虚拟主机 多项目 设置 建议把Nginx配置文件映射出来 可以使用数据卷的方式

注意:这里是从容器里把目录映射到本机 不是从本机映射到容器 注意这2个的区别

可以使用 命令 docker volume create name 最后的 name 属性随便你定义 自己记得就好了

1
2
[root@localhost]# docker volume create nginx_vol
nginx_vol

使用Dockerfile创建镜像

下面有个压缩包已经写好了 Dockerfile

另外说下 如果你想安装不同版本的PHP只需要更改 Dockerfile 文件中的 FROM alpine:3.8 源的版本就可以了 具体对应是多少可以参考官方的 「PHP-Dockerfile」https://hub.docker.com/_/php 文件 找到对应的文件名即可 上面都有对应的版本

下面创建镜像 执行命令 docker build -t phpenv .

创建容器

docker run --name myphp -d -p 80:80 -v /data/website:/app/www --mount source=nginx_vol,target=/etc/nginx phpenv

注意后面的参数 --mount source=nginx_vol,target=/etc/nginx 其中 source后面是创建的数据卷的名字,target 后面的映射的容器里的目录到主机中

使用 docker ps 可以看到运行中的容器

1
2
3
[root@localhost servers]# docker ps
CONTAINER ID IMAGE CREATED STATUS PORTS NAMES
48f1d2a773ad phpenv About an hour ago Up 44 minutes 0.0.0.0:80->80/tcp, 443/tcp myphp

查看数据卷

1
2
3
4
[root@localhost]# docker volume ls
DRIVER VOLUME NAME
local 194e43a9e1d7d81942179fd1c8acc990604b0639540f800636c47c71eb3f7ac6
local nginx_vol

如果你想查看具体的容器中的数据卷使用可以使用下面的命令

docker inspect container_name 其中 container_name 就是容器名字 比如下面的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost]# docker inspect myphp
"Mounts": [
{
"Type": "volume",
"Name": "nginx_vol",
"Source": "/var/lib/docker/volumes/nginx_vol/_data",
"Destination": "/etc/nginx",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
},
{
"Type": "bind",
"Source": "/data/website/www",
"Destination": "/app/www",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

Mounts 下面就是了 可以看到我们上面创建的数据卷映射到了 /var/lib/docker/volumes/nginx_vol/_data 本机的这个目录下

配置主机

经过上面我们就创建好了一个 php + nginx 的容器了。 不过一般我们做为开发环境的话都是配置的多项目 比如多个虚拟主机配置。

上面已经把容器里的nginx配置映射到了本地docker的数据卷中 根据上面查看的结果 在本机的 /var/lib/docker/volumes/nginx_vol/_data 目录下 然后进入该目录 然后进入 里面的 servers 目录(因为查看 nginx.conf 文件的话你会发现最后他还引入了这个目录下的所有 *.conf 文件) 这里就是我们的虚拟主机配置目录了

1
2
[root@localhost servers]# ls
default.conf

这个 default.conf 文件是Nginx默认的主机配置文件 可以看到他里面只想了根目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
server_name local.docker.show;
root /app/www;
if ($time_iso8601 ~ '^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})') {
set $year $1;
set $month $2;
set $day $3;
}
access_log /app/logs/access-$year-$month-$day.log;
error_log /app/logs/error.log;
# Php files
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php-fpm7.sock;
}
location / {
try_files $uri $uri/ /index.php?$args;
# Cache time
add_header Cache-Control $cacheable_types;
}
}

注意修改 server_name host 把host 改成你想配置的域名即可。这个是默认的根目录 如果你不需要的话也可以改动 root /app/www 这一行 这是设置访问的目录路径的

当我们想新增一个虚拟主机的时候可以复制一份该文件 然后修改 其中的 server_nameroot 属性即可 分别换成对应的自己喜欢域名和访问路径即可

比如我新增一个api项目配置

1
2
3
4
5
6
server {
listen 80;
server_name local.api.show;
root /app/www/api/public;
...
}

自己注意目录就好了

容器里安装php扩展

首先进入执行 执行 更新 apk update 然后

1
# apk add php7-package

如果仓库里有的话他会自动下载安装 没有的话就GG了。大概原理就是安装PHP的时候他其实启动了很多的功能和配置,只是没有扩展文件类似 xx.so 的文件,现在就是把他们都下载下来即可生效 类似这种操作吧…

然后重启fpm或者容器

最后

经过了上面的配置后已经完成了多虚拟主机的配置 然后需要进入到容器中创建日志目录 如果你把本地映射进去的话就不需要操作这一步了

1
2
3
[root@localhost]# docker exec -it myphp sh
[..............]# mkdir -p /app/logs
[..............]# chmod 644 -R /app/logs

这里可能会有问题 如果nginx报错写入不了文件记录改下文件权限和所有者 chmod 644 -R path chown app:app path

查看Nginx的状态的话 可以执行 ps -a | nginx 可以看到nginx的状态 这个很重要 有时候改了配置乱七八糟报错 这里都会有 (这个是在容器里执行的)

最后 退出容器 回到主机中 重启容器使配置生效 docker restart myphp 或者在容器中 执行 nginx -s reload


-------------The End-------------