苹果Mac下搭建PHP与Nginx的开发环境

记录一下mac搭建php环境的步骤,支持多站点不同PHP版本,终端切换PHP版本

首先介绍一下本文所依赖的目录

站点存放目录

/Users/iuu/Sites/

目录结构如下

Sites
├── php74.test.com # php7.4环境网站
│   ├── 404.html
│   ├── 50x.html
│   ├── index.html
│   ├── index.php
│   └── log # 网站日志存放目录
│       ├── access.log
│       └── error.log
└── php82.test.com  # php8.2环境网站
    ├── 404.html
    ├── 50x.html
    ├── index.html
    ├── index.php
    └── log # 网站日志存放目录
        ├── access.log
        └── error.log

brew services 常用命令

# 启动
 brew services start  xx
# 停止
 brew services stop  xx
 # 状态
 brew services info  xx
 # 服务列表
 brew services list

网站目录配置

在站点目录创建站点文件夹

/Users/iuu/Sites/php70.test.com

在站点目录创建站点日志文件夹

/Users/iuu/Sites/php70.test.com/log/

php安装与配置

添加 shivammathur/php 仓库源

github https://github.com/shivammathur/homebrew-php

brew tap shivammathur/php

搜索可安装的 PHP 版本

brew search shivammathur/php

比如你要这些 PHP 版本就这样操作:

brew install shivammathur/php/php@8.1
brew install shivammathur/php/php@8.2
brew install shivammathur/php/php@8.3

查看php安装信息:

brew info php@7.4

php安装目录为:

/opt/homebrew/opt/php@你的版本/

php-fpm 配置文件为:

/opt/homebrew/etc/php/你的版本/

配置php-fpm:

# 修改/opt/homebrew/etc/php/你的版本/php-fpm.conf 中 error_log 配置:
error_log = log/php-fpm-82.log

# 修改/opt/homebrew/etc/php/你的版本/php-fpm.d/www.conf  中 user 配置:
 user = _www
 group = _www
# 改为:
; eg ; user = _www
; eg ; group = _www
# 修改同文件中的 listen  这里端口我为了统一PHP版本我改的是 90[PHP版本]
listen = 127.0.0.1:9082

php-fpm的启动与停止

# 启动
brew services start shivammathur/php/php@8.2
# 停止
brew services stop shivammathur/php/php@8.2 
# 状态
brew services info shivammathur/php/php@8.2 

终端切换php版本

# 8.2 切 8.3
 brew unlink php 
 brew link --overwrite --force shivammathur/php/php@8.3
# 8.3 切 8.2
  brew unlink php 
  brew link --overwrite --force shivammathur/php/php@8.2
  brew unlink php@8.2 && brew link --force php@8.2
# 8.2切 7.4
 brew unlink php@8.2
 brew link --overwrite --force shivammathur/php/php@7.4 
# 7.4 切 8.3
 brew unlink php@7.4   
 brew link --overwrite --force shivammathur/php/php@8.3

nginx安装与配置

安装 nginx :

brew install nginx 

安装完nginx后 查看配置文件信息:

brew info nginx

默认 nginx 站点目录为 :

/opt/homebrew/var/www

默认nginx 端口与配置文件为:

8080
/opt/homebrew/etc/nginx/nginx.conf 

默认nginx会加载该目录的所有配置文件:
(注意为了统一网站配置文件以后新建站点,站点的配置文件我都放在这里了)

/opt/homebrew/etc/nginx/servers/

贴一下我的nginx 主配置文件

# /opt/homebrew/etc/nginx/nginx.conf 

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       8080;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.php index.html index.htm;
        }

        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
           try_files $uri =404;
           root           html;
           fastcgi_pass   127.0.0.1:9082;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
           include        fastcgi_params;
        }

       access_log  /opt/homebrew/var/www/log/access.log;
       error_log   /opt/homebrew/var/www/log/error.log;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
    include servers/*;
}

接下来创建一个站点:

在 /opt/homebrew/etc/nginx/servers/ 目录下创建一个名称为 php74.test.com.conf 配置文件,内容为:

server {
        listen       80; # 端口
        server_name  php74.test.com; # 站点名称

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /Users/iuu/Sites/php74.test.com;
            index  index.php index.html index.htm;
        }

        error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
             try_files $uri =404;
           root           /Users/iuu/Sites/php74.test.com;
           fastcgi_pass   127.0.0.1:9074;
           fastcgi_index  index.php;
           fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
           include        fastcgi_params;
        }

       access_log  /Users/iuu/Sites/php74.test.com/log/access.log;
       error_log   /Users/iuu/Sites/php74.test.com/log/error.log;
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

不同人配置不同 视情况修改

nginx 校验配置文件是否有效

nginx -t

nginx 启动 与停止

# 启动
brew services start nginx
# 停止
brew services stop nginx
# 重启
brew services restart nginx
# 状态
brew services info nginx

重新加载配置文件

nginx -s reload

修改hosts 文件实现域名访问

# 新增hosts 记录
127.0.0.1       php70.test.com

启动nginx 启动对应版本的 php-fpm 即可访问对于网址

# nginx 程序日志位置
/opt/homebrew/var/log/nginx
# php-fpm 日志位置
/opt/homebrew/var/log 

(为什么指定了php-fpm日志名称还会出现php-fpm.log文件?)
答:因为brew services 启动 php-fpm 的时候带了一个 StandardErrorPath 字段指定了日志

# 当启动php-fpm 或nginx 可以进这个目录看 brew services 的启动文件
~/Library/LaunchAgents 

参考 https://www.jianshu.com/p/6c3b26490861

Docker的三种网络代理配置

众所周知的原因,Docker最近需要使用代理。
Docker的代理配置,略显复杂,因为有三种场景。 但基本原理都是一致的,都是利用Linux的http_proxy等环境变量。

Dockerd 代理

在执行docker pull时,是由守护进程dockerd来执行。 因此,代理需要配在dockerd的环境中。 而这个环境,则是受systemd所管控,因此实际是systemd的配置。
修改docker 的docker.service文件
Service节点下新增代理环境变量配置
我的文件位置是:/lib/systemd/system/docker.service

[Service]
Environment="HTTP_PROXY=http://127.0.0.1:1080"
Environment="HTTPS_PROXY=http://127.0.0.1:1080"

dockerd代理的修改比较特殊,它实际上是改systemd的配置,因此需要重载systemd并重启dockerd才能生效。

systemctl daemon-reload
systemctl restart docker.service

Container 代理

在容器运行阶段,如果需要代理上网,则需要配置~/.docker/config.json。 以下配置,只在Docker 17.07及以上版本生效。

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://proxy.example.com:8080",
     "httpsProxy": "http://proxy.example.com:8080",
     "noProxy": "localhost,127.0.0.1,.example.com"
   }
 }
}

这个是用户级的配置,除了proxies,docker login等相关信息也会在其中。 而且还可以配置信息展示的格式、插件参数等。
此外,容器的网络代理,也可以直接在其运行时通过-e注入http_proxy等环境变量。 这两种方法分别适合不同场景。 config.json非常方便,默认在所有配置修改后启动的容器生效,适合个人开发环境。 在CI/CD的自动构建环境、或者实际上线运行的环境中,这种方法就不太合适,用-e注入这种显式配置会更好,减轻对构建、部署环境的依赖。 当然,在这些环境中,最好用良好的设计避免配置代理上网。

docker build代理

虽然docker build的本质,也是启动一个容器,但是环境会略有不同,用户级配置无效。 在构建时,需要注入http_proxy等参数。

docker build . \
    --build-arg "HTTP_PROXY=http://proxy.example.com:8080/" \
    --build-arg "HTTPS_PROXY=http://proxy.example.com:8080/" \
    --build-arg "NO_PROXY=localhost,127.0.0.1,.example.com" \
    -t your/image:tag

注意:无论是docker run还是docker build,默认是网络隔绝的。 如果代理使用的是 localhost:3128 这类,则会无效。 这类仅限本地的代理,必须加上--network host才能正常使用。 而一般则需要配置代理的外部IP,而且代理本身要开启gateway模式。

代理配置完成后,reboot重启当然可以生效,但不重启也行。

docker build代理是在执行前设置的,所以修改后,下次执行立即生效。
Container代理的修改也是立即生效的,但是只针对以后启动的Container,对已经启动的Container无效。

在 Linux 上使用 Docker 安装 Portainer CE

首先,创建 Portainer Server 用于存储其数据库的卷:

docker volume create portainer_data

然后,下载并安装 Portainer Server 容器:

docker pull portainer/portainer-ce

启动容器

docker run -d \
-p 8000:8000 \
-p 9000:9000 \
-p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \ # Dockeer的套接字映射
-v portainer_data:/data \ # 存贮卷映射
portainer/portainer-ce:latest

容器启动后浏览器访问 http://IP:9000 即可

Docker网络的学习

  • 用户是使用Docker Client与 Docker Daemon建立通信,并发送请求给后者
  • Docker Daemon作为Docker架构中主体部分,首先提供Docker Server的功能使其可以接受Docker Client的请求
  • Docker Engine执行Docker内部的一系列工作,每一项工作都是以Job的形式存在
  • Job的运行过程中,当需要容器镜像时则从Docker Registry中下载镜像,并通过镜像管理驱动Graph driver将下载镜像以Graph的形式存储
  • 当需要为Docker创建网络环境时,通过网络管理驱动Network driver 创建并配置Docker容器网络环境
  • 当需要限制Docker容器运行资源或执行用户指令等操作时,则通过Exec driver来完成
  • Libcontainer是一项独立的容器管理包,Network driver以及Exec driver都是通过Libcontainer来实现具体对容器进行的操作

操作系统本身网络

  • 桥接模式 - 直接连接物理网络
  • NAT模式 - 用于共享主机的IP地址
  • 仅主机模式 - 与主机共享的专用网络
  • 用户自定义模式 - 特定的虚拟网络

docker 不启动 默认网络情况

docker 启动后 网络情况
docker 启动后会产生一个名为docker0的虚拟网桥

ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:e9ff:fee5:668a  prefixlen 64  scopeid 0x20<link>
        ether 02:42:e9:e5:66:8a  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 266 (266.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Docker 网络的常用命令

默认创建3大网络模式
bridge 网桥模式
host  主机网络
none 无网络
还有两种:
容器模式
自定义模式
共计5种

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f14cce59440e   bridge    bridge    local
b171456906be   host      host      local
73342418fb83   none      null      local

查看命令帮助
docker network --help 
创建网络
docker network create a_network
删除网络 
docker network rm a_network
查看网络数据源
docker network inspect bridge

Docker 网络能干啥

容器间的互联和通信以及端口映射
容器IP变动的时候可以通过服务名直接网络通信而不收到影响

Docker 网络模式

默认三大网络模式 共计5种
bridge 网桥模式
host 主机网络
none 无网络
容器模式
自定义模式

bridge

为每个容器分配、设置IP等,并将容器连接到一个docker0的虚拟网桥,默认为该模式
bridge模式:使用--network bridge 指定,默认使用docker0

host

容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
host模式:使用--network host 指定

none

容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等
none模式:使用--network none指定

container

新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
container模式:使用--network container:NAME或者容器ID指定

自定义模式

Docker虚悬镜像

虚悬镜像就是仓库名、标签都是的镜像,俗称dangling image
查看系统的虚悬镜像

docker image ls -f dangling=true

虚悬镜像已经失去存在价值,可以删除

docker image prune
1 6 7 8 9 10 12