面向WEB开发人员的Docker(五):部署开发WordPress

前面介绍了Docker的一些基本知识和使用,对于新技术或者新系统想去尝试运行起来,Docker是一个最佳的选择,上手容易,抛弃也容易,如果系统或者应用运行起来后不需要了可以直接删除即可,对宿主机没有任何的影响,也不会受到宿主机环境的干扰。本文将分享如何使用Docker构建WordPress环境,并运行起来。

WordPress是2003年首次发布的基于PHPMySQL的开放源代码内容管理系统。它为40%的网站提供支持,受到许多Web主机的支持,易于设置,并提供数千个免费主题和插件。

对于大多数人来说,WordPress是一个博客系统,其实不然,可以为以下需求提供解决方案:

  • 可以作为网站的CMS,编辑内容,生成静态网站
  • 作为服务器端,为前端提供API,如Vue、React、Angular等
  • 构建门户、社区、视频等内容网站
  • ......

即使你不使用(或不想使用)WordPress,本文主要分享Docker如何构建一个运行环境来执行代码,环境配置对于开发来说必不可少,但Docker值得你去尝试。

本章中创建的文件包含在 https://github.com/QuintionTang/docker-wordpress 提供的示例代码存储库的wordpress目录中

环境要求

要运行WordPress需要配置的环境:

  • Web服务器,通常为Apache
  • PHP运行时和扩展,然后相应地配置Web服务器
  • MySQL或MariaDB定义一个供WordPress使用的新数据库
  • WordPress本身,以及所有必需的主题和插件。

XAMPP之类的工具可以降低环境的配置难度,但是,有了Docker,你只需要几分钟就可以运行WordPress并开发代码。

Windows用户还将发现WordPress在基于Docker的基于Linux的文件系统上的运行要比本地NTFS驱动器快得多。

Docker配置

需要提取两个Docker镜像:

  • wordpress:最新的镜像是个不错的选择,它提供了Debian Linux、Apache、PHP和WordPress的稳定版本。
  • mysql:wordpress数据库,选择8.0

启动这两个镜像,并加入Docker网络中wpnet

Docker volumes

创建两个Docker volumes:

  • wpdata:存储数据文件,在MySQL容器中挂载到/var/lib/mysql
  • wpfiles:WordPress应用程序文件夹,对应容器Apache服务器根目录中/var/www/html

可能有人会觉得挂载wpfiles卷是一种反模式,这样WordPress容器不再是无状态的。不过WordPress并不是一个无状态的应用程序。为了开发目的,Docker被用来模拟一个活动服务器环境。

挂载wpfiles卷有很多好处:

  • Docker的启动速度更快:这样无需每次启动容器时都复制核心WordPress文件

  • WordPress应用程序可以自动更新:这将在安装中发生,因此在开发期间对其进行复制非常有用

如果不挂载wpfiles卷,则需要经常运行docker pull wordpress以下载最新的应用程序镜像。

挂载开发目录

wp-content子目录将在主机PC上的项目目录中创建。对应WordPress容器的/var/www/html/wp-content目录,目录包含所有插件、主题和上传的资源。

WordPress开发人员一般只需在wp-content目录中创建和修改文件。

另外,对于项目开发,就需要将wp-content文件提交到Git仓库更加容易,因为这个目录是宿主机PC上唯一的WordPress文件夹。

localhost域名替换

WordPress将启动在localhost:8001域上,在实际开发中如果涉及多个站点,不希望用端口进行切换,同时也会带来一些问题。

  • 浏览器可能会缓存来自一个站点的文件,并在另一个站点上显示它们。
  • WordPress将访问域名存储在其数据库中,因此使用一个和生产环境一致的域名可以避免一些问题。

为了避免以上的问题,可以在文件中配置其他域以供开发使用,这就涉及更改本机hosts

  • 在Linux和macOS上,修改文件:/etc/hosts
  • 在Windows上,修改文件:C:\Windows\System32\drivers\etc\hosts

在主机文件的底部添加一行,例如 127.0.0.1 devpoint.wordpress 并保存。对于 Windows 用户必须运行nbtstat -R或重新启动。

这样,就可以使用 http://devpoint.wordpress 进行访问,而不是http://localhost,实际上两者都解析到 127.0.0.1

修改 hosts ,是前端经常用来模拟一个真实访问常用的手段。

docker run --mount "src=wpfiles,target=/var/www/html" -v $PWD/wp-content:/var/www/html/wp-content

$PWD引用Linux和macOS上的当前目录。它在Windows上不可用,因此必须使用正斜杠表示法指定完整路径,如下:

docker run --mount "src=wpfiles,target=/var/www/html" -v /c/projects/wordpress/wp-content:/var/www/html/wp-content

Docker Compose配置

Docker Compose是一个用于管理具有关联volumes和网络的多个容器的工具。单个配置文件,通常命名为docker-compose.yml,定义容器,并可以在必要时覆盖Dockerfile设置。详细的介绍请参阅《面向WEB开发的Docker(二):什么是Docker、镜像、编排?

在项目目录下创建目录 wordpress

mkdir wordpress
cd wordpress

这里将使用Docker Compose,在目录中创建docker-compose.yml文件,代码如下:

version: "3" # 表示该 Docker-Compose 文件使用的版本为3
services:
    mysql:
        image: mysql:8
        container_name: mysql
        environment:
            - MYSQL_DATABASE=wpdb
            - MYSQL_USER=wpdbuser
            - MYSQL_PASSWORD=devpoint
            - MYSQL_ROOT_PASSWORD=devpointCn
        volumes:
            - wpdata:/var/lib/mysql
        ports:
            - "3306:3306"
        networks:
            - wpnet
        restart: on-failure
    wordpress:
        image: wordpress
        container_name: wordpress
        depends_on:
            - mysql
        environment:
            - WORDPRESS_DB_HOST=mysql
            - WORDPRESS_DB_NAME=wpdb
            - WORDPRESS_DB_USER=wpdbuser
            - WORDPRESS_DB_PASSWORD=devpoint
        volumes:
            - wpfiles:/var/www/html
            - ./wp-content:/var/www/html/wp-content
        ports:
            - "80:80"
        networks:
            - wpnet
        restart: on-failure
volumes:
    wpdata:
    wpfiles:
networks:
    wpnet:

下面就来对上面的代码做个详细的介绍:

环境变量

MySQL环境变量包括MYSQL_DATABASEMYSQL_USERMYSQL_PASSWORDMYSQL_ROOT_PASSWORD

  • MYSQL_DATABASE:数据库名称,这里定义为 wpdb
  • MYSQL_USER:数据库用户名称,这里定义为 wpdbuser
  • MYSQL_PASSWORD:数据库连接密码,定义为devpoint
  • MYSQL_ROOT_PASSWORD:数据库root用户密码,定义为devpointCn,在应用程序连接中不会用到 root 用户,但对于备份数据或执行其他数据库维护就需要,因此这里也进行了定义

接下来设置 WordPress 的环境变量,包括WORDPRESS_DB_HOSTWORDPRESS_DB_NAMEWORDPRESS_DB_USERWORDPRESS_DB_PASSWORD

  • WORDPRESS_DB_HOST:连接地址,这里我们定义为mysql
  • WORDPRESS_DB_NAME:连接数据库名称,上面定义的是 wpdb
  • WORDPRESS_DB_USER:连接数据库用户名称,这里为 wpdbuser
  • WORDPRESS_DB_PASSWORD:对应的数据库连接密码,为devpoint

端口暴露

MySQL的端口3306是暴露给宿主机PC的,所以它可以连接和检查数据库使用任何MySQL客户端。

ports:
      - "3306:3306"

上面代码的意思是容器中的3306端口和宿主机的3306端口对应。

如果不想将端口暴露给宿主机,就不需要与其对应,如下:

ports:
      - "3306"

这样暴露端口对Docker网络中的其他容器也可用,但不会将其暴露给宿主机,从安全的角度可以起到隔离的效果。WordPress容器不会受到影响,但是宿主机上的MySQL客户端将无法连接到容器中的MySQL数据库。

接下来就是Apache端口的暴露,WordPress容器中绑定的端口为80,前面的80为绑定的宿主机端口。

ports:
      - "80:80"

WordPress卷绑定挂载

WordPress容器定义了两个,Mysql容器定义了1个:

  • wpfiles :对应Docker中Apache服务器根目录下/var/www/html
  • wp-content:对应Docker中/var/www/html/wp-content
  • wpdata:对应Docker中/var/lib/mysql
    volumes:
      - wpdata:/var/lib/mysql
    volumes:
      - wpfiles:/var/www/html
      - ./wp-content:/var/www/html/wp-content

启动WordPress环境

一切都准备好了,就是这么简单!打开一个终端,访问项目目录,然后输入:

docker-compose up

docker-compose up

一切下载安装全部自动完成,由于Docker需要下载镜像、初始化数据库并复制应用程序文件,因此该过程在第一次运行时可能需要花费几分钟。

安装WordPress

在浏览器中打开前面我们设置好的域名devpoint.wordpress,首次执行此操作时,将进入WordPress安装流程:

wordpress安装

按照流程输入基本信息,即可完成安装。

workpress控制面板

wordpress站点

下面选择主题Appointment Dark,进行安装,并启用。

wordpress黑色主题

本地WordPress开发

现在,可以在宿主机PC的目录wp-content中添加、编辑或删除主题插件。

管理面板限制

WordPress允许直接从管理面板中安装、编辑和删除主题和插件文件,这在Windows上是允许的,但是Linux和mac OS用户可能需要通过在宿主机上输入以下命令授予对项目的wp-content文件夹的权限:

chmod -R 777 ./wp-content

主题制作

要开始开发一个新的WordPress主题,在宿主机上目录wp-content/themes中创建主题文件夹,例如 devpoint ,并添加一个style.css样式文件:

/*
Theme Name: DevPoint Theme
Version: 1.0.0
License: MIT
*/

body {
    margin: 0px;
    padding: 30px;
    background-color: #efefef;
    font-family: "Microsoft YaHei", "微软雅黑", "pingfang sc", "宋体", Arial,
        Helvetica, sans-serif;
    line-height: 1.5;
    color: #212529;
}

接着再添加一个 index.php 文件,代码如下:

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<title><?php bloginfo('name'); ?></title>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
<?php wp_head(); ?>
</head>
<body>
  <header>
    <h1><?php bloginfo('name'); ?></h1>
    <p><?php bloginfo('description'); ?></p>
  </header>
  <main>
    <?php
      if ( have_posts() ) : while ( have_posts() ): the_post(); ?>
      <article id="post-<?php the_ID(); ?>">
        <h2><?php the_title(); ?></h2>
        <?php the_excerpt(); ?>
      </article>
    <?php
      endwhile;
    endif;
    ?>
  </main>
  <?php wp_footer(); ?>
</body>
</html>

在WordPress管理面板的“外观”>“主题”页面中激活此主题,刷新页面即可看到如下效果。

wordpress主题切换

点击启用,既可完成自制主题启用。

devpoint主题启用

总结

到这里,已经基本可以使用Docker构建简单的WEB应用了,在前端开发中,合理利用Docker,可以减少很多环境带来的问题。