M1 Docker PHP 开发环境搭建(容器独立方式)
M1 Docker PHP 开发环境搭建(容器独立方式)
Docker 下载 安装步骤省略
Docker 官方镜像库
PHP(7.0)+MySQL(8.0)+Nginx+Redis(单实例)/Redis集群
??????注意??????
声明:
- 本文中出现的huoxiao文件夹为本人电脑用户目录。
- 本文中出现的 192.168.1.68 为本人在指定网络下的内网固定IP,请勿混淆。
所有镜像拉取前需要注意支持 ARM64
docker run 命令的常用参数如下:
- -d:创建自动式守护容器(后台运行)
- -i:以交互模式运行容器,通常与 -t 一起使用
- -t:为容器重新分配一个伪输入终端,通常与 -i 一起使用
- -p:指定端口映射
- -P:随机端口映射
- -v:目录(文件夹)映射
- -name:容器名
- --privileged:true=提权 默认: false
1. PHP (本人是拉取的php-fpm-7.0镜像)
这里可能会有人担心本地代码是5.x版本,高版本能否适用?
首先, 只要你高于你本地代码要求版本就没有问题,官方兼容
其次, 此方式搭建环境是本人目前正在使用的方式
docker pull php-fpm-7.0
docker run -dit --name=php-fpm-7.0 -p 9000:9000 -P -v /Users/huoxiao/Documents/data/dev/:/data/www/ -v /etc/localtime:/etc/localtime --privileged=true php-fpm-7.0
??命令释义
1. 拉取 php-fpm7.0 镜像(拉取 php 或 php-fpm 均可, php-fpm 目前已被 php 集成为官方内容)
2. 创建一个名称为 php-fpm-7.0 的容器
- 端口映射(宿主机端口:容器端口 注意 -p 和 -P 区分大小写, 且含义不一)
- -p 9000:9000
- -P 随机端口映射 备用端口, 可在需要其它端口情况下, 直接取用
- 目录映射方式(即 本地目录:容器目录)如下:
- 项目目录:-v /Users/huoxiao/Documents/data/dev/:/data/www/
- 宿主机时间:-v /etc/localtime:/etc/localtime
- 使用镜像:命令最后的参数 php-fpm-7.0
docker run -dit --name=php-fpm-8.1 -p 9001:9000 -P -v /Users/huoxiao/Documents/data/dev/:/data/www/ -v /etc/localtime:/etc/localtime --privileged=true php:8.1.5-fpm
??本人的另一个 8.0 版本的容器,只需要本地的另外一个端口 9001 映射到容器的 9000 端口即可
2. MySQL
docker pull mysql/mysql-server
docker run -dit --name=mysql-8.0 -p 3306:3306 -P -v /etc/localtime:/etc/localtime -e MYSQL_ROOT_PASSWORD=密码 --privileged=true mysql/mysql-server
??命令释义
1. 拉取 mysql/mysql-server 镜像(8.0版本,无需担心太高)
2. 创建一个名称为 mysql-8.0 的容器
- 端口映射、目录映射同PHP方式
- 需要注意的是在创建MySQL容器时, 需要设置密码, 即参数: MYSQL_ROOT_PASSWORD
- MySQL的配置文件 my.cnf 可在本地新建后映射到容器中, 本人未映射
Navicat 工具连接,使用本机IP或172.0.0.1 + 端口(创建容器时的端口) + 创建容器时设置的密码即可
3. Nginx
docker pull nginx
docker run -dit --name=nginx -p 80:80 -p 8088:8088 -p 8089:8089 -P -v /Users/huoxiao/Documents/data/env/nginx/:/etc/nginx -v /etc/localtime:/etc/localtime -v /Users/huoxiao/Documents/data/dev/:/data/www --privileged=true nginx
??命令释义
1. 拉取nginx镜像
2. 创建一个名称为nginx的容器
- 由于需要本人映射了 80、8088、8089 端口, 根据实际情况按需即可
- 解释一下为什么把项目目录分别映射到PHP容器和Nginx容器:
因为 Nginx 服务器负责将 PHP 内容转发到 PHP 容器解析, 而 静态文件(图片、Css、Js等)需要 Nginx 解析
因此需要分别将项目目录映射到PHP容器和Nginx容器
在这里说明一下 Nginx 与 PHP 容器的通信
location ~ .*\.(php|php5)?$ {
fastcgi_pass 172.17.0.1:9000; # 使用docker网卡通过端口将php内容转发到php-fpm中
fastcgi_index index.php; # 入口文件
include conf/fastcgi.conf; # fastcgi.conf
}
4. Redis
docker pull redis
docker run -dit --name=redis-6379 -p 6379:6379 -P -v /etc/localtime:/etc/localtime --privileged=true redis
??命令含义同PHP/MySQL/Nginx
5. Redis集群
需要的文件较多, 以下所需文件需要看清目录, 均是我本地的目录, 注意区分
- 运行 redis-cluster-config.sh 将 redis-cluster.tmpl 配置内容批量生成配置文件
redis-cluster-config.sh 内容如下??:
for port in `seq 6391 6396`; do \
mkdir -p /Users/huoxiao/Documents/data/env/redis/redis-cluster/${port}/conf \
&& PORT=${port} envsubst < ./redis-cluster.tmpl > /Users/huoxiao/Documents/data/env/redis/redis-cluster/${port}/conf/redis.conf \
&& mkdir -p /Users/huoxiao/Documents/data/env/redis/redis-cluster/${port}/data; \
done
redis-cluster.tmpl 内容如下??:
# redis端口
port ${PORT}
#redis 访问密码
# requirepass 密码
#redis 访问Master节点密码
# masterauth 密码
# 关闭保护模式
protected-mode no
# 开启集群
cluster-enabled yes
# 集群节点配置
cluster-config-file nodes.conf
# 超时
cluster-node-timeout 15000
# 集群节点IP host模式为宿主机IP # 注意此处为本机IP
cluster-announce-ip 192.168.1.68
# 集群节点端口 6391 - 6396
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
# 开启 appendonly 备份模式
appendonly yes
# 每秒钟备份
appendfsync everysec
# 对aof文件进行压缩时,是否执行同步操作
no-appendfsync-on-rewrite no
# 当目前aof文件大小超过上一次重写时的aof文件大小的100%时会再次进行重写
auto-aof-rewrite-percentage 100
# 重写前AOF文件的大小最小值 默认 64mb
auto-aof-rewrite-min-size 64mb
# 日志配置
# debug:会打印生成大量信息,适用于开发/测试阶段
# verbose:包含很多不太有用的信息,但是不像debug级别那么混乱
# notice:适度冗长,适用于生产环境
# warning:仅记录非常重要、关键的警告消息
loglevel notice
# 日志文件路径
logfile "/data/redis.log"
- docker-compose -f docker-compose.yml up -d 后台启动容器, 容器生成完成 docker ps 查看是否创建成功
执行命令如下??:
docker-compose -f docker-compose.yml up -d
docker-compose.yml 内容如下??:
version: "3.6"
services:
master-1:
image: redis:latest # 基础镜像
container_name: master-1 # 容器服务名
working_dir: /data # 工作目录
environment: # 环境变量
- PORT=6391 # 跟 redis.conf 里的配置一样的端口
- TZ=Asia/Shanghai # 设置时区为上海,否则时间会有问题
ports: # 映射端口,对外提供服务
- "6391:6391" # redis 的服务端口
- "16391:16391" # redis 集群监控端口
stdin_open: true # 标准输入打开
networks: # docker 网络设置
master:
ipv4_address: 172.50.0.2
tty: true
privileged: true # 拥有容器内命令执行的权限
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6391/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6391/data:/data"
]
# entrypoint: # 设置服务默认的启动程序
# - /bin/bash
# - redis.sh
command: ["redis-server", "/etc/redis/redis.conf"]
master-2:
image: redis:latest
working_dir: /data
container_name: master-2
environment:
- PORT=6392
- TZ=Asia/Shanghai
networks:
master:
ipv4_address: 172.50.0.3
ports:
- "6392:6392"
- "16392:16392"
stdin_open: true
tty: true
privileged: true
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6392/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6392/data:/data"
]
# entrypoint:
# - /bin/bash
# - redis.sh
command: ["redis-server", "/etc/redis/redis.conf"]
master-3:
image: redis:latest
container_name: master-3
working_dir: /data
environment:
- PORT=6393
- TZ=Asia/Shanghai
networks:
master:
ipv4_address: 172.50.0.4
ports:
- "6393:6393"
- "16393:16393"
stdin_open: true
tty: true
privileged: true
# volumes: ["/Users/huoxiao/Documents/data/env/redis:/etc/redis"]
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6393/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6393/data:/data"
]
# entrypoint:
# - /bin/bash
# - redis.sh
command: ["redis-server", "/etc/redis/redis.conf"]
slave-1:
image: redis:latest
container_name: slave-1
working_dir: /data
environment:
- PORT=6394
- TZ=Asia/Shanghai
networks:
slave:
ipv4_address: 172.30.0.2
ports:
- "6394:6394"
- "16394:16394"
stdin_open: true
tty: true
privileged: true
# volumes: ["/Users/huoxiao/Documents/data/env/redis:/etc/redis"]
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6394/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6394/data:/data"
]
# entrypoint:
# - /bin/bash
# - redis.sh
command: ["redis-server", "/etc/redis/redis.conf"]
slave-2:
image: redis:latest
working_dir: /data
container_name: salve-2
environment:
- PORT=6395
- TZ=Asia/Shanghai
ports:
- "6395:6395"
- "16395:16395"
stdin_open: true
networks:
slave:
ipv4_address: 172.30.0.3
tty: true
privileged: true
# volumes: ["/Users/huoxiao/Documents/data/env/redis:/etc/redis"]
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6395/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6395/data:/data"
]
# entrypoint:
# - /bin/bash
# - redis.sh
command: ["redis-server", "/etc/redis/redis.conf"]
slave-3:
image: redis:latest
container_name: slave-3
working_dir: /data
environment:
- PORT=6396
- TZ=Asia/Shanghai
ports:
- "6396:6396"
- "16396:16396"
stdin_open: true
networks:
slave:
ipv4_address: 172.30.0.4
tty: true
privileged: true
volumes: [ # 映射数据卷,配置目录
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6396/conf:/etc/redis",
"/Users/huoxiao/Documents/data/env/redis/redis-cluster/6396/data:/data"
]
command: ["redis-server", "/etc/redis/redis.conf"]
# entrypoint:
# - /bin/bash
# - redis.sh
networks:
master:
driver: bridge # 创建一个docker 的桥接网络
ipam:
driver: default
config:
-
subnet: 172.50.0.0/16
slave:
driver: bridge
ipam:
driver: default
config:
-
subnet: 172.30.0.0/16
- 进入第一个容器中, 执行 redis-cluster-create.conf 中内容, 注意文件中的IP地址要与redis-cluster.tmpl 中的ip保持一致
执行如下命令进入容器??(master-1 为刚创建的集群容器主节点1):
docker exec -it master-1 /bin/bash
redis-cluster-create.conf 内容如下??,创建集群:
redis-cli --cluster create 192.168.1.68:6391 192.168.1.68:6392 192.168.1.68:6393 192.168.1.68:6394 192.168.1.68:6395 192.168.1.68:6396 --cluster-replicas 1