CentOS LNMP WordPress自动更新需填写FTP解决方法

无论是使用阿里云还是其他云 VPS 下的 Linux + LNMP 一键安装包环境,安装 WordPress 后,遇上提示更新升级的时候,都会出现需要填写 FTP 相关信息的情况,相当不方便。不过,根据 LNMP 作者军哥的博客提示,只需要在服务器内做一些文件权限的修改变可以。

这个问题的产生,主要是网站目录的权限执行身份非文件属主身份。

解决方法如下:

假设你的 WordPress 安装目录为 /home/wwwroot/lnmp.org

用 Putty 登录 Linux VPS ,执行:chown -R www /home/wwwroot/lnmp.org

执行上面的命令就可以将 /home/wwwroot/lnmp.org 下所有文件的属主改为 www ,这样就可以解决自动更新必须填FTP的问题。

基本上按以上方法就可以解决问题,如果还不能正常成功更新,可以尝试修改 wp-config.php 文件

在 wp-config.php 中加入一行代码

define('FS_METHOD', "direct");

如此就能可以在后台点击更新升级。

使用docker-compose来部署WordPress

很早的时候想维护一个个人Blog,一开始通过 github home page + jekyll,奈何没精力再去把ruby玩溜,自己也不是个擅长改写前端页面的人,无疾而终。今天终于鼓起勇气,买了服务器和域名,部署了wordpress,毕竟wordpress易用易上手,模板也多,也就懒得自己改了。既然本Blog是运行在Docker之上的,那第一篇文章也就来说说这个吧。

部署方式介绍

  • 我的服务器安装的是Arch Linux,自己也是比较喜欢这个极简的Linux发行版。
  • 我使用了docker-compose来做镜像编排工具,nginx,mysql(mairadb),wordpress分别运行于不同的容器。
  • 托上面两个先决条件的福,下面的内容大家根据自己的实际环境,酌情选择。

准备工作

安装Docker

托Arch Linux的福,安装Docker非常简单。

pacman -S docker

安装docker-compose

同样是托Arch的福,安装依旧简单粗暴。

pacman -S docker-compose

准备配置

首先我们需要做的是准备好docker wordpress运行的用户,执行以下命令,添加一个叫wordpress的新用户,将它添加到docker用户组,并为它设置密码

useradd -m -s /bin/zsh wordpress
usermod -a -G docker wordpress
passwd wordpress

紧接着,创建一些目录,保存docker-compose配置文件,存储运行产生的文件,让数据库落地到本机而不是容器,执行以下命令

su - wordpress
cd
mkdir wordpress-compose
touch docker-compose.yml
mkdir -p wordpress-compose/db-data
mkdir -p wordpress-compose/logs/nginx
mkdir -p wordpress-compose/nginx
mkdir -p wordpress-compose/wordpress

这些目录和文件的功能分别如下:

目录或文件 含义

  • wordpress-compose 容器相关根目录
  • wordpress-compose/db-data 数据库数据存储目录
  • wordpress-compose/logs/nginx nginx存储目录
  • wordpress-compose/nginx nginx配置文件
  • wordpress-compose/wordpress wordpress本体,因为安装插件等会改变php文件

接下来我们编写必要的nginx配置文件。在wordpress-compose/nginx下新建wordpress.conf文件,文件中写入下面这些配置,一个很经典的php-fpm的nginx配置文件。

server {
    listen 80;
    server_name www.gsgtzq.com;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/wordpress-access.log;
    error_log /var/log/nginx/wordpress-error.log;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass wordpress:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

接下来就是docker-compose配置文件的编写了,首先将工作目录切换至刚刚创建的wordpress-compose目录,用自己熟悉的编辑器打开docker-compose.yml文件。

vim docker-compose.yml

先是nginx部分,我使用最新的nginx镜像,暴露80端口给本机,挂载conf.d、log、/var/www/html目录到本机,连接nginx和wordpress容器。

nginx:
        image: nginx:latest
        ports:
                - '80:80'
        volumes:
                - ./nginx:/etc/nginx/conf.d
                - ./logs/nginx:/var/log/nginx
                - ./wordpress:/var/www/html
        links:
                - wordpress
        restart: always

然后是mysql部分,我使用了mairadb的最新镜像,挂载mysql数据存储点到本机,链接mysql和wordpress容器,通过环境变量设置mysql的默认root密码。

mysql:
        image: mariadb:latest
        volumes:
                - ./db-data:/var/lib/mysql
        environment:
                - MYSQL_ROOT_PASSWORD=123345
        restart: always

最后是wordpress本体,我使用wordpress:php7.1-fpm的镜像,挂载/var/www/html目录到本机,链接连接mysql容器和wordpress,并且使用环境变量,指定mysql主机名,表前缀,和库名。

wordpress:
        image: wordpress:php7.1-fpm
        volumes:
                - ./wordpress:/var/www/html
        environment:
                - WORDPRESS_DB_NAME=wpdb
                - WORDPRESS_TABLE_PREFIX=wp_
                - WORDPRESS_DB_HOST=mysql
        links:
                - mysql
        restart: always

到此位置,docker-compose的配置文件全部编写完毕。

启动容器

编排文件已写完,接下来启动容器即可。

docker-compose up -d

当收到三个done以后,编排好的容器就正式启动了,我们现在可以访问本机的IP或域名来访问wordpress了。
我还可以使用下面这些命令来检查容器的运行情况,注意,docker-compose命令只有在刚才写好配置文件的目录下执行才有效果。

命令 含义

  • docker ps -a 查看当前所有运行的docker容器
  • docker-compose logs wordpress 查看wordpress容器的日志
  • docker-compose ps 查看当前编排好的应用的所有容器状态
  • docker-compose top 查看当前编排好的应用中各容器中的进程情况

具体还有一些其他的办法,可以通过查阅docker手册和docker-compose文档来进行使用。

结束语

到此为止,使用docker来运行wordpress已经完成,从开始折腾Docker到现在少说1个半月过去了,也是学习到了非常多的东西,目前而言公司的项目想用起docker来还是有不少难度,我思考了很多使用docker对传统部署和开发带来冲击的问题,例如对开发人员的要求其实高了很多,尤其是在运维这块,基础环境部署等等……但很希望自己能把它用好了,开发受益,运维也受益。

WordPress迁移网站目录时如何修改数据库信息

当我们搭建好网站后,如果需要给网站更换主机空间和迁移网站目录,也就是站长常说的“网站搬家”,对于新手站长来说可能会比较复杂,最近很多用户咨询:主机上的网站目录如何迁移,下面为大家详细介绍Wordpress迁移网站目录数据库信息的修改方法!

1、登陆数据库修改下配置然后移动到站点根目录

未分类

WordPress迁移网站目录数据库信息的修改方法

2、修改两个字段siteurlhome

未分类

修改两个字段siteurlhome

3、点击执行操作即可

未分类

点击执行操作

Ubuntu 16.04使用Docker部署WordPress

未分类

介绍

WordPress是基于PHP和MySQL的著名内容管理系统,根据GNU GPLv2(或更高版本)的规定分发。通常它安装在像Apache这样的Web服务器上,但也可以在使用Docker容器构建的隔离环境中运行它,特别是使用Docker Compose。本教程的主题时使用Ubuntu 16.04作为操作系统。

入门

首先,有必要安装Docker和Docker Compose。 在Ubuntu 16.04中,这可以通过两种不同的方式完成:

  • 设置存储库并从中安装,方便安装和升级任务
  • 下载DEB包并手动安装; 还允许您完全手动管理升级

在本教程中,Docker将使用存储库方法进行安装。 因此,您需要安装软件包以允许apt通过HTTPS使用存储库:

# apt install -y --no-install-recommends apt-transport-https ca-certificates curl software-properties-common

接下来,添加Docker的官方GPG密钥:

$ curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -

密钥ID应为58118E89F3A912897C070ADBF76221572C52609D,因此验证:

$ apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D

使用以下命令设置稳定存储库:

# add-apt-repository 
       "deb https://apt.dockerproject.org/repo/ 
       ubuntu-$(lsb_release -cs) 
       main"

现在可以安装Docker了。

首先,更新apt包索引:

# apt update

然后:

# apt install docker-engine
This will install docker and its daemon should start automatically.

安装 Docker Compose

安装Docker后,下一步是安装Compose,这是此过程所必需的。 只需执行命令:

# curl -L https://github.com/docker/compose/releases/download/1.11.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

更改docker-compose binary的权限:

# chmod +x /usr/local/bin/docker-compose

测试:

$ docker-compose --version

现在Docker和Docker Compose已安装并可以使用。

安装 MariaDB

创建一个空目录,例如docker_wordpress。
然后改成:

$ cd docker_wordpress

创建一个docker-compose.yml文件,该文件将启动您的WordPress博客和一个单独的MySQL实例与卷挂载数据持久性。
在此文件中,输入以下文本:

version: '2'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: wordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

接下来,在docker_wordpress文件夹中,使用以下命令启动容器:

# docker-compose up -d

这很简单,因为Docker团队确保一切都配置良好。 事实上,WordPress Docker容器中有一个脚本,它从wordpress容器中读取MYSQL_ROOT_PASSWORD变量,并使用它来连接到WordPress。

安装 PHPMyAdmin

添加PHPMyAdmin与添加数据库没有什么不同。在docker-compose.yml文件中,只需在“services”部分添加以下行:

phpmyadmin:
image: corbinu/docker-phpmyadmin
  links:
    - wordpress_db:mysql
  ports:
    - 8181:80
  environment:
    MYSQL_USERNAME: root
    MYSQL_ROOT_PASSWORD: wordpress

保存这些配置并运行docker-compose命令来创建和启动容器:

# docker-compose up -d

配置几乎完成! 使用Web浏览器,转到URL:http://SERVER_IP:8181。 它将显示PhpMyAdmin的登录屏幕。 使用在docker-compose.yml文件中配置的相同凭据进行登录。

总结

就这样!现在服务器正在运行WordPress安全和隔离的容器。虽然Docker是“开发人员工具”,但它可以用于各种项目,就像这里所示。 当然,配置文件可以通过更细致的细节进行编辑和定制,例如DNS部分和一些硬件限制,如CPU和内存使用。 祝你玩得开心!

wordpress启用memcached加速访问

Memcached 是什么?

Memcached 是一种高性能的分布式内存对象缓存系统。在动态应用,Memcached 既能提高访问的速度,同时还减低了数据库的负载。

Danga Interactive 为提升 LiveJournal.com 的速度研发了 Memcached。目前,LiveJournal.com 每天已经在向一百万用户提供多达两千万次的页面访问。而这些,是由一个由 Web 服务器和数据库服务器组成的集群完成的。Memcached 几乎完全放弃了任何数据都从数据库读取的方式,同时,它还缩短了用户查看页面的速度、更好的资源分配方式,以及 Memcache 失效时对数据库的访问速度。

WordPress 和 Memcached

由于 WordPress 默认支持 Object Cache,所以在 WordPress 实现 Memcached 就是使用 Memcached 把 WordPress 的 Object Cache 写到内存中去,下次直接从内存中读取。相比直接从数据库去读取数据,或者从 Object Cache 数据存到文件,然后从硬盘中读取,Memcached 有很大的速度优势。

WordPress 如何启用 Memcached 缓存

  1. 需要你的服务器支持,就是你的 PHP 需要安装上 Memcached 相关的扩展,注意 PHP 有两个扩展:PHP Memcache 扩展 和 PHP Memcached 扩展,两者仅仅相差一个字母 D,你可以通过 phpinfo() 这个 PHP 函数来检测,你安装的是哪个扩展。
  2. 下载object-cache.php ,点击这里下载
  3. 把下载的:object-cache.php 复制到 wordpress的wp-content目录,这里值得注意不是 wp-content/plugins/

WordPress 会自动检查在 wp-content 目录下是否有 object-cache.php 文件,如果有,直接调用它作为 WordPress 对象缓存机制。查询数据次数明显减少

开启了之前 0.201 秒内总共 30次查询

开启之后 0.205 秒内总共 9 次查询

Fail2ban防止WordPress受到xmlrpc.php CC攻击

WordPress本身是一个非常强大的CMS(内容管理系统),功能强大。但是也正是因为其强大的特性,使其很容易被利用,造成服务器的不稳定甚至崩溃。最容易遭受攻击的就是xmlrpc.php这个文件,攻击者只要每秒发送1个post请求到此文件,不出1分钟,一台512M内存Debian7系统的VPS就会崩溃,php进程和Mysql占用内存过高而导致无法访问。在尝试了网上流传的多个防攻击手段之后,fail2ban是效果最好的一个,下面就简单记录一下过程,供大家参考。

分析日志

在服务器出现异常的时候,首先去分析Nginx日志, /var/log/nginx/access.log ,从代码中可以发现如下可以IP不断发送Post请求到xmlrpc.php,每个IP的发送频率大概在2秒钟一次,严格来说频率并不高但足以让php和mysql进程崩溃。

185.188.204.16 - - [15/Jul/2017:23:51:07 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.6 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.8 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.14 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.16 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.7 - - [15/Jul/2017:23:51:08 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.12 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 499 0 "-" "*****"
185.188.204.11 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.15 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"
185.188.204.11 - - [15/Jul/2017:23:51:09 -0400] "POST /xmlrpc.php HTTP/1.0" 502 574 "-" "*****"

安装fail2ban和iptables

安装fail2ban和iptables,这样能使用ipotables对攻击进行防御,想对于其它js和php的防御方式自动化更高,更为高效。

apt-get install fail2ban iptables

设置fail2ban jail.local

使用jail.local设定

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
vi /etc/fail2ban/jail.local
[xmlrpc]
enabled = true
filter = xmlrpc
action = iptables[name=xmlrpc, port=http, protocol=tcp]
logpath = /var/log/nginx/access.log
bantime = 43600
maxretry = 2

设置fail2ban 自定义filter

vi /etc/fail2ban/filter.d/xmlrpc.conf
[Definition]
failregex = ^<HOST> .*POST .*xmlrpc.php.*
ignoreregex =

设置fail2ban jail.local

设置好之后重启fail2ban服务既可生效

service fail2ban restart

查看fail2ban日志查看防御情况

tail -f /var/log/fail2ban.log
2017-07-15 23:51:38,265 fail2ban.jail   : INFO   Creating new jail 'ssh'
2017-07-15 23:51:38,266 fail2ban.jail   : INFO   Jail 'ssh' uses Gamin
2017-07-15 23:51:38,287 fail2ban.filter : INFO   Set maxRetry = 6
2017-07-15 23:51:38,288 fail2ban.filter : INFO   Set findtime = 600
2017-07-15 23:51:38,288 fail2ban.actions: INFO   Set banTime = 600
2017-07-15 23:51:38,320 fail2ban.jail   : INFO   Creating new jail 'xmlrpc'
2017-07-15 23:51:38,320 fail2ban.jail   : INFO   Jail 'xmlrpc' uses Gamin
2017-07-15 23:51:38,321 fail2ban.filter : INFO   Added logfile = /var/log/nginx/access.log
2017-07-15 23:51:38,322 fail2ban.filter : INFO   Set maxRetry = 2
2017-07-15 23:51:38,323 fail2ban.filter : INFO   Set findtime = 600
2017-07-15 23:51:38,323 fail2ban.actions: INFO   Set banTime = 43600
2017-07-15 23:51:38,328 fail2ban.jail   : INFO   Jail 'ssh' started
2017-07-15 23:51:38,329 fail2ban.jail   : INFO   Jail 'xmlrpc' started
# 以上日志显示自定义的xmlrpc filter已经生效
2017-07-15 23:51:45,350 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.8
2017-07-15 23:51:45,361 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.9
2017-07-15 23:51:45,368 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.6
2017-07-15 23:51:45,376 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.7
2017-07-15 23:51:45,382 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.16
2017-07-15 23:51:45,387 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.14
2017-07-15 23:51:45,392 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.15
2017-07-15 23:51:45,400 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.12
2017-07-15 23:51:45,415 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.10
2017-07-15 23:51:45,426 fail2ban.actions: WARNING [xmlrpc] Ban 185.188.204.11
# 以上日志则显示成功防御对xmlrpc进行攻击的IP等情况

参考链接:https://rbgeek.wordpress.com/2014/09/11/block-wordpress-xmlprc-php-ddos-attacks-using-fail2ban/

WordPress插件:https://wordpress.org/plugins/wp-fail2ban/

Related posts:

  1. WordPress 启用HTTPS设置
  2. Wp Super Cache + Nginx规则
  3. Akismet:强大的反垃圾评论插件
  4. 浅谈博客的友情链接与链接
  5. WordPress移除静态资源版本号

使用代理服务器解决升级WordPress慢的问题

更新WordPress版本有两种方法,在后台点击自动升级或者手动下载新的版本替换旧的。为了方便,一般选择前者自动升级。不过由于自动升级使用的是国外的服务器downloads.wordpress.org,在国内自动升级wordpress的话会非常慢甚至超时失败。不过wordpress提供了可以设置代理了方法,本人在国外服务器架设了一台代理服务器,可以直接拿来用,由于代理服务器限制了只能代理wordpress.org域名,使用完后请注释掉代码,以免影响wordpress使用。

解决方法

打开wp-config.php,在底部增加如下代码:

  1. define(‘WP_PROXY_HOST’, ‘us.webres.wang’);
  2. define(‘WP_PROXY_PORT’, ‘31281’);

保存之后登录wordpress后台,切换到更新,点击升级按钮开始更新。
更新完成后请注释掉刚才加的代码,即在前面添加//,如:

  1. //define(‘WP_PROXY_HOST’, ‘us.webres.wang’);
  2. //define(‘WP_PROXY_PORT’, ‘31281’);

下次需要升级时再删除注释。
未分类

Docker部署WordPress LNMP(Nginx PHP MySQL)环境实践

Docker基于LXC实现了把软件封装到一个完整的文件系统,可以在docker容器中运行所需的一切代码,运行环境,系统工具和系统库。由于docker使用独立于主机的文件系统,可以确保软件在不同的主机环境中仍然保持运行环境不变。docker与主机共用一个操作系统内核,使用docker容器具有轻量级的特点,能占用更少的内存快速启动容器。

下面我们学习使用docker来部署目前非常流行的博客系统wordpress的运行环境nginx php mysql(作者wordpress博客devops.webres.wang正是运行在docker容器中)。那么docker部署wordpress的运行环境与我们传统上直接在主机配置环境有什么区别?我们从开发和运维人员角度来说明。运维使用docker制作好wordpress容器,分发给开发人员,开发人员随即只需一个命令就可以部署好完全一样的运行环境,从此只需要关注代码本身,而不再需要把时间浪费在配置环境上。而同时,docker容器确保了开发环境与生产环境的一致性,极大减少由于开发环境与生产环境不一致出现的各种问题。而由于docker容器可以快速部署的特点,运维人员可以很轻松的对服务进行伸缩和扩展。

那么如何使用docker部署wordpress的运行环境?大概步骤是分别编写nginx php mysql的Dockerfile文件,从这些Dockerfile文件中生成各自的镜像,然后使用docker-compose工具来统一管理nginx php mysql。为了能只使用docker-compose.yml一个文件就能快速部署wordpress环境,我们把Dockerfile及环境的相关配置保存到阿里云的Kelude(git代码托管code.aliyun.com),然后使用阿里云的Docker镜像仓库(cr.console.aliyun.com)从Kelude拉取Dockerfile自动构建镜像。国外此类服务有hub.docker.com和github.com,使用阿里云的是因为可以免费设置私有git仓库和私有镜像,因为我们可能需要保存一些不便公开的私密信息(如网站证书,密码)。当然你也可以不使用这类服务,直接把镜像保存到本地环境中。下面开始一步步介绍。

准备工作

使用阿里云Kelude

到https://code.aliyun.com/创建一个项目,如Dockerfile。之后我们把wordpress环境的所有相关Dockerfile及配置文件放置到centosbz目录。

使用阿里云镜像仓库

阿里云docker镜像仓库地址为https://cr.console.aliyun.com,用来存放docker镜像,可以在本地push镜像上去,也可以从Kelude拉取Dockerfile自动构建镜像。我们先登录,然后新建一个namespace,如centos-bz,之后所有的nginx,php,mysql镜像将存放在这个namespace下。

安装docker-compose

需要在运行docker容器的主机上安装docker-compose,可以参照官方文档手动安装,也可以使用ezhttp的一键安装工具(推荐)安装。如:

wget webres.wang/ezhttp.zip
unzip ezhttp.zip
cd ezhttp-master
./start.sh

之后会弹出一个菜单,输入2选择Some Useful Tools,然后输入18选择安装docker和compose。

编写Dockerfile

clone以上在阿里云Kelude创建的Dockerfile镜像到本地,在此项目中创建webres.wang,然后在webres.wang目录分别创建mysql,nginx,php目录,用于存放它们各自Dockerfile及配置文件。
这里我们还约定以下目录:

  • /home/docker/nginx/logs/webres.wang:存放devops.webres.wang网站的日志
  • /home/docker/nginx/www/webres.wang: 存放devops.webres.wang网站的文件
  • /home/docker/php: 存放php-fpm的日志
  • /home/docker/mysql:mysql data目录
  • nginx Dockerfile

    在nginx目录创建Dockerfile文件,写入如下内容:

    # 从debian:jessie镜像基础上安装nginx
    FROM debian:jessie
    
    # 声明此Dockerfile维护者的邮箱,有什么问题可以发到此邮件寻问
    LABEL maintainer "[email protected]"
    
    # 定义软件版本及编译工具变量
    ENV NGINX_VERSION 1.10.3
    ENV OPENSSL_VERSION 1.0.2h
    ENV ZLIB_VERSION 1.2.11
    ENV PCRE_VERSION 8.40
    ENV CONCAT_VERSION 1.2.2
    ENV BUILD_TOOLS wget gcc make g++
    ENV SRC_DIR /opt/nginx
    
    # 切换到工作目录
    WORKDIR ${SRC_DIR}
    
    # 开始编译nginx,我们这里使用编译安装nginx而不是使用官方提供的nginx镜像是因为这里使用到了第三方的concat模块,只能编译了。
    # 把所有的安装命令都写在一个RUN指令中是因为这样可以减小镜像层数,缩减镜像大小。推荐使用反斜杠和&&把所有的安装命令放置到一行中。
    RUN apt-get update 
        && apt-get -y --no-install-recommends install ca-certificates ${BUILD_TOOLS} 
        && wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz  
        && wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz  
        && wget http://www.zlib.net/zlib-${ZLIB_VERSION}.tar.gz  
        && wget https://ftp.pcre.org/pub/pcre/pcre-${PCRE_VERSION}.tar.gz  
        && wget https://github.com/alibaba/nginx-http-concat/archive/${CONCAT_VERSION}.tar.gz -O nginx-http-concat-${CONCAT_VERSION}.tar.gz  
        && tar xf nginx-${NGINX_VERSION}.tar.gz  
        && tar xf openssl-${OPENSSL_VERSION}.tar.gz  
        && tar xf zlib-${ZLIB_VERSION}.tar.gz  
        && tar xf pcre-${PCRE_VERSION}.tar.gz  
        && tar xf nginx-http-concat-${CONCAT_VERSION}.tar.gz  
        && cd nginx-${NGINX_VERSION}  
        && ./configure --prefix=/usr/local/nginx --with-pcre=../pcre-${PCRE_VERSION} 
                    --with-zlib=../zlib-${ZLIB_VERSION} 
                    --with-http_ssl_module 
                    --with-openssl=../openssl-${OPENSSL_VERSION} 
                    --add-module=../nginx-http-concat-${CONCAT_VERSION}  
        && make -j$(nproc) 
        && make install 
        && rm -rf ${SRC_DIR} 
        && apt-get purge -y --auto-remove ${BUILD_TOOLS} 
        && rm -rf /var/lib/apt/lists/* 
    
    # 把构建上下文目录conf,即Dockerfile/webres.wang/nginx/conf目录下的文件复制到容器的/usr/local/nginx/conf目录。
    COPY conf/ /usr/local/nginx/conf/
    
    # 定义启动容器时运行的命令
    ENTRYPOINT ["/usr/local/nginx/sbin/nginx"]
    
    EXPOSE 80 443
    

    对于conf目录下的nginx配置文件,需要把日志,网站目录更改为以下约定的目录位置。

    php-fpm Dockerfile

    创建Dockerfile/webres.wang/php-fpm目录,在此目录下创建Dockerfile文件,内容如下:

    FROM debian:jessie
    LABEL maintainer "[email protected]"
    
    # 定义软件版本,编译工具,依赖等变量
    ENV PHP_VERSION 5.6.30
    ENV BUILD_TOOLS m4 
                   autoconf 
                   autoconf2.13 
                   openssl 
                   wget 
                   gcc 
                   make
    
    ENV BUILD_DEPS libcurl4-gnutls-dev 
                   libxml2-dev 
                   zlib1g-dev 
                   libpcre3-dev 
                   libjpeg-dev 
                   libpng12-dev 
                   libfreetype6-dev 
                   libmhash-dev 
                   libmcrypt-dev 
                   libssl-dev 
                   libtool
    
    ENV PHP_LOCATION /usr/local/php
    ENV BUILD_ARG   --prefix=${PHP_LOCATION} 
                    --with-config-file-path=${PHP_LOCATION}/etc 
                    --enable-fpm 
                    --enable-bcmath 
                    --with-pdo_sqlite 
                    --with-gettext 
                    --with-iconv 
                    --enable-ftp 
                    --with-sqlite3 
                    --enable-mbstring 
                    --enable-sockets 
                    --enable-zip 
                    --enable-soap 
                    --with-openssl 
                    --with-zlib 
                    --with-curl 
                    --with-gd 
                    --with-jpeg-dir 
                    --with-png-dir 
                    --with-freetype-dir 
                    --with-mcrypt 
                    --with-mhash 
                    --with-mysql=mysqlnd 
                    --with-mysqli=mysqlnd 
                    --with-pdo-mysql=mysqlnd 
                    --without-pear 
                    --with-libdir=lib64 
                    --enable-opcache 
                    --disable-cgi
    
    ENV SRC_DIR /opt/php
    
    WORKDIR ${SRC_DIR}
    
    # 开始编译安装php
    RUN apt-get update 
        && apt-get -y --no-install-recommends install ${BUILD_DEPS} ${BUILD_TOOLS} 
        && wget http://php.net/distributions/php-${PHP_VERSION}.tar.gz 
        && tar xf php-${PHP_VERSION}.tar.gz 
        && cd php-${PHP_VERSION} 
        && ln -s /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/libssl.so 
        && ln -s /usr/lib /usr/lib64 
        && ./configure ${BUILD_ARG} 
        && make -j$(nproc) 
        && make install 
        && cp php.ini-production ${PHP_LOCATION}/etc/php.ini 
        && cp ${PHP_LOCATION}/etc/php-fpm.conf.default ${PHP_LOCATION}/etc/php-fpm.conf 
        && rm -rf ${SRC_DIR} 
        && apt-get purge -y --auto-remove ${BUILD_TOOLS} 
        && rm -rf /var/lib/apt/lists/* 
    
    
    WORKDIR ${PHP_LOCATION}/etc/
    
    # 配置php-fpm,即使用sed工具编辑php-fpm.conf和php.ini文件,这里的php-fpm相关配置命令不与上面的编译命令合在一起来减小层数是因为
    # 配置文件可能会改动比较多,这样分开当配置文件更改时可以直接使用缓存跳过编译步骤,加快构建速度。
    RUN set_php_variable(){ 
            local key=$1; 
            local value=$2; 
            if grep -q -E "^$keys*=" php.ini;then 
                sed -i -r "s#^$keys*=.*#$key=$value#" php.ini; 
            else 
                sed -i -r "s#;s*$keys*=.*#$key=$value#" php.ini; 
            fi; 
            if ! grep -q -E "^$keys*=" php.ini;then 
                echo "$key=$value" >> php.ini; 
            fi; 
        } 
        && BASE_DIR=/home/docker/php 
        && set_php_variable disable_functions "dl,eval,assert,exec,popen,system,passthru,shell_exec,escapeshellarg,escapeshellcmd,proc_close,proc_open" 
        && set_php_variable expose_php Off 
        && set_php_variable error_log ${BASE_DIR}/php_errors.log 
        && set_php_variable request_order  "CGP" 
        && set_php_variable cgi.fix_pathinfo 0 
        && set_php_variable short_open_tag on 
        && set_php_variable date.timezone Asia/Chongqing 
        && sed -i 's/^user =.*/user = www-data/' php-fpm.conf 
        && sed -i 's/^group =.*/group = www-data/' php-fpm.conf 
        && sed -i "s#;slowlog = log/$pool.log.slow#slowlog = ${BASE_DIR}/$pool.log.slow#" php-fpm.conf 
        && sed -i 's/;request_slowlog_timeout = 0/request_slowlog_timeout = 5/' php-fpm.conf 
        && sed -i 's/^pm.max_children.*/pm.max_children =20/' php-fpm.conf 
        && sed -i 's/^pm.start_servers.*/pm.start_servers =5/' php-fpm.conf 
        && sed -i 's/^pm.min_spare_servers.*/pm.min_spare_servers =3/' php-fpm.conf 
        && sed -i 's/^pm.max_spare_servers.*/pm.max_spare_servers =8/' php-fpm.conf 
        && sed -i '/[global]/adaemonize =no' php-fpm.conf 
        && sed -i 's/^listen.*/listen =0.0.0.0:9000/' php-fpm.conf 
        && echo "[opcache]n 
                zend_extension=opcache.son 
                opcache.memory_consumption=128n 
                opcache.interned_strings_buffer=8n 
                opcache.max_accelerated_files=4000n 
                opcache.revalidate_freq=60n 
                opcache.fast_shutdown=1 n" >> php.ini
    
    ENTRYPOINT ["/usr/local/php/sbin/php-fpm"]
    
    EXPOSE 9000    
    

    mysql Dockerfile

    创建Dockerfile/webres.wang/mysql/Dockerfile文件,内容如下:

    FROM mysql:5.6
    LABEL maintainer "[email protected]"
    COPY my.cnf /etc/mysql/my.cnf
    

    这个Dockerfile非常简单,直接使用了官方的mysql镜像,唯一区别是我们使用自己定义的my.cnf配置文件。
    对于my.cnf配置文件,需要把日志,data目录指向/home/docker/mysql,一个my.cnf示例文件如下:

    # Generated by EZHTTP at 2016-02-03 01:05:29
    
    [mysql]
    
    # CLIENT #
    port                           = 3306
    socket                         = /home/docker/mysql/mysql.sock
    
    [mysqld]
    
    # GENERAL #
    port                           = 3306
    user                           = mysql
    default-storage-engine         = InnoDB
    socket                         = /home/docker/mysql/mysql.sock
    pid-file                       = /home/docker/mysql/mysql.pid
    skip-name-resolve
    
    # MyISAM #
    key-buffer-size                = 32M
    
    # INNODB #
    #innodb-flush-method            = O_DIRECT
    innodb-log-files-in-group      = 2
    innodb-log-file-size           = 64M
    innodb-flush-log-at-trx-commit = 2
    innodb-file-per-table          = 1
    innodb-buffer-pool-size        = 1G
    
    # CACHES AND LIMITS #
    tmp-table-size                 = 32M
    max-heap-table-size            = 32M
    query-cache-type               = 0
    query-cache-size               = 0
    max-connections                = 300
    thread-cache-size              = 50
    open-files-limit               = 1024
    table-definition-cache         = 100
    table-open-cache               = 400
    
    
    # SAFETY #
    max-allowed-packet             = 16M
    max-connect-errors             = 1000000
    
    # DATA STORAGE #
    datadir                        = /home/docker/mysql
    
    # LOGGING #
    log-error                      = /home/docker/mysql/mysql-error.log
    log-queries-not-using-indexes  = 1
    slow-query-log                 = 1
    slow-query-log-file            = /home/docker/mysql/mysql-slow.log
    
    # BINARY LOGGING #
    log-bin = /home/docker/mysql/mysql-bin
    server-id = 1
    expire-logs-days = 14
    sync-binlog = 1
    

    构建镜像

    把上一步创建的文件推送到阿里云的Kelude。然后我们登录阿里云的docker镜像仓库cr.console.aliyun.com。这里以设置自动构建nginx镜像为例,php和mysql镜像构建设置类似。
    1.点击左侧“镜像列表”,在右侧点击仓库镜像,如图:
    虚拟化技术
    2.在仓库镜像创建对话框中,说明如下:
    地域:选择离部署docker主机最近的位置,国内的话选择华东1或华东2。
    Namespace和仓库名称:这里选择centos-bz,nginx。
    设置代码源:我们这里选择阿里云code。
    构建设置:勾选代码变更时自动构建镜像,海外机器构建(因为国内主机apt-get安装软件时较慢),Dockerfile路径填/webres.wang/nginx
    完成后点击创建仓库按钮。
    如图:
    虚拟化技术
    3.回到镜像列表,找到nginx镜像,点击管理。
    4.左侧点击“构建”,右侧点击“立即构建”开始首次构建,之后我们更改Dockerfile及配置文件到Kelude之后就会自动构建了。
    5.查看日志,查看构建进程。
    然后继续完成php,mysql的镜像构建设置。

    启动环境

    为了方便统一管理nginx,php,mysql的启动,我们使用docker-compose工具。我们只需要编写一个docker-compose.yml文件,然后使用docker-compose工具就可以快速启动docker容器了。之后把docker-compose.yml传输到任意一台支持docker环境的主机中就可以快速配置wordpress的运行环境。

    docker-compose.yml

    把docker-compose.yml文件放置在/home/docker目录下。

    version: '3'
    # 定义三个服务nginx,php,mysql
    services:
        nginx:
            # 依赖php服务,意味着在启动nginx之前先启动php
            depends_on:
                - php
            # nginx镜像的路径
            image: registry.cn-hangzhou.aliyuncs.com/centos-bz/nginx
            # 容器的/home/docker/nginx目录挂载主机中的/home/docker/nginx目录,
            # 这样使nginx容器把网站文件和目录存放到主机目录中,持久化和方便管理
            volumes:
                - /home/docker/nginx:/home/docker/nginx
            # nginx意外退出时自动重启
            restart: always
    
            # 映射80和443端口
            ports:
                - "80:80"
                - "443:443"
    
            # 容器名称
            container_name: nginx    
        php:
            depends_on:
                - mysql
            image: registry.cn-hangzhou.aliyuncs.com/centos-bz/php-fpm
            restart: always
            volumes:
                - /home/docker/nginx/www:/home/docker/nginx/www
                - /home/docker/php:/home/docker/php
            container_name: php   
    
        mysql:
            image: registry.cn-hangzhou.aliyuncs.com/centos-bz/mysql
            volumes:
                - /home/docker/mysql:/home/docker/mysql
            restart: always
            # 设置MYSQL_ROOT_PASSWORD环境变量,这里是设置mysql的root密码。这里为root。
            environment:
                MYSQL_ROOT_PASSWORD: root
            container_name: mysql
    

    启动环境

    在/home/docker目录执行:

    docker-compose up
    

    查看nginx,php,mysql是否正常启动,如果正常,ctrl-c停止,再执行:

    docker-compose up -d
    

    这里compose命令就在后台启动了。
    执行docker ps查看容器运行状态。

    连接问题

    容器之间可以通过容器名称来连接,如nginx配置文件中连接php的代码fastcgi_pass php:9000,网站数据库配置文件使用mysql:3306。

    日常运维

    迁移

    比如A主机迁移到B主机。只需要三步。

  • 1.打包A主机的/home/docker目录,传输到B主机相同位置
  • 2.配置B主机docker环境
  • 3.在B主机的/home/docker目录下执行docker-compose up -d
  • 导出导入数据库

    把centos.sql.gz数据库文件导入到centos数据库:

    gunzip < centos.sql.gz | docker exec -i mysql mysql -uroot -proot centos
    

    把centos数据库导出到centos.sql.gz

    docker exec -i mysql mysqldump -uroot -proot centos | gzip > centos.sql.gz
    

    备份

    推荐使用ezhttp一键备份设置:

    wget webres.wang/ezhttp.zip
    unzip ezhttp.zip
    cd ezhttp-master
    ./start.sh
    

    之后会弹出一个菜单,输入2选择Some Useful Tools,然后输入14选择备份设置。需要注意的是在设置mysql使用mysqldump备份时,在提示输入mysql bin directory时,输入docker exec /usr/bin/。

    快速入门: Compose和WordPress

    我们可以使用docker compose很容易地在使用docker容器的隔离环境运行wordpress。本快速指南演示如何使用compose配置和运行wordpress。

    定义项目

    1.创建一个空的项目目录。
    可以用容易记住和理解的名称命名此项目。这个目录是应用程序镜像的上下文。此目录应该只包含用于构建那个镜像的资源。
    2.切换目录到项目目录。
    例如,如果命名项目目录为my_wordpress:

    1. cd my_wordpress/

    3.创建启动wordpress博客的docker-compose.yml文件,以及为了数据持久性挂载一个数据卷的独立的mysql实例:

    1. version: ‘2’
    2.  
    3. services:
    4.    db:
    5.      image: mysql:5.7
    6.      volumes:
    7.        – db_data:/var/lib/mysql
    8.      restart: always
    9.      environment:
    10.        MYSQL_ROOT_PASSWORD: wordpress
    11.        MYSQL_DATABASE: wordpress
    12.        MYSQL_USER: wordpress
    13.        MYSQL_PASSWORD: wordpress
    14.  
    15.    wordpress:
    16.      depends_on:
    17.        – db
    18.      image: wordpress:latest
    19.      ports:
    20.        – "8000:80"
    21.      restart: always
    22.      environment:
    23.        WORDPRESS_DB_HOST: db:3306
    24.        WORDPRESS_DB_PASSWORD: wordpress
    25. volumes:
    26.     db_data:

    注意:docker数据卷db_data将保持由wordpress对mysql的更新的数据。

    构建项目

    现在从项目目录执行docker-compose -up命令。
    这个命令将拉取所需的镜像和启动wordpress和数据库容器。

    1. $ docker-compose up -d
    2. Creating network "my_wordpress_default" with the default driver
    3. Pulling db (mysql:5.7)…
    4. 5.7: Pulling from library/mysql
    5. efd26ecc9548: Pull complete
    6. a3ed95caeb02: Pull complete
    7. Digest: sha256:34a0aca88e85f2efa5edff1cea77cf5d3147ad93545dbec99cfe705b03c520de
    8. Status: Downloaded newer image for mysql:5.7
    9. Pulling wordpress (wordpress:latest)…
    10. latest: Pulling from library/wordpress
    11. efd26ecc9548: Already exists
    12. a3ed95caeb02: Pull complete
    13. 589a9d9a7c64: Pull complete
    14. Digest: sha256:ed28506ae44d5def89075fd5c01456610cd6c64006addfe5210b8c675881aff6
    15. Status: Downloaded newer image for wordpress:latest
    16. Creating my_wordpress_db_1
    17. Creating my_wordpress_wordpress_1

    浏览器配置wordpress

    在浏览器中打开ip:8000,开始配置wordpress。