Docker用docker-compose.yml启动php开发环境nmpr(nginx+mysql+php+redis集群)

nmpr是一个集成了nginx、mysql、php、redis的php开发环境。
nmpr不是docker官方程序,而是由csdn博主one312原创设计。

nmpr是学习docker过程中所做,水平有限,欢迎指正。

参阅以下文章,有助于理解nmpr的运作原理:

1.Deepin+Docker+Redis5.0 安装 Redis集群

2.Docker构建自己的PHP-fpm容器镜像

3.Docker容器PHP5.6-fpm环境通过composer安装laravel

一、在当前用户下创建目录~/nmpr,用于存放工程文件

wdh@wdh-PC:~$ mkdir nmpr

     nmpr工程目录结构如下:

 

wdh@wdh-PC:~/nmpr$ tree
.
├── docker-compose.yml         
#用来启动所有容器nginx+mysql+redis+php
├── mysql                                   #mysql
   └── conf.d                              #mysql容器映射出来的配置文件目录
├── nginx                                    #nginx
   ├── conf.d                              #nginx容器映射出来的服务配置文件目录
      └── nginx-default.conf    #nginx配置文件
   ├── log                                   #nginx容器映射出来的日志文件目录
      ├── access.log                 #nginx日志,由容器内nginx服务自动生成
      └── error.log                     #nginx日志,由容器内nginx服务自动生成
   └── www                                #nginx容器映射出来的www目录
│       ├── index.html                   #www目录下html入口文件
       ├── index.php                    #www目录下php入口文件
       ├── php-default.ini            #该文件可以由php.ini-development复制得到
├── nmpr-down.sh                     #停止nmpr服务
├── nmpr-restart.sh                   #重启nmpr服务
├── php                                       #php
   ├── conf.d                             #php容器映射出来的配置文件目录
      ├── php-default.ini.bak   #自己备份出来的php.ini文件
      └── php.ini                        #php配置文件
   └── Dockerfile                       #用来构建php镜像,重新构建镜像的时候可以用到,点击查看重构步骤
└── redis                                     #redis目录
    ├── bin                                    #redis容器映射出来的可执行文件目录
       ├── cluster.sh                    #用于启动redis集群入口服务容器内的redis服务
       └── redis.sh                       #用于启动redis集群节点服务容器内的redis服务
    ├── cluster                              #redis服务容器启动后的配置文件目录,该目录下文件由redis各节点在启动时自动生成
       ├── nodes-6379.conf
       ├── nodes-6391.conf
       ├── nodes-6392.conf
       ├── nodes-6393.conf
       ├── nodes-6394.conf
       ├── nodes-6395.conf
       └── nodes-6396.conf
    ├── conf                                 
#redis服务容器个节点的配置文件,包括 cluster 和 各nodes
       ├── nodes-6379.conf       #集群配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6391.conf       #主节点1配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6392.conf       #主节点2配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6393.conf       #主节点3配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6394.conf       #从节点1配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6395.conf       #从节点2配置,redis服务容器内的redis服务启动时使用
       ├── nodes-6396.conf       #从节点3配置,redis服务容器内的redis服务启动时使用
    ├── Dockerfile                       #用来构建redis镜像,重新构建redis镜像时候可以用到
    ├── dump-6379.rdb               #redis节点的数据文件,该文件由redis容器内的redis服务启动后自动生成
    ├── dump-6391.rdb               
    ├── dump-6393.rdb               
    ├── dump-6394.rdb               
    ├── dump-6395.rdb               
    ├── dump-6396.rdb               
    ├── logs                                 
#redis容器内redis服务的启动日志文件目录
       ├── nodes-6379-1.log      
       ├── nodes-6379.log
       ├── nodes-6391.log
       ├── nodes-6392.log
       ├── nodes-6393.log
       ├── nodes-6394.log
       ├── nodes-6395.log
       └── nodes-6396.log
    └── redis-5.0.5.tar.gz           #redis5.0源程序,重新安装redis5.0时可以用到,这里只是留作备用
wdh@wdh-PC:~/nmp$ 

      nmpr目录下所有见文章末尾附录。

二、启动与停止nmpr集成环境

      1.启动nmpr

wdh@wdh-PC:~/nmpr$ ./nmpr-restart.sh

可以看到各服务的容器都已正常启动

    2.停止nmpr

三、文件附录

      1. ./docker-compose.yml

version: "3.6"
services:
  redis-cluster:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-cluster # 容器服务名
    depends_on:
      - redis-master1
      - redis-master2
      - redis-master3
      - redis-slave1
      - redis-slave2
      - redis-slave3
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6379 # 跟 nodes-6391.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6379:6379" # redis 的服务端口
      - "16379:16379" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-cluster-net:
        ipv4_address: 172.200.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
     - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/cluster.sh # 设置服务默认的启动程序 /home/wdh/redis/bin

#########################################################################
  redis-master1:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-master1 # 容器服务名
    #links:
    #  - "redis-master1" #服务别名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6391 # 跟 nodes-6391.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6391:6391" # redis 的服务端口
      - "16391:16391" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-master-net:
        ipv4_address: 172.100.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序 /home/wdh/redis/bin
  redis-master2:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-master2 # 容器服务名
    #links:
    #  - "redis-master2" #服务别名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6392 # 跟 nodes-6392.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6392:6392" # redis 的服务端口
      - "16392:16392" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-master-net:
        ipv4_address: 172.100.0.3
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序
  redis-master3:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-master3 # 容器服务名
    #links:
    #  - "redis-master3" #服务别名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6393 # 跟 nodes-6393.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6393:6393" # redis 的服务端口
      - "16393:16393" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-master-net:
        ipv4_address: 172.100.0.4
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序
  redis-slave1:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-slave1 # 容器服务名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6394 # 跟 nodes-6394.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6394:6394" # redis 的服务端口
      - "16394:16394" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-slave-net:
        ipv4_address: 172.50.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序
  redis-slave2:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-slave2 # 容器服务名
    #links:
    #  - "redis-slave2" #服务别名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6395 # 跟 nodes-6395.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6395:6395" # redis 的服务端口
      - "16395:16395" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-slave-net:
        ipv4_address: 172.50.0.3
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序
  redis-slave3:
    image: hengda/redis:5.0 # 基础镜像
    container_name: redis-slave3 # 容器服务名
    #links:
    #  - "redis-slave3" #服务别名
    working_dir: /config # 工作目录
    environment: # 环境变量
      - PORT=6396 # 跟 nodes-6396.conf 里的配置一样的端口
    ports: # 映射端口,对外提供服务
      - "6396:6396" # redis 的服务端口
      - "16396:16396" # redis 集群监控端口
    stdin_open: true # 标准输入打开
    networks: # docker 网络设置
      redis-slave-net:
        ipv4_address: 172.50.0.4
    tty: true
    privileged: true # 拥有容器内命令执行的权限
#    volumes: ["/home/wdh/nmp/redis:/config"] # 映射数据卷,配置目录
    volumes:
      - ./redis:/config
    entrypoint:
      - /bin/bash
      - bin/redis.sh # 设置服务默认的启动程序

################################################################################
  hengda-mysql:
    image: mysql:5.7
    container_name: hengda-mysql
    environment:
      - PORT=80
      - MYSQL_ROOT_PASSWORD=123456
    ports:
      - 3306:3306
    stdin_open: true #标准输入打开
    networks: #
      hengda-mysql-net:
        ipv4_address: 172.30.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
    # 映射数据卷,配置目录
    # 映射容器内部目录/etc/mysql/conf.d到Deepin目录/home/wdh/nmp/mysql/conf.d
    volumes:
      - ./mysql/conf.d:/etc/mysql/conf.d
  hengda-php:
    image: hengda/php5.6-fpm:v1
    container_name: hengda-php
    depends_on:
      - hengda-mysql
    restart: always
    environment:
      - PORT=9000
    ports: 
      - 9000:9000
    stdin_open: true # 标准输入打开
    networks:
      hengda-php-net:
        ipv4_address: 172.20.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
    volumes:
      - ./nginx/www:/www
      - ./php/conf.d:/usr/local/etc/php/conf.d
  hengda-nginx:
    image: nginx:1.8
    container_name: hengda-nginx
    depends_on:
      - hengda-php
    restart: always
    ports:
      - 80:80
      - 8080:80
      - 443:443
    stdin_open: true # 标准输入打开
    networks:
      hengda-nginx-net:
        ipv4_address: 172.10.0.2
    tty: true
    privileged: true # 拥有容器内命令执行的权限
    volumes: 
      - ./nginx/conf.d:/etc/nginx/conf.d
      # 映射数据卷,配置目录
      # 映射容器内部目录/etc/nginx/conf.d到Deepin目录./nmp/nginx/conf.d
      - ./nginx/log:/var/log/nginx
      - ./nginx/www:/usr/share/nginx/html
#   links:
#      - hengda-php:php
#      - 172.10.0.4:9000

networks: 
  hengda-nginx-net: 
    driver: bridge #创建一个docker 的桥接网络
    ipam: 
      driver: default
      config:
        -
          subnet: 172.10.0.0/16 
  hengda-php-net: 
    driver: bridge #创建一个docker 的桥接网络
    ipam: 
      driver: default
      config:
        -
          subnet: 172.20.0.0/16
  hengda-mysql-net: 
    driver: bridge #创建一个docker 的桥接网络
    ipam: 
      driver: default
      config:
        -
          subnet: 172.30.0.0/16
###################################################################
  redis-cluster-net:
    driver: bridge # 创建一个docker 的桥接网络
    ipam:
      driver: default
      config:
        -
          subnet: 172.200.0.0/16
  redis-master-net:
    driver: bridge # 创建一个docker 的桥接网络
    ipam:
      driver: default
      config:
        -
          subnet: 172.100.0.0/16
  redis-slave-net:
    driver: bridge # 创建一个docker 的桥接网络
    ipam:
      driver: default
      config:
        -
          subnet: 172.50.0.0/16

2. ./nmpr-restart.sh

#!/bin/bash


#关闭docker
docker-compose down;


#备份文件
WORK_DIR=$(cd "$(dirname "$0")"; pwd);
time=$(date "+%Y%m%d%H%M%S");


dirname="cluster${time}.bak";
mv ${WORK_DIR}"/redis/cluster" ${WORK_DIR}"/redis/${dirname}" 2> /dev/null; #用绝对路径 可以在其他目录执行
#mv "./redis/cluster" "./redis/${dirname}" 2> /dev/null;#用相对路径时只能在.sh文件同目录下执行

#dirname="dump${time}.bak";
#mv ${WORK_DIR}"/redis/dump" ${WORK_DIR}."/redis/${dirname}" 2> /dev/null;
#mv "./redis/dump" "./redis/${dirname}" 2> /dev/null;

#创建目录
mkdir ${WORK_DIR}"/redis/cluster";
#mkdir "./redis/cluster";

#mkdir ${WORK_DIR}"/redis/dump";


#等待容器安装完毕
docker-compose up -d #&
#wait


#进入容器执行创建集群命令
CLUSTER_PORT=6379
echo "echo 'yes' | redis-cli --cluster create 172.17.0.1:6391 172.17.0.1:6392 172.17.0.1:6393 172.17.0.1:6394 172.17.0.1:6395 172.17.0.1:6396 --cluster-replicas 1 >> ./logs/nodes-${CLUSTER_PORT}-1.log 2>&1 & " | docker exec -i redis-cluster /bin/bash

3. ./php/Dockerfile

FROM php:5.6-fpm
RUN     apt-get update \
    #cp -r /etc/apt/sources.list /etc/apt/sources.list.bak \
    #修改软件源
    #
    #&& echo "deb http://mirrors.aliyun.com/debian/ wheezy main non-free contrib" > /etc/apt/sources.list \
    #&& echo "deb http://mirrors.aliyun.com/debian/ wheezy-proposed-updates main non-free contrib" >> /etc/apt/sources.list \
    #&& echo "deb-src http://mirrors.aliyun.com/debian/ wheezy main non-free contrib" >> /etc/apt/sources.list \
    #&& echo "deb-src http://mirrors.aliyun.com/debian/ wheezy-proposed-updates main non-free contrib" >> /etc/apt/sources.list \
    #
    #&& apt-get update \
    #切换目录
    && cd /tmp \
    #安装sudo
    && apt-get install sudo -y \
    #安装vim文本编辑器
    && apt-get install vim -y \
    #安装wget下载工具
    && apt-get install wget -y \
    #安装网络管理工具
    && apt-get install net-tools -y \
    #安装ping
    && apt-get install iputils-ping -y \
    #安装telnet
    && apt-get install telnet -y \
    #安装进程管理命令ps, top, vmstat, w, kill, free, slabtop, and skill
    && apt-get install procps -y \
    #安装C/C++编译包,该软件包,编译c/c++所需要的软件包也都会被安装。
    #该包包含gcc,g++,make等`
    && apt-get install build-essential -y \
    #安装zip依赖 zlib
    && apt-get install zlib1g-dev -y \
    #安装zip
    && bash -c "apt-get install unzip -y;" \
    #安装openssh-server  即sshd
    && apt install -y openssh-server -y \
    #给root用户设置初始密码123456
    && echo root:123456 | chpasswd \
    #安装composer命令
    #下载composer.phar
    && php -r "readfile('https://getcomposer.org/installer');" | php \
    #给composer.phar赋可执行权限
    #将composer.phar复制到/bin/目录下并重命名为composer
    && mv composer.phar /bin/composer \
    #查看composer版本
    #composer -v
    #修改composer镜像源地址为国内地址
    && composer config -g repo.packagist composer https://packagist.phpcomposer.com \
    #安装php扩展
    #下载
    && wget http://qinqinxia.com/zip-1.13.5.tgz \
    #解压
    && tar -zvxf zip-1.13.5.tgz \
    #解压后复制到目录/usr/local/src
    && cp -r zip-1.13.5 /usr/local/src \
    #切换目录到/usr/local/src/zip-1.13.5
    && cd /usr/local/src/zip-1.13.5 \
    #安装php扩展php-zip
    #
    && /usr/local/bin/phpize \
    #
    && ./configure --with-php-config=/usr/local/bin/php-config \
    #
    && make && make install
    # 扩展所在目录:
    #Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20131226/
    #配置
    #cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini
    #vim /usr/local/etc/php/php.ini
    #然后添加配置项extension=zip.so即可
    #composer安装laravel
    #composer global require laravel/installer

4. ./redis/Dockerfile

RUN apt-get update \
    && apt-get install sudo \
    && apt-get install iputils-ping -y \
    && apt-get install telnet -y \
    && apt-get install net-tools \
    && apt-get install vim -y

5. ./redis/bin/cluster.sh 

redis-server ./conf/nodes-${PORT}.conf

6. ./redis/bin/redis.sh (与上面文件分开是因为方便各自添加附加的程序步骤,互不影响)

redis-server  conf/nodes-${PORT}.conf

7. ./redis/conf/nodes-6379.conf

    过滤注释行命令查看配置内容:$ cat ./redis/conf/nodes-6379.conf | grep -v "^[[:space:]].*#" | grep -v "^#" | grep -v "^$"

    该文件由redis官方配置更改而来,其中红色配置项为改动项。

bind 172.200.0.2
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile "logs/nodes-6379.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-6379.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
cluster-enabled yes
cluster-config-file "cluster/nodes-6379.conf"
cluster-node-timeout 15000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

8. ./redis/conf/nodes-6391.conf(6392,6393,6394,6395,6396对应节点配置与此相似,不同之处是端口、IP、日志文件等名称)

    过滤注释行命令查看配置内容:$ cat ./redis/conf/nodes-6391.conf | grep -v "^[[:space:]].*#" | grep -v "^#" | grep -v "^$"

    该文件由redis官方配置更改而来,其中红色配置项为改动项。

 
bind 172.100.0.2
protected-mode no
port 6391
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6391.pid
loglevel notice
logfile "logs/nodes-6391.log"
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump-6391.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
cluster-enabled yes
cluster-config-file "cluster/nodes-6391.conf"

cluster-node-timeout 15000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

9. .nginx/conf.d/nginx-default.conf 

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html/laravel/public;
        index index.php index.html index.htm server.php;


    #开启后忽略入口文件
    if (!-e $request_filename) {
        rewrite  ^(.*)$  /index.php$1  last;
        break;
    }

    }

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

    location ~ \.php(.*)$ {
#    fastcgi_pass    php:9000;
    fastcgi_pass    172.17.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /www/laravel/public/$fastcgi_script_name;
        include        fastcgi_params;
    }
}
 

发布了118 篇原创文章 · 获赞 17 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/one312/article/details/104097139