Docker: 使用容器技术快速搭建独立WordPress环境
现在Docker CI 什么的这么火,我也赶紧学一套。熟话说,学以致用,那么我就把自己使用的wordpress-nginx-php-mysql一套容器化了。
Docker是目前最火的开源容器解决方案。你把他理解为基于软件层面的虚拟机技术,类似于目前安卓平台的双开,多开软件的实现效果。
阅读此文,你需要先学习基本的docker知识,docker-compose脚本的编写。
分析:
整个服务器主要分了三块,一个是web服务器,一个是php,最后是mysql。也就是需要创建3个Docker容器来存放这3部分,当然你喜欢的话也可以塞一起,但不推荐这么做。
基础镜像
现在我们需要找几个合适的基础镜像用于构建容器
- 1.web服务器用的是nginx,直接使用了官方仓库的最新版本(hub.c.163.com/library/nginx:latest)
- 2.php-fpm模块不能直接使用官方的,因为php-fpm还需要安装php-mysql模块,直接用官方的话没办法连接数据库的,所以github上找了一个第三方库(nanoninja/php-fpm) 这个库用的人很多,而且脚本是开源并基于此自动构建的,所以还是很安全的。
- 3.mysql的话也可以直接用官方仓库的
配置容器
现在容器有了,但这些容器实例化后使用的都是默认的配置,你想一个刚安装好的nginx跑起来后你能访问什么页面,貌似就一个欢迎页面吧。
我们可以使用docker的links功能,将我们宿主机上的已经写好的配置文件映射到容器内,或者直接拷贝到容器内部
- 1.一个ngixn服务器配置,你需要提供一个default.conf配置文件,包含了你的网站的一些配置,比如域名啊,端口号啊,网站根路径啊
参考配置
#监听80端口(也就是http) 重写url 全部跳转到https server { listen 80 ; server_name blog.coderstory.cn; rewrite ^(.*) https://$server_name$1 permanent; } #监听443端口(也就是https) server { server_name blog.coderstory.cn; #配置网站根目录 root /var/www/html/htdocs; #配置网站的首页 index index.html index.htm index.nginx-debian.html; #location ^~ /.well-known/acme-challenge/ { # alias /var/www/html/.well-known/acme-challenge/; # try_files $uri =404; #} # 配置URL重写 解决wp中文章页404 location / { if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) { return 403; } #禁止指定UA及UA为空的访问 if ($http_user_agent ~ "CPython|python|Firefox/29.0|FeedDemon|JikeSpider|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Microsoft URL Control|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|YisouSpider|HttpClient|MJ12bot|heritrix|EasouSpider|LinkpadBot|Ezooms|^$" ) { return 403; } #禁止非GET|HEAD|POST方式的抓取 if ($request_method !~ ^(GET|HEAD|POST)$) { return 403; } if (-f $request_filename/index.html){ rewrite (.*) $1/index.html break; } if (-f $request_filename/index.php){ rewrite (.*) $1/index.php; } if (!-f $request_filename){ rewrite (.*) /index.php; } #检查url是否合法(是否存在) 不存在的返回404页面 try_files $uri $uri/ =404; } #配置URL重写 后台管理页面404的问题 rewrite /wp-admin$ $scheme://$host$uri/ permanent; #配置PHP页面的处理方法 转发到php location ~ \.php$ { fastcgi_pass php7.1:9000; add_header Strict-Transport-Security max-age=63072000; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } #SSL 配置段 包括开启ssl 监听端口 以及证书路径 listen 443 ssl http2 default_server; ssl on; ssl_certificate /var/www/html/mypem.pem; ssl_certificate_key /var/www/html/mykey.key; ssl_prefer_server_ciphers on; ssl_dhparam /var/www/html/dhparam.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4"; keepalive_timeout 70; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; #ssl_stapling on; #ssl_stapling_verify on; ssl_trusted_certificate /var/www/html/chain.pem; #add_header Public-Key-Pins 'pin-sha256="TOBBREP700HCbZjmW8CUdvJCjF/Nsz8Hrt4GhqQAXdk="; max-age=2592000; includeSubDomains'; }
- 2.php模块默认不需要额外的配置,自动监听9000端口
- 3.mysql数据库也不需要额外的配置,默认的数据库访问用户名密码什么的都是动态配置的
当然,如果你想自定义一些额外的配置,则你只要提供相应的配置文件,然后在构建容器的时候复制到容器内部就行了。
构建docker-compose.yml
因为整个项目包含了三个容器,每次开启关闭都是操作三次比较麻烦,所以需要一个统一管理工具docker-compose。
它可以批量化的处理多个容器。
docker-compose需要自己写一个配置文件.配置文件并不多,参考如下配置你可以看到一共定义了三个容器:nginx mysql php7.1
容器定义又包含如下属性:
1.image 表是引用的镜像来源
2.ports 表是端口映射,比如 - "80:80" 表是绑定宿主机的80端口和容器nginx的80端口,访问宿主机的80端口就等于访问nginx上的80端口
3.volumes 表是挂载数据卷,宿主机上的指定文件会共享到容器中,如果容器中已经存在则覆盖,你可以理解为引用关系。有些带了 ":ro" 的后缀,表是这个是只读挂载,容器中能查看这个文件但不能修改。
4.environment 是用来设置环境变量的
5.expose 表示开放端口,但这个端口只能在容器间访问,外部是访问不到的。
version: '2' services: nginx: image: hub.c.163.com/library/nginx:latest ports: - "80:80" - "443:443" volumes: # 挂载网站的目录 - ./app:/var/www/ # 挂载日志目录 - ./docker/logs:/var/log/nginx/ # nginx configs - ./docker/nginx/:/etc/nginx/:ro - ./docker/letsencrypt:/etc/letsencrypt:ro mysql: image: hub.c.163.com/library/mysql:latest expose: - "3306" volumes: - ./docker/mysql:/var/lib/mysql environment: - MYSQL_DATABASE=wpp - MYSQL_USER=root - MYSQL_PASSWORD=password - MYSQL_ROOT_PASSWORD=password php7.1: image: nanoninja/php-fpm links: - mysql volumes: # app - ./app:/var/www/ # log - ./docker/logs:/var/log/ - ./docker/php:/etc/php/
整个配置的目录结构
app目录是网站的目录,chained.pem之类的是ssl的证书,htdocs才是网站主题的根目录
config下包含了nginx配置,数据库目录以及日志目录
docker-compose.yml是构建配置文件
coderstory@jdu4e00u53f7:~/dockerfile$ tree -L 3 . ├── app │ └── html │ ├── chained.pem │ ├── chain.pem │ ├── dhparam.pem │ ├── htdocs │ ├── mykey.key │ └── mypem.pem ├── config │ ├── logs │ │ ├── access.log │ │ └── error.log │ ├── mysql │ │ ├── auto.cnf │ │ ├── debian-5.7.flag │ │ ├── ib_buffer_pool │ │ ├── ibdata1 │ │ ├── ib_logfile0 │ │ ├── ib_logfile1 │ │ ├── ibtmp1 │ │ ├── mysql │ │ ├── performance_schema │ │ ├── sys │ │ └── wp │ └── nginx │ └── default.conf └── docker-compose.yml
创建容器实例
终端下执行
docker-compose up
它会自动下载相应的镜像并创建实例,创建网络,映射文件等等。。。
coderstory@jdu4e00u53f7:~/dockerfile$ docker-compose up dockerfile_mysql_1 is up-to-date dockerfile_php7.1_1 is up-to-date dockerfile_nginx_1 is up-to-date Attaching to dockerfile_mysql_1, dockerfile_php7.1_1, dockerfile_nginx_1 mysql_1 | 2017-10-14T05:34:23.143720Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). mysql_1 | 2017-10-14T05:34:23.145248Z 0 [Note] mysqld (mysqld 5.7.18) starting as process 1 ... mysql_1 | 2017-10-14T05:34:23.152471Z 0 [Note] InnoDB: PUNCH HOLE support available
参考
docker-compose配置
https://github.com/nanoninja/docker-nginx-php-mysql
网易docker
https://c.163.com/hub