bedezign / dchelper
增强 docker-compose 的额外开发者友好功能
Requires
- php: ^7.0
- league/container: ^2.4
- monolog/monolog: ^1.23
- symfony/dotenv: ^4.0 || ^3.0
- symfony/process: ^4.0 || ^3.0
- symfony/yaml: ^4.0 || ^3.0
This package is not auto-updated.
Last update: 2024-09-15 03:24:09 UTC
README
(仍在开发中,使用风险自担)
请注意,此辅助程序(别名/代理)中相关的网络功能仅在 macOS 上有效。对此我深感抱歉。我也非常愿意帮助 Windows 用户,但事实是,它不支持大多数所需的功能。
如果您使用 docker compose,并且希望能够使用像 http://myproject.test 这样的合理 URL 来开发项目,而不是像 http://127.0.0.1:32721 这样几乎不需要额外设置的情况,请继续阅读!
此工具将围绕 docker-compose 运行,从而可以为您的开发环境添加一些新的功能。
请注意,此脚本需要某些命令的 sudo 权限。
安装
您可以通过 packagist/composer 简单地添加它
composer global require bedezign/dchelper
之后,您可能想在 .bashrc
文件中设置一个别名
alias docker-compose="php ~/.composer/bin/dchelper"
就这么简单!
注意
- 目前
dchelper
假定每个服务将只有一个实例。它主要用于开发目的,并且直到有人请求对每个服务多个容器的支持,我都不会考虑增加的复杂性。 - IP 地址和主机名映射目前只适用于第一个找到的 IP 地址(优先考虑别名而不是代理)。
它做什么?
简而言之
- 为您的项目提供“专用 IP”(而不是
127.0.0.1
) - 无需指定端口
- 自动创建/维护您的项目的域名。在浏览器中使用 myproject.test 而不是 IP 地址!
- 轻松“shell”进入容器(使用
docker-compose shell
并在默认容器中获得登录 shell)。 - 内置对 docker-compose v3.4(或更高版本)配置的帮助(目前有“envsubst”和“scriptrunner”,欢迎提出建议)
- 所有这些都可以通过环境变量(
.env
)或 docker-compose.yml 设置来实现。
端口,端口,端口!
当从容器发布端口时,默认情况下,docker VM 将其映射到您的 localhost
(127.0.0.1
)。
如果您未指定远程端口,则不会发生端口冲突,但您最终可能会得到一些晦涩的端口,如 32122
。我不知道您的情况如何,但将我的开发站点托管在 http(s)://127.0.0.1:32122
并不觉得合适。即使将它分配给主机,只要总是需要指定端口,它看起来也不会更美观。
另一种选择是将它映射到默认远程端口,但这样您可能会遇到“端口已占用”等问题。
Docker 实际上已经为这个问题提供了解决方案,而 DCHelper 添加了第二种解决方案。
前提是我们可以为每个 docker-compose-project 添加额外的虚拟 IP。这意味着像 80 和 443 这样高度使用的端口始终在“您的”IP 上可用。
操作系统(Linux和macOS)中已经内置了解决方案:允许您向回环网络接口(即IP别名)添加“虚拟”IP。Docker和dchelper
都可以使用这项功能来简化您的生活。
远程IP(Docker)
Docker(和Docker Compose)定义端口规范如下:[[remote_ip:]remote_port[-remote_port]:]port[/protocol]
这意味着,当您添加已发布端口时,您还可以指定要添加端口的IP。
container:
ports:
- 172.99.0.6:80:80
因此,上述命令告诉Docker将服务端口80
链接到IP 172.99.0.6
上的端口80
(而不是127.0.0.1
)。是不是很酷?但是有一个小问题:docker-compose
不会将别名IP添加到您的网络接口。
但是dchelper会。
它会在提前解析docker-compose配置(以及找到的.env
配置)后,确定需要哪些IP进行别名设置,以使您的配置正常工作。
如果它发现任何尚未存在的IP,它会在传递控制权给docker-compose之前为您注册它们。
使用这项功能很简单:您只需要对配置进行上述示例中所示的修改。
更详细的示例
.env
:
COMPOSE_ALIAS_IP=172.99.0.1
docker-compose.yml
:
services:
db:
ports:
- ${COMPOSE_ALIAS_IP}:3306:3306
nginx:
ports:
- ${COMPOSE_ALIAS_IP}:80:80
通过使用配置值,您在稍后更新IP时不需要做太多工作。因为变量会被docker-compose替换,dchelper仍会检测到实际的IP。
COMPOSE_ALIAS_IP
有特殊含义:即使它在您的配置中未进一步使用,dchelper也会始终别名此IP。该变量也用于hosts
功能。
这意味着在配置文件中需要稍作修改,但Docker会处理其余部分,不需要外部工具。
TCP代理/隧道(通过socat)
此功能使用socat
(SOcket CAT),这是一个非常强大的工具,自称是“多功能中继”。(它可以通过HomeBrew轻松安装在mac上)
对于这个变体,您的端口配置保持不变
container:
ports:
- 80
这里的技巧是,您要么添加全局环境变量COMPOSE_PROXY_IP
,要么在容器的环境中指定PROXY_IP
。
container:
ports:
- 80
environment:
PROXY_IP: 172.99.0.1
(指定PROXY_IP
允许您在设置中使用不同的IP。如果只需要一个IP,全局使用COMPOSE_PROXY_IP
。)
在解析配置时,dchelper将检测所有已发布端口及其链接位置。然后,它将启动多个socat
实例,在代理IP和随机分配的127.0.0.1
上的docker端口之间建立隧道。
最终效果与“远程IP”方法相同,因此取决于您个人的喜好。这里的缺点是,这只能在运行up
命令时从容器中分离出来时使用。隧道只能在“up”命令完成后才能建立(容器需要运行以检测配置),而这是在-d
选项不使用的情况下不会发生的。
此示例产生相同的结果
.env
:
COMPOSE_PROXY_IP=172.99.0.1
docker-compose.yml
:
services:
db:
ports:
- 3306
nginx:
ports:
- 80
端口3306
和80
都将通过172.99.0.1
可用。
如前所述:可以使用不同的IP为每个服务,只需使用PROXY_IP
即可。
主机名
通过向环境添加COMPOSE_HOSTNAME
,您告诉dchelper检查您的/etc/hosts
文件,并在必要时添加新条目。使用的IP将是COMPOSE_ALIAS_IP
,如果未设置,则为COMPOSE_PROXY_IP
。
目前没有支持每个服务/容器的特定主机,只有全局主机。 (如果有人请求,我会添加这个功能,目前我没有这个需求)
Shell
DCHelper 添加了一个 shell
命令。例如,通过执行 dchelper shell php
,它将在相关容器中触发一个(登录)shell。这实际上会在后台运行 docker exec -it <container> <command>
,但你可以指定 compose 服务名称,而不是必须找到 docker 容器名称。
由于 这个问题 和 这个问题(伪终端大小未正确设置的问题),当前默认执行的命令实际上是 '/bin/bash -c "export COLUMNS=`tput cols`; export LINES=`tput lines`; exec bash -l"'
。
通过在您的环境中使用 COMPOSE_SHELL_DEFAULT=service-name
,您可以指定在未指定服务时使用哪个服务。这也可以通过将 SHELL_DEFAULT=1
添加到您的服务环境定义之一来实现。
如果您有一个理解转义序列的终端应用程序(如 iTerm2),DCHelper 还可以为您更改标签页标题。您可以在服务的环境中使用 SHELL_TITLE
为每个服务指定一个标题,或者通过 COMPOSE_SHELL_TITLE
指定全局格式。在这种情况下,{CONTAINER}
将被容器名称替换。
例如:COMPOSE_SHELL_TITLE="${COMPOSE_HOSTNAME: {CONTAINER}"
。主机名替换将由 docker compose 处理,{CONTAINER}
将由 DCHelper 替换。
辅助工具
这仅在您使用格式 v3.4 或更高版本的 compose 文件时才有效。这是第一个允许(忽略)特定供应商的根条目(x-...
)的版本。
使用辅助工具
单个辅助工具
您可以指定要运行的单个命令。
x-dchelper:
command:
configuration...
x-dchelper:
command:
configuration...
command2:
configuration...
多个辅助工具
如果您想运行同一个辅助工具多次,您可以添加一些“垃圾”来创建不同的键。
x-dchelper:
command.serviceone:
configuration...
command.servicetwo:
configuration...
点后面的内容将被丢弃,所以您可以使用任何您想要的内容。
根目录
您可以将 root
作为辅助工具名称指定,并设置本地系统中每个相对 source/origin 目录的 '基础路径'。
x-dchelper:
root: /generic/docker/folder/
envsubst:
files:
- nginx.template:./.docker/nginx.conf
这将使用来自 /generic/docker/folder/nginx.template
的模板,并将其存储在 .docker/nginx.conf
相对位置,该位置位于 docker-compose.yml
旁边。它还会在源、目标和根指令中为您转换 ~
-条目。
如果您有一个全局的 root
设置,并希望将特定部分的重置为项目目录,只需在该部分中将它设置为空即可。
x-dchelper:
root: /generic/docker/folder/
scriptrunner:
root:
files:
- ./script.sh
script.sh
将从工作目录加载,而不是从 /generic/docker/folder
。
阶段
目前,辅助工具可以在 2 个阶段运行:pre.<command>
和 post.<command>
。(例如:在 docker-compose up
命令之前和之后)。通过在配置中指定 at
,您可以覆盖此行为。post.up
只能在 up
命令完成后运行,所以如果您没有分离,它只会在您终止容器后运行。其他可能性还包括 pre.shell
等。
EnvSubst
如果您的 compose 项目需要基于您的环境值的配置文件,迄今为止的技巧是在某个地方插入一个 envsubst
调用,以处理这个问题。DCHelper 以原生和简单的方式支持此功能。
重要:辅助工具是以一种方式编写的,它将仅替换环境中已知的内容。这不会触及除了这一点之外的内容。所以 proxy_set_header Host $http_host;
是安全的,只要您没有定义 http_host
。
注意,这是一个内部功能。您不需要安装 envsubst
命令才能使此功能正常工作。
要生成配置文件,只需添加一个 envsubst
条目。
x-dchelper:
envsubst:
environment-file:
- .env
environment:
- nginx
files:
- /generic/template/folder/nginx/site-fpm.conf:./.docker/site.conf
默认情况下,这将在 pre.up
下运行。
环境文件
要加载哪些文件作为环境文件。默认情况下(如果未指定),工作目录中的 .env
文件。
环境
要加载的 docker 容器环境。
在示例中,它将使用添加了 nginx 服务的 .env
文件。
文件
要替换的文件列表。源文件(甚至目标文件)不需要在项目目录中。
这允许您创建多个模板,然后在运行 docker-compose up
时为每个项目生成配置。
通过使用多个命令语法,您可以在需要不同环境的情况下多次运行 envsubst
。
通过将输出文件名前缀以服务名,配置将在相关容器中创建。此路径 必须是绝对路径。使用 docker cp
实现此功能。
上述示例
x-dchelper:
envsubst:
files:
- /generic/template/folder/aws/credentials.conf:aws-cli:/home/root/.aws/site.conf
dchelper
将确保在需要时为目标文件夹创建文件夹,并将文件复制到其中。
结果
envsubst
辅助程序在所有其他操作之前运行,因此生成的文件可在所有服务中使用
nginx:
image: nginx:latest
volumes:
- ./.docker/site.conf:/etc/nginx/conf.d/site.conf
ScriptRunner
scriptrunner
允许您在容器中运行 shell 脚本。无论脚本是否映射到容器中,它都将其作为一组 bash 命令执行。
如果没有指定,默认情况下在 post.up
下运行。
示例
x-dchelper:
scriptrunner:
service: php
once:
- /my/script/dir/php/install_pdo.sh
- /my/script/dir/php/install_xdebug.sh
注意,scriptrunner
支持 EnvSubst
。
此功能对于命令行(始终启用)有效,因此 ${SCRIPT_FOLDER}/script.sh
将有效)。默认情况下,还启用了在脚本内容中替换,但可以通过指定 envsubst: false
来关闭。与 EnvSubst
一样,您还可以指定 environment-file
和 environment
-key 以进行更多配置。
服务
要针对哪个服务/容器运行。如果您想在主机本身上运行脚本,请使用 localhost
。目前不支持在 localhost
上运行的脚本(仅支持容器)的 once
行为。
锁文件
此文件添加到容器中,用于记住已运行的哪些脚本。由 "once" 命令使用。如果未指定,则默认为 /.dchelper.scripts
once 与 always
您可以在 once
或 always
下指定脚本。我想这种差异是显而易见的。
直接
对于在 localhost
(与 always
)上运行的脚本,您可以指定 direct: true
。这强制 dchelper 以 shell 脚本的形式运行,而不是加载其内容并执行。请注意,在这种情况下文件内容的 envsubst 不会像这样工作。由于它在 localhost
上运行,因此您可以在这些脚本上始终使用 .env
文件。
完整示例
以下是一个完整的 docker-compose.yml
示例
version: '3.4'
services:
php:
image: php:7-fpm
volumes:
- .:/project:rw
environment:
- XDEBUG_CONFIG=remote_enable=1 remote_mode=req remote_port=9000 remote_host=172.99.0.100 remote_connect_back=0
- PHP_IDE_CONFIG=serverName=docker-dev
nginx:
image: nginx:latest
volumes:
- .:/project:rw
- ./storage/app/docker/site.conf:/etc/nginx/conf.d/site.conf
ports:
- ${COMPOSE_ALIAS_IP}:80:80
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- ~/tmp/dev-data/myproject.test/mysql:/var/lib/mysql:rw
ports:
- ${COMPOSE_ALIAS_IP}:3306:3306
x-dchelper:
root: ~/Steve/Development/Docker
envsubst:
environment:
- nginx
files:
- nginx/conf/site_php-fpm_php-9000.template:./storage/app/docker/site.conf
envsubst.aws:
at: post.up
files:
- aws/conf/credentials.template:php:/root/.aws/credentials
scriptrunner:
service: php
once:
- debian/scripts/install_aws-cli.sh
- debian/scripts/install_top.sh
- debian/scripts/install_ping.sh
- php/scripts/install_pdo_mysql.sh
- php/scripts/install_xdebug.sh
- php/scripts/laravel_artisan_xdebug.sh
- php/scripts/fpm_reload.sh
.env
的一部分
COMPOSE_ALIAS_IP=172.99.0.1
COMPOSE_HOSTNAME=myproject.test
COMPOSE_SHELL_TITLE="${COMPOSE_HOSTNAME}: {CONTAINER}"
APP_URL=https://${COMPOSE_HOSTNAME}
这样做:此配置将为您提供具有端口号 80
和 3306
的可工作的 http://myproject.test。它在一个 3 容器结构上运行,所有容器都使用来自 docker hub 的未修改的镜像。
root
条目表示所有相对 源 位置都将映射到其中,目标位置不使用此条目。
~
会对目标和源进行翻译。
注意:如果 root
也是相对路径,则它将以当前工作目录作为其基础(或如果使用 ~
,则为主目录)。它可以在本地辅助配置中重写。
这里使用了 2 个 envsubst
命令。
nginx
-one根据pre.up
阶段的配置创建一个本地存储的文件。生成的文件被挂载到nginx
容器中,以便在启动时使用。aws
-one将直接在容器中创建文件。由于该功能仅在容器启动后才能使用,我们在配置中使用了at: post.up
。
这也表明,只需追加一些随机的(最好是对你有意义的)内容,就可以使用多个envsubst条目。
scriptrunner
命令运行我的某些实用脚本来在容器中安装东西,并跟踪容器内安装了什么。 once
表示这些脚本只运行一次,如果尚未在lock-file
中找到的话。
由于这些将执行“透传”,你将在控制台看到正在执行的操作,而无需查看容器日志来查看何时完成。(这是我使用替代入口脚本安装东西时个人感到烦恼的事情)。
示例中的APP_URL
被添加以表明你还可以在那里重用变量。这里的目的是尽量减少修改以设置新的项目。