一、前言
为什么要用docker构建,直接在主机上装一个nginx和一个php不就行了吗。
其实如果是单机应用,这样做自然可以。但是我们后面用到的基本都会做负载均衡,包括Nginx、PHP、MySQL、RabbitMQ、Consul、Keepalived、Haproxy等等。
甚至于说多个Nginx、多个PHP可能安装在不同的主机上,这样为了保证环境的一致,且高效快速安装,使用docker镜像无疑是最好的选择。
当然,我们也可以通过dockerfile构建镜像,或者通过docker-compose编排一组服务,不过这里我们为的就是速度,因此我们直接使用已经构建好的镜像。
二、准备工作
1、拉取Nginx镜像
docker pull haveyb/nginx
docker tag haveyb/nginx nginx1.21
docker rmi haveyb/nginx
2、拉取PHP镜像
docker pull haveyb/php
docker tag haveyb/php:latest php7.4:latest
docker rmi haveyb/php:latest
3、创建网络,用于nginx容器和php容器的网络连接
docker network create --driver bridge haveyb
当然,直接通过ip地址连接也可行,但是既然使用了docker,还是追求灵活,ip可能会变,但容器名称不会变。
4、添加测试站点的hosts解析
sudo vi /etc/hosts
127.0.0.1 test.cn
因为这里直接把macbook作为docker容器的宿主机,所以我们这里的ip填写的就是127.0.0.1 test.cn
如果nginx容器并不是直接在mac上,而是在mac的虚拟机上的linux环境,我们这里添加的记录就应该填写为 容器所在虚拟机的ip,举例192.168.78.200 test.cn
三、构建PHP环境
1、创建PHP容器
docker run -itd --name php74 --privileged -p 9000:9000 -v /Users/SH-Server:/data php7.4
2、将PHP容器加入我们创建的网络
docker network connect haveyb php74
3、创建测试文件index.php
# 这里进入的是宿主机目录,因为已经做宿主机和容器的目录映射了,在这里编辑就相当于在容器内的/data目录下编辑
cd /Users/SH-Server
vi index.php
<?php
phpinfo();
wq保存成功后,通过exit命令退出容器,返回宿主机
四、构建Nginx环境
1、创建Nginx容器
docker run -itd --name nginx1.21 --privileged -p 80:80 -p 443:443 nginx1.21
说明:这里本来是想将nginx的conf通过-v映射到Mac上的目录的,但是不论是用直接目录映射还是数据卷挂载都不行,其中有nginx的问题,也有Mac自身的问题,因为在Linux环境虽然不能直接通过目录映射,但是是可以通过数据卷挂载方式来映射的,但是Mac上这两种方式都不行,所以只能进入容器内部来修改了,这种无法进行目录映射的情况当前仅出现在nginx镜像上,当然也有方式解决,就是把Mac上映射目录和Nginx容器内的映射目录的用户名和用户组都改为一模一样,但我懒( ̄▽ ̄)~*
2、将Nginx容器加入我们创建的网络里
docker network connect haveyb nginx1.21
3、编写Nginx配置文件nginx.conf
docker exec -it nginx1.21 bash
cd /etc/nginx
vi nginx.conf
worker_processes 4;
error_log logs/error.log error;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name localhost;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ /\.ht {
deny all;
}
}
include /etc/nginx/conf.d/*.conf;
}
4、创建conf.d目录及测试站点配置文件
mkdir -p /etc/nginx/conf.d
cd /etc/nginx/conf.d
vi test.conf
server {
listen 80;
server_name test.cn;
client_max_body_size 128M;
error_log logs/error.log warn;
charset utf-8;
root /data;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ ^/assets/.*\.php$ {
deny all;
}
location ~ \.php$ {
fastcgi_pass php74:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
这里有一个点要注意,如果是php文件,因为其处理已经被php接管了,所以其读取的文件目录就是php容器的/data目录;如果不是php文件,则读取的是nginx容器的/data目录。
当然,实际生产环境,这两个目录读取的一定是一个项目目录,但测试部署调试时这块如果不注意,可能就会忽略掉。
5、重启Nginx容器,以加载配置
docker restart nginx1.21
五、查看结果
在电脑访问 test.cn
六、php.ini 在哪里
# /usr/local/etc 目录
|-- pear.conf
|-- php
| |-- conf.d
| | |-- docker-php-ext-sodium.ini
| | |-- extension-gd.ini
| | |-- extension-igbinary.ini
| | |-- extension-memcached.ini
| | |-- extension-mongodb.ini
| | |-- extension-msgpack.ini
| | |-- extension-redis.ini
| | |-- extension-sockets.ini
| | |-- extension-swoole.ini
| | |-- extension-yar.ini
| | |-- extension-zip.ini
| | `-- extension-zstd.ini
| |-- php.ini-development
| `-- php.ini-production
|-- php-fpm.conf
|-- php-fpm.conf.default
`-- php-fpm.d
|-- docker.conf
|-- www.conf
|-- www.conf.default
`-- zz-docker.conf
可以看到,其实通过docker拉取的php镜像,默认是不带php.ini这个文件的,但用源码编译其实本身也是不带的,都是后面我们人为地通过 cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
来创建一个php.ini文件。之后我们进行的相关配置都可以在php.ini中进行添加修改,php会自动加载该php.ini文件。
但是需要说明的是为了添加及修改PHP扩展操作起来方便及清晰,后添加的PHP扩展一般不写在php.ini文件里,而是写在了/usr/local/etc/php/conf.d目录下。当然,写在php.ini文件里也是可以的。
七、注意-如果报错:
如果报502,极大概率是nginx和php网络通信问题,我们可以尝试将nginx配置文件中的fastcgi_pass 由原来的通过容器名指定改为通过ip指定。
fastcgi_pass php74:9000;
改为:
# 这里的192.168.78.200是我的虚拟机的网络ip,如果直接在mac上创建的容器,一般不会出现该问题。
fastcgi_pass 192.168.78.200:9000;
另外,也可能是防火墙的问题,或者尝试将虚拟机中的docker重启 systemctl restart docker