最近,我的困扰之一是保持操作系统尽可能干净。为了做到这一点,我希望尽可能少地安装任何东西。
Node.js使这个任务变得如此简单,因为我只需要node
全局安装,其他所有内容都可以本地安装在项目目录中。但是,对于许多其他语言(例如Python
和)PHP
,通常并非如此。此外,当每个项目需要不同的环境设置时,管理所有内容很快就变得很痛苦,有时您会破坏整个系统。
Docker进行了救援。
尽管Docker主要用于控制生产和团队环境,但它对于封装开发环境并提供“干净的状态”以确保无意外损坏也非常有用。
在构建docker开发系统时,我经常考虑以下要求:
- 最小卷挂载:在已挂载的主机卷上的文件IO操作速度很慢(在Windows和Mac上),因此您只想挂载要编辑的源代码文件。构建图像时应复制其他图像。
- 没有运行时安装:依赖项和第三方插件不应在容器运行时安装,尤其是在需要Internet连接的情况下,以确保恢复开发时的最快启动时间。构建映像时应安装它们。
- 主机最小第三方:如果可能的话,依赖性和第三方插件将被取回来自互联网(通过像一个配置文件
package.json
或者Gemfile
甚至是上市内Dockerfile
)。否则,应在构建图像时将它们保存为zip文件并进行复制/提取。有两个原因:- 从主机到映像复制大量文件非常缓慢。
- 在您的git目录中保留大量的第三方文件非常混乱。
- 可跟踪的快照:您应该能够对当前的开发进度进行快照(尤其是在Wordpress中,如下所述),并且应该能够在git存储库中对其进行跟踪。
对于Wordpress开发,我使用了chriszarate/wordpress
它,因为它通过环境变量提供了许多有用的功能,包括:
- 容器启动时自动激活插件。因为没有人希望每次都手动激活主题。但是,一旦开始使用数据库快照,这将变得无关紧要。
- 容器启动时自动激活主题。同样,一旦开始使用数据库快照,这将变得无关紧要。
- 将其他PHP附加到
wp-config.php
。 - 预先配置管理员用户,管理员密码,管理员电子邮件和网站网址,以跳过无聊的欢迎设置屏幕。
该Docker映像背后的魔力是一组wp-cli
脚本,这些脚本附加到docker-entrypoint.sh
官方wordpress
Docker映像的默认入口点。
这是我的Wordpress开发目录的文件夹结构,共有3个主要部分(在屏幕截图中名称不佳,但在下图中有很好的解释):
- 源代码:您当前正在开发的插件和主题。他们是文本文件(
.php
,.css
,.xml
等),你会在大多数项目时间表的创建和更改。 - 第三方:它们是您的站点所需的第三方插件,您的项目或要为其创建子主题的父主题的依赖项。它们应作为zip文件保存在这些文件夹中,或在中指定为url
Dockerfile
。 - 快照:包括来自wordpress数据库的sql转储和文件
wp-content/uploads
夹的压缩文件(如果您正在构建主题的内容或从演示内容开始)。
通过这种结构,映像中将内置第3方和快照,同时安装了源代码以允许进行开发更改。
docker-entrypoint.sh
是docker-entrypoint.sh
原始docker映像的默认入口点,将进行修改(见下文)以适应我们的需求。
有关示例Dockerfile
,请查看此要点。
对于Dockerfile配置,我安装以下软件包:
unzip
:如上所述,快照和第3方保存为zip文件(如果是远程获取,也以zip格式保存)。我们将需要此实用程序来解压缩它们。mysql-client
:该包提供所要求neccessary命令wp db
至出口和进口的wordpress数据库作为.sql
快照。- [可选]
wget
:在dependencires可远程获取的情况下,我们使用wget
到下载从指定的URL他们。
FROM chriszarate/wordpress:4.9.1
RUN \
apt-get update && \
apt-get install unzip wget mysql-client -y && \
rm -rf /var/lib/apt/lists/*
我们将zip文件的每个第三方目录复制到图片上的临时文件夹(或通过下载wget
),提取并删除所有zip文件。这些文件夹的内容将在运行时通过复制到真实的目标目录docker-entrypoint.sh
。
我们之所以没有将它们直接复制到真实的目标文件夹中,是因为它们会被官方wordpress image中的命令覆盖docker-entrypoint.sh
。
# If copied from folder
COPY ./plugins/ /temp/plugins
# If downloaded via url
wget -P /temp/plugins/ https://downloads.wordpress.org/plugin/jetpack.5.9.zip
# Extract and delete zip files
RUN unzip '/temp/plugins/*.zip' -d /temp/plugins && rm /temp/plugins/*.zip || true;
|| true
添加以确保没有zip文件时,脚本不会失败并终止图像构建过程。
同样,我们将快照文件(如果有)复制到映像中。该uploads.zip
文件应如上所述进行解压缩,然后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-content
THEME_DIR=$CONTENT_DIR/themes
PLUGIN_DIR=$CONTENT_DIR/plugins
cp -r /temp/themes/* $THEME_DIR || true
cp -r /temp/plugins/* $PLUGIN_DIR || true
cp -r /temp/base/* $CONTENT_DIR || true
# Activate plugins. Install if it cannot be found locally.
# ...
这里要注意的一件事是,所有这些文件和文件夹均归root
用户所有,因此Wordpress将无法写入。如果您需要授予这些目录的Wordpress权限,则需要插入以下内容:
chown -R $WEB_USER:$WEB_USER $ROOT_DIR/wp-content/uploads
最后,完成所有操作后,在的结尾docker-entrypoint.sh
,我们将要导入wordpress.sql
文件。我们将此行放在文件的末尾,就在之前exec "$@"
,以确保我们的数据库不会被任何内容覆盖。
runuser $WEB_USER -s /bin/sh -c "wp db import $CONTENT_DIR/wordpress.sql"
exec "$@"
对于docker-compose
配置,您可以在chriszarate的存储库中找到示例。它是两种服务的组合:wordpress
用于PHP wordpress安装和mysql
用于数据库。这里只有几件事需要更改:
- 构建您的Dockerfile:而不是
chriszarate/wordpress
直接使用映像
services:
wordpress:
build: .
- 根据您的项目,一个接一个地安装源代码。不要挂载整个目录
themes
或plugins
目录,因为它们在容器中的版本已经用其他文件填充了。
volumes:
- "./src/themes/my-custom-theme:/var/www/html/wp-content/themes/my-custom-theme"
- "./src/plugins/my-custom-plugin:/var/www/html/wp-content/plugins/my-custom-plugin"
- 仅限本地:仅列出在docker image
WORDPRESS_ACTIVATE_PLUGINS
和WORDPRESS_ACTIVATE_THEME
环境变量中安装的插件和主题。否则,入口点脚本将尝试从Internet下载它们并延长启动时间。
现在我们开始了。让我们去清理所有XAMPP或MAMP堆栈,或者删除所有内容并重新安装操作系统,或者最好将机器扔掉,换一台全新的计算机。玩得开心。