nmpr是一个集成了nginx、mysql、php、redis的php开发环境。 nmpr不是docker官方程序,而是由csdn博主one312原创设计。 nmpr是学习docker过程中所做,水平有限,欢迎指正。 参阅以下文章,有助于理解nmpr的运作原理: |
一、在当前用户下创建目录~/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; } } |