我最近的一个痴迷是尽可能保持操作系统干净。为了做到这一点,我想尽可能少地安装任何东西。

Node.js 使这个任务变得如此简单,因为我只需要 node 全局安装,其他一切都可以安装在本地项目目录中。然而,对于许多其他语言,例如PythonPHP,通常情况并非如此。此外,当每个项目都需要不同的环境设置时,快速管理所有内容会变得很痛苦,有时您会破坏整个系统。

Docker 来拯救。

虽然 Docker 主要用于控制生产和团队环境,但它对于封装开发环境和提供“干净状态”以确保不会意外损坏也非常有用。


目标

在搭建docker开发系统的时候,我经常会考虑以下需求:

  • Minimal volume mount:已挂载的主机卷上的文件 IO 操作很慢(在 Windows 和 Mac 上),因此您只想挂载要编辑的源代码文件。构建镜像时应复制其他镜像。
  • 没有运行时安装:依赖和第三方插件不应该在容器运行时安装,尤其是当一个互联网恢复开发时需要连接以确保最快的启动时间。构建映像时应安装它们。
  • Host Minimal 3rd party:依赖项和 3rd party 插件将尽可能从互联网上获取(通过配置类似 package.jsonGemfile 的文件,甚至在 Dockerfile <跨度>)。否则,应将它们另存为 zip 文件并在构建图像时复制/提取。有两个原因:
    • 将大量文件从主机复制到映像非常慢。
    • 在您的 git 目录中保留大量的第 3 方文件非常令人困惑。
  • 可追踪的快照:你应该可以看一下当前的开发进度快照(尤其是在 WordPress 中,如下所述),并且您应该能够在 git 存储库中跟踪它们。

基本的Docker镜像

我用的Wordpress开发 chriszarate/wordpress它,因为它通过环境变量提供了很多有用的特性,包括:

  • 当容器启动时自动激活插件。因为没有人愿意每次都手动激活一个主题。但是,一旦您开始使用数据库快照,这就变得无关紧要了。
  • 自动容器启动时激活主题。同样,一旦您开始使用数据库快照,这就变得无关紧要了。
  • 将额外的 PHP 附加到 wp-config.php
  • 预先配置管理员用户、管理员密码、管理员电子邮件和网站 URL,以跳过无聊的欢迎设置屏幕。

这个 Docker 镜像背后的魔法是一组 wp-cli 脚本附加到 docker-entrypoint.shOfficialwordpress Docker 镜像的默认入口点。


文件夹结构

这是我的Wordpress开发目录的文件夹结构,一共有3个主要部分(在屏幕截图中命名不当,但在下图中得到了很好的解释):

  • 源代码: 您当前正在开发的插件和主题。它们是文本文件(.php, .css, .xml 等),您将在大多数项目进度表中创建和更改它们。
  • Third Party:这些是你的网站需要你的项目或创建依赖的第三方插件子主题的父主题。它们应该作为 zip 文件保存在这些文件夹中,或者在 Dockerfile 中指定为 url。
  • 快照:包括来自 wordpress 数据库的 sql 转储和文件wp-content /uploads 文件夹(如果您正在为主题构建内容或从演示内容开始)。

通过这种结构,第 3 方和快照被内置到图像中,同时安装源代码以允许开发更改。

docker-entrypoint.sh是原docker的docker-entrypoint.sh image 默认入口点,将对其进行修改(见下文)以满足我们的需要。


Docker文件

例如Dockerfile,回顾这个要点。

支持

对于Dockerfile配置,我安装了以下包:

  • unzip:如上所述,快照和第 3 方被保存为 zip 文件(如果远程获取,也保存为 zip 格式)。我们将需要此实用程序来解压缩它们。
  • mysql-client:这个包提供了必需的命令wp db to 导出和导入 wordpress 数据库作为 .sql快照。
  • [可选] wget:当可以远程获取依赖时,我们使用wget 从指定的 URL 下载 它们。

FROM chriszarate/wordpress:4.9.1RUN apt-get update && apt-get install unzip wget mysql-client -y && rm -rf /var/lib /apt/lists/*

第 3 方和快照

我们将 zip 文件的每个第 3 方目录复制到图像文件夹上的临时文件夹(或通过下载wget),提取并删除所有 zip 文件。这些文件夹的内容会在运行时通过docker-entrypoint.sh复制到真正的目标目录。

之所以没有直接复制到真正的目标文件夹中,是因为它们会被wordpress官方镜像中的命令覆盖 docker -entrypoint.sh.

# 如果从文件夹复制COPY ./plugins/ /temp/plugins# 如果通过urlwget -P /temp/plugins/ https://downloads.wordpress.org/plugin 下载/jetpack.5.9.zip# 提取并删除 zip 文件 RUN unzip '/temp/plugins/*.zip' -d /temp/plugins && rm /temp/plugins/*.zip ||真;

|| true 添加以确保当没有 zip 文件时,脚本不会失败并终止图像构建过程。

同样,我们将快照文件(如果有)复制到图像中。 uploads.z​​ip文件如上解压,然后wordpress.sql处理 跨度docker-entrypoint.sh

入口点和配置

我们需要docker-entrypoint.sh 用修改后的脚本替换默认值。我们不必指定 ENTRYPOINT 因为它已经在官方 docker 镜像中声明了。

COPY docker-entrypoint.sh /usr/local/bin/RUN chmod +x /usr/local/bin/docker-entrypoint.sh

uploads.ini在存储库中拥有自己的 php 上传配置并将其插入图像中也很有用。显然,你可以用同样的方式配置其他内部系统文件:将自定义文件复制到镜像内部的绝对路径中。

COPY ./uploads.ini /usr/local/etc/php/conf.d/uploads.ini


入口点脚本

例子docker-entrypoint.sh这个要旨。

是时候做出改变了docker-entrypoint.sh。从 chriszarate/wordpress 的脚本克隆开始,我们需要复制 /temp/ 中的所有文件目录到所需位置。这些行需要在插件和主题激活之前放置。

CONTENT_DIR=$ROOT_DIR/wp-contentTHEME_DIR=$CONTENT_DIR/themesPLUGIN_DIR=$CONTENT_DIR/pluginscp -r /temp/themes/* $THEME_DIR || truecp -r /temp/ plugins/* $PLUGIN_DIR || truecp -r /temp/base/* $CONTENT_DIR || true# 激活插件。本地找不到就安装。# ...

这里要注意一点,所有这些文件和文件夹都属于root 用户,所以 WordPress 将无法写信给他们。如果您需要授予 WordPress 对这些目录的权限,则需要插入以下内容:

chown -R $WEB_USER:$WEB_USER $ROOT_DIR/wp-content/uploads

最后,一切搞定之后,在docker-entrypoint.sh的最后,我们要导入< code>wordpress.sql 文件。我们将这一行放在文件的末尾,就在 exec "$@" 之前,以确保我们的数据库没有被任何东西覆盖。

runuser $WEB_USER -s /bin/sh -c "wp db import $CONTENT_DIR/wordpress.sql"exec "$@"


< p>Docker-compose

对于docker-compose的配置,可以在chriszarate 的存储库中找到示例。它是两个服务的组合:wordpress 用于 PHP wordpress 安装和 mysql 用于数据库。这里只有几处需要更改:

  • 构建您的 Dockerfile: 而不是 chriszarate/wordpress直接使用图片

services: wordpress: build: .

    < li >根据你的项目,一个一个地安装源不要挂载整个目录themes或者plugins 目录,因为它们在容器中的版本已经填充了其他文件。

volumes: - "./src/themes/my-custom-theme:/var/www/html/wp-content/themes/my-custom -主题" - "./src/plugins/my-custom-plugin:/var/www/html/wp-content/plugins/my-custom-plugin"

  • < span>仅限本地:仅在 docker 镜像中列出WORDPRESS_ACTIVATE_PLUGINSWORDPRESS_ACTIVATE_THEME> span>环境变量中安装的插件和主题。否则,入口点脚本将尝试从 Internet 下载它们并延长启动时间。

现在开始。让我们清理所有 XAMPP 或 MAMP 堆栈,或者删除所有内容并重新安装操作系统,或者更好的是,扔掉机器并获得一台全新的计算机。玩得开心。