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;
}
}
|