# 實戰應用使用Docker構建LNMP環境(二)
## ttlinux/php-fpm:5.4
cd docker-training/php-fpm/
ls
Dockerfile nginx_nginx.conf supervisor_nginx.conf
nginx_default.conf php_www.conf supervisor_php-fpm.conf
各文件解釋:
- nginx_nginx.conf 替換默認的nginx.conf文件
- nginx_default.conf 替換默認的default.conf文件
- php_www.conf 修改apache用戶為nginx
- supervisor_nginx.conf 添加啟動nginx的supervisor文件
- supervisor_php-fpm.conf 添加啟動php-fpm的supervisor文件
#### 構建中間件PHP
# Dockerizing php-fpm: Dockerfile for building php-fpm images
#
FROM ttlinux/centos:7.4
MAINTAINER huyi,<345270016@qq.com>
# Set environment variable
ENV APP_DIR /app
RUN yum -y install nginx php-cli php-mysql php-pear php-ldap php-mbstring php-soap php-dom php-gd php-xmlrpc php-fpm php-mcrypt && \
yum clean all
ADD nginx_nginx.conf /etc/nginx/nginx.conf
ADD nginx_default.conf /etc/nginx/conf.d/default.conf
ADD php_www.conf /etc/php-fpm.d/www.conf
RUN sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php.ini
RUN mkdir -p /app && echo "<?php phpinfo(); ?>" > ${APP_DIR}/info.php
EXPOSE 80 443
ADD supervisor_nginx.conf /etc/supervisor.conf.d/nginx.conf
ADD supervisor_php-fpm.conf /etc/supervisor.conf.d/php-fpm.conf
ONBUILD ADD . /app
ONBUILD RUN chown -R nginx:nginx /app
### 構建php-fpm鏡像
docker build -t ttlinux/php-fpm:5.4 .
# 命令解析:
`ONBUILD ADD . /app`
`ONBUILD` 在生成當前docker鏡像的時候不生效,在子鏡像生效;`ONBUILD`在產品發布時起著非常重要的作用!舉例
A鏡像中有`ONBUILD`指令,在構建A鏡像時`ONBUILD`指令不執行;B鏡像`FROM A`,在構建B鏡像時`ONBUILD`指令開始執行;
如何給docker鏡像命名:
- registry-url: registry服務器的域名或者ip
- namespace:
- image-name: docker鏡像的名字
- tag: docker鏡像的版本號,推薦使用應用服務的版本號來命名,如`php-fpm:5.4`
```
Step 12 : ONBUILD add . /app
---> Running in 9e21ede67350
---> 7541483a5a76
Removing intermediate container 9e21ede67350
Step 13 : ONBUILD run chown -R nginx:nginx /app
---> Running in ab55fc7a46a1
---> c61699e8c237
Removing intermediate container ab55fc7a46a1
Successfully built c61699e8c237
```
生成website容器:
docker run -d -p 8080:80 --name website ttlinux/php-fpm:5.4
da30b15d3518320f4150b20ef329e59432a65610968977277879578b5fd8f4f7
參數解釋:
- -d 后臺運行
- -p 8080:80 將宿主機的8080端口映射到容器的80端口
- --name website 給容器命名為website
- ttlinux/php-fpm:5.4 使用這個鏡像鏡像創建docker容器
使用瀏覽器訪問:`http://your_ip:8080/info.php`
如何進入一個正在運行的docker容器?
`docker exec -it website /bin/bash`
$supervisorctl 查看當前容器中使用supervisor啟動了哪些服務?
nginx RUNNINGpid 8, uptime 0:04:20
php-fpm RUNNING pid 9, uptime 0:04:20`
## 構建中間件 ttlinux/mysql:5.5
# Dockerizing Mariadb: Dockerfile for building Mariadb images
#
FROM ttlinux/centos:7.4
MAINTAINER Carson,C.J.Zeong <zcy@nicescale.com>
ENV DATA_DIR /var/lib/mysql
# Install Mariadb
RUN yum install -y mariadb mariadb-server && \
yum clean all
ADD mysqld_charset.cnf /etc/my.cnf.d/
COPY scripts /scripts
EXPOSE 3306
VOLUME ["/var/lib/mysql"]
ENTRYPOINT ["/scripts/start"]
> PS: 注意給scripts目錄下所有文件添加執行權限
chmod +x scripts/firstrun*
chmod +x scripts/start
#### 構建mysql docker鏡像
docker build -t ttlinux/mysql:5.5 .
#### 命令解析:
`VOLUME`指令,宿主機文件目錄和docker容器文件目錄做映射
VOLUME ["/var/lib/mysql"]
`ENTRYPOINT`在每次啟動docker容器時都會被執行,此例,是運行了一個shell腳本"/scripts/start"
`ENTRYPOINT ["/scripts/start"]`
每次啟動都會運行`/scripts/start`腳本,腳本內容如下:
cat start
#!/bin/bash
set -e
#
# When Startup Container script
#
if [[ -e /scripts/firstrun ]]; then
# config mariadb
/scripts/firstrun_maria
rm /scripts/firstrun
else
# Cleanup previous mariadb sockets
if [[ -e ${DATA_DIR}/mysql.sock ]]; then
rm -f ${DATA_DIR}/mysql.sock
fi
fi
exec /usr/bin/mysqld_safe
腳本解析:
- `set -e` 腳本中只要有一行有錯誤,就會中斷腳本執行
- 如果firstrun文件存在,執行firstrun_maria腳本,如果不存在,刪除mysql.sock文件,并啟動Mariadb
> firstrun_maira腳本是初始化Mariadb,以及設置數據庫用戶和密碼,詳情內容請自行閱讀[腳本文件](http://git.oschina.net/dockerf/docker-training/blob/master/mysql/scripts/firstrun_maria?dir=0&filepath=mysql%2Fscripts%2Ffirstrun_maria&oid=788bfb61d8cc45a33b60cde5a0e98899ee08f808&sha=3a86a4767292c267af0794628efb76fe31e754e6)
### docker volume 保證刪除容器后,數據不被刪除
- 保存容器中的數據
- 數據共享
使用方法:
1.在Dockerfile中定義VOLUME["/data"]
2.通過`docker run -d -v <host_dir>:<container_dir>`
### 案例:
1. 創建mysql容器,不掛載docker volume,刪除后,數據是否存在
2. 創建mysql容器,掛載docker volume,刪除后,數據是否存在
運行不掛載docker volume的mysql容器
docker run -d -p 3306:3306 --name dbserver ttlinux/mysql:5.5
0a3092395c1e6a84f0ecd5383799f210519c5aefc82cbb7ee2ed1a471fc463f5
刪除docker容器,容器里面的數據都會隨著容器被刪除而刪除
```
# docker rm dbserver
Error response from daemon: Cannot destroy container dbserver: Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f
Error: failed to remove containers: [dbserver]
```
參數解釋:
- `docker rm` 刪除狀態為“Exited”的docker容器
- `docker rm -f` 強制刪除docker容器
運行掛載docker volume的mysql容器
`docker run -d -p 3306:3306 -v /var/lib/docker/vfs/dir/mydata:/var/lib/mysql ttlinux/mysql:5.5`
`f49165d5e081b8bd8af9cb9c0bbbeb6545d45f857c1a852646c105`
`docker exec -it f49 /bin/bash`
登陸數據庫創建mydb數據庫
```
# mysql
# show databases;
# create database mydb;
Query OK, 1 row affected (0.00 sec)
# show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
# exit
exit
```
查看主機文件目錄下,是否已生成mydb數據庫目錄文件
```
# ls /var/lib/docker/vfs/dir/mydata/
aria_log.00000001 ibdata1 ib_logfile1 mysql performance_schema
aria_log_control ib_logfile0 mydb mysql.sock test
```
```
停止docker容器
# docker stop f49165d5e081
f49165d5e081
刪除docker容器,查看`mydb`目錄是否被刪除
# docker rm f49165d5e081
f49165d5e081
# ls /var/lib/docker/vfs/dir/mydata/ 驗證,掛載docker volume后,容器被刪除掉,數據還在
aria_log.00000001 ibdata1 ib_logfile1 mysql performance_schema
aria_log_control ib_logfile0 mydb mysql.sock test
```
新創建一個容器,掛載到剛才的數據目錄下,是否可以把之前的數據庫加載回來
docker run -d -p 3306:3306 --name newdb -v /var/lib/docker/vfs/dir/mydata:/var/lib/mysql ttlinux/mysql:5.5
`docker exec -it newdb /bin/bash`
```
# mysql
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
```
驗證結果: 只要保證數據在,重新創建一個容器掛載回之前的數據目錄,業務即可恢復(容器可隨意刪除、創建)
- 第一章 Docker核心技術(一)
- 第一章 Docker核心技術(二)
- 第一章 Docker核心技術(三)
- 第一章 Docker核心技術(四)
- 第二章 Docker 入門
- 第三章 使用docker鏡像
- 第四章 實戰應用使用Docker構建LNMP環境 (一)
- 第四章 實戰應用使用Docker構建LNMP環境 (二)
- 第四章 實戰應用使用Docker構建LNMP環境 (三)
- 第五章 構建企業級Harbor-Registry
- 第六章 構建Docker應用發布系統(一)
- 第六章 構建Docker應用發布系統(二)
- 第六章 構建Docker應用發布系統(三)
- 第六章 構建Docker應用發布系統(四)