Docker基础
这里不多说,借助docker官方文档可以学习到大部分内容,而且很详细。
本次配置中用到的镜像:
并且使用docker-compose来管理容器,它在pdf文档中有介绍,这里不再赘述。
多机结构
为了实现一台真机模拟多台机,引入逻辑主机
的概念。例如现在只有一台云主机,但是我们又要把测试环境(dev)
和 正式环境(online)
分开。
以下是项目完成后的目录结构,每一个目录对应一个逻辑主机
和独立数据卷
.
├── dev
│ ├── docker-compose.yml
│ └── php
│ └── Dockerfile
├── online
│ ├── docker-compose.yml
│ └── php
│ └── Dockerfile
└── _self
└── docker-compose.yml
这里需要做以下说明:
测试环境(dev)
和正式环境(online)
除了数据卷
不一样,其他配置都一样_self
目录表示宿主主机,上面有nginx
dev 配置
dev
环境下有php和mysql,两个app都在独立的容器中,两者通过 sock文件
或网络进行通信,以下是dev环境的docker-compose.yml
文件内容:
php1:
#build: ./php
#image: php:7.1-fpm-alpine
image: php-fpm-composer:1.0
container_name: dev_php1
expose:
- "9000"
volumes:
- "/data-dev/data1/:/data1/"
- "/data-dev/data2/:/data2/"
- "/data-dev/data2/php/conf/:/usr/local/etc/"
links:
- mysql1:server_mysql
mysql1:
image: mysql/mysql-server:5.7.20
container_name: dev_mysql1
expose:
- "11308"
volumes:
- "/data-dev/data1/:/data1/"
- "/data-dev/data2/:/data2/"
- "/data-dev/data2/mysql/conf/:/etc/mysql/"
environment:
- MYSQL_ROOT_PASSWORD=123456789
volumes
先看数据卷。以 dev_php1
容器为例,我们可以看到 宿主
的/data-dev/data1
和 /data-dev/data2
被映射到了php容器的/data1
和 /data2
目录。是的,宿主的/data-dev
目录就是专门为dev
环境划分的逻辑目录。
再看dev_mysql1
容器,道理和上述一样。
端口配置
先看dev_php1
,根据 php-fpm
配置文件中监听了9000
端口,所以开放容器的9000
端口。
mysql
配置文件中设置的是11308
端口,所以我们开放容器的11308
端口。
其实在实际使用中,两者也都支持 sock文件
方式进行连接。
自定义的php镜像
由于官方的php缺少一些扩展,所以我基于该镜像添加了扩展和compose
,Dockerfile如下:
FROM php:7.1-fpm-alpine
RUN apk add --no-cache \
libpng-dev \
&& docker-php-ext-install pdo_mysql gd zip \
&& php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
为了避免构建多层镜像又保证命令的整洁性,使用 \
(表示换行)把要执行的命令分开。
可以看到我这里添加了pdo_mysql
、gd
、zip
扩展,其中zip
镜像是安装compose必要的,且为了安装gd
扩展,系统必须要先安装libpng-dev
库。
后面四行命令是安装composer的,安装后放在了/usr/local/bin
目录下,文件名是composer
。
根据这个Dockerfile构建了名为php-fpm-composer:1.0
的镜像。
其他配置
dev_mysql1
的 MYSQL_ROOT_PASSWORD
表示数据库初始密码,如果数据库初始化过了(数据卷中已有数据)则没效了。
online配置
online
环境的docker-compose.yml
文件内容如下:
php1:
#build: ./php
#image: php:7.1-fpm-alpine
image: php-fpm-composer:1.0
container_name: online_php1
expose:
- "9000"
volumes:
- "/data-online/data1/:/data1/"
- "/data-online/data2/:/data2/"
- "/data-online/data2/php/conf/:/usr/local/etc/"
links:
- mysql1:server_mysql
mysql1:
image: mysql/mysql-server:5.7.20
container_name: online_mysql1
expose:
- "11308"
volumes:
- "/data-online/data1/:/data1/"
- "/data-online/data2/:/data2/"
- "/data-online/data2/mysql/conf/:/etc/mysql/"
environment:
- MYSQL_ROOT_PASSWORD=123456789
部署步骤
可以看到online
环境除了逻辑目录
是/data-onlie
以外,其他的配置都和dev
一样,当然容器名是不一样的。
如果我们已经成功部署了dev
环境,那么只需把/data-dev
copy一份为 /data-online
即可完成数据卷的部署,保证online的数据和dev是一样的(主要是php、mysql等app的配置一样)。
nginx的配置
本项目采取的方式是nginx
单例,所以nginx必须放在宿主主机上,稍后讨论多例nginx的配置。
目前已经有了dev
和 online
两个环境,且分别运行了php和m ysql,单例nginx模式的架构如下:
圆圈
表示逻辑主机
, 矩形框
内是英文的表示容器,英文表示容器名称。
宿主环境
(nginx)的docker-compose.yml
文件内容如下:
nginx1:
image: nginx:1.12-alpine
container_name: nginx1
ports:
- "80:80"
- "443:443"
expose:
- '80'
- '443'
volumes:
- "/data/:/data/"
- "/data1/:/data1/"
- "/data2/:/data2/"
- "/data2/nginx/conf/:/etc/nginx/"
- "/data-dev/:/data-dev/"
- "/data-online/:/data-online/"
可以看到,为了dev
、online
提供服务,需要将两个逻辑主机
的数据目录
映射到nginx容器中去,从而达到nginx与宿主主机的文件系统是一样的。
文件路径
在进行nginx配置的时候,需要非常注意的是文件路径。
在dev
逻辑主机中,网站根目录是/data1/sites/html
,这个目录对应于宿主主机的/data-dev/data1/sites/html
,那么在nginx中配置的时候,就需要特别注意。
下面是nginx 为dev
环境提供服务所写的配置信息:
...
listen 80;
server_name dev.domain.com;
root /data-dev/data1/sites/html/;
index index.html index.htm index.php;
access_log /data2/nginx/logs/dev/html_access.log main;
error_log /data2/nginx/logs/dev/html_error.log warn;
# use php-fpm.sock
location ~ \.php$ {
fastcgi_pass unix:/data-dev/data2/socks/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /data1/sites/html$fastcgi_script_name;
include fastcgi_params;
}
...
由于nginx
运行在宿主主机,所以使用的是宿主主机的文件系统:(下面的/data2
是宿主主机上的)
root /data-dev/data1/sites/html/;
access_log /data2/nginx/logs/dev/html_access.log main;
error_log /data2/nginx/logs/dev/html_error.log warn;
根据web请求流程和CGI原理,所以fastcgi在寻找文件时使用的是 dev
主机的文件系统:
fastcgi_param SCRIPT_FILENAME /data1/sites/html$fastcgi_script_name;
注意:不能写成$document_root$fastcgi_script_name,因为$document_root是宿主主机的文件系统
静态文件测试
根据上述配置文件,配置好root
路径即可进行静态文件测试。
现有两个文件,他们在宿主主机
文件系统中的路径如下:
/data-dev/data1/sites/html/index.html
/data-online/data1/sites/html/index.html
可以看到,一个在 dev
中,一个在 online
环境中
那么在dev
的文件系统中,则是:
/data1/sites/html/index.html
文件内容是:
This is dev
在online
的文件系统中,则是:
/data1/sites/html/index.html
文件内容是:
This is online
可以发现,在两个逻辑主机中,他们并不知道宿主主机的存在,也就是宿主主机对于他们来说是透明的
。
/etc/hosts
配置如下,同步修改nginx
的server_name
:
127.0.0.1 dev.domain.com
127.0.0.1 online.domain.com
进行测试:
curl dev.domain.com
curl online.domain.com
输出:
This is dev
This is online
php测试
php的测试主要看nginx是否正确使用了对应环境的php-fpm.sock
,如果你是用9000
端口通信的,那就看ip是否填对了,方式与静态页面类似,不再赘述。