我需要在 docker 实用程序容器中运行 php Composer,作为设置 PHP 开发环境的一部分。
我正在使用官方
composer
docker镜像,并按照dockerhub文档中的步骤进行操作。
composer install
,以便使用相同的权限创建供应商目录。这似乎是一个常见的要求,并且在 doc
中提供了现成的解决方案eval $(ssh-agent); \
docker run --rm --interactive --tty \
--volume $PWD:/app \
--volume $SSH_AUTH_SOCK:/ssh-auth.sock \
--volume /etc/passwd:/etc/passwd:ro \
--volume /etc/group:/etc/group:ro \
--env SSH_AUTH_SOCK=/ssh-auth.sock \
--user $(id -u):$(id -g) \
composer install
但它对我和作曲家要求 github 令牌不起作用(从 Ubuntu 23 运行 Docker 版本 26.0.0)。
该命令对我来说看起来不错,因为它将
SSH_SOCKET
绑定到容器以及 /etc/passwd
和 /etc/group
文件。
但是为什么 SSH 代理转发没有按预期工作?
到目前为止我所尝试过的,
我尝试使用 docker 命令
sh -c "ssh -T [email protected]"
而不是 install
检查与 github 的 SSH 连接 - 这会产生错误 Could not create directory '/home/<user>/.ssh'
并且 github 的权限被拒绝。
我尝试将 SSH 密钥添加到 ssh-agent 并运行 docker 命令,但收到相同的错误(也使用
composer install
命令)
eval $(ssh-agent -s) && \
ssh-add ~/.ssh/<my_private_key> && \
docker run --rm --interactive --tty \
--volume $PWD:/app \
--volume $SSH_AUTH_SOCK:/ssh-auth.sock \
--volume /etc/passwd:/etc/passwd:ro \
--volume /etc/group:/etc/group:ro \
--env SSH_AUTH_SOCK=/ssh-auth.sock \
--user $(id -u):$(id -g) \
composer \
sh -c "ssh -T [email protected]"
尝试将我的系统 SSH 密钥绑定到容器作为下一个解决方案,但我不知道如何正确执行此操作,composer 使用
alpine
linux 基础映像,我认为 SSH 查找密钥的默认位置是 /home/<user>/.ssh
,我尝试使用 Dockerfile 创建用户和主目录,但也失败了。
最后的手段是使用 github 令牌来提取私有 Composer 依赖项,但是有没有办法通过 SSH 来做到这一点?
回答我自己的问题,
问题出在
ssh-add
命令上,
eval $(ssh-agent); \
docker run --rm --interactive --tty \
...
仅此方法不起作用,我需要在
ssh-agent
初始化后添加我的ssh密钥,
eval $(ssh-agent -s) && \
ssh-add ~/.ssh/id_rsa && \
docker run --rm --interactive --tty \
...
(注意:问题中已经提到了这一点,但这是一个错误,因为有多个 ssh 密钥,而我当时提供了错误的密钥。
之后,我还对下面提到的文档提到的方法进行了一些更改)
这不是一种运行这样的作曲家的优雅方式(如问题评论中所建议的),但如果您的要求是将所有内容保留在独立的容器中,您可以检查这个。
所以我每次需要安装composer时都需要运行这个长命令,这很不方便,而且没有缓存(每次都会下载包)而且每次都会出现这个sshknown-host提示您正在连接到 github 以拉取私有存储库。
The authenticity of host 'github.com (20.111.11.82)' can't be established.
ECDSA key fingerprint is SHA256:XXXXX.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
就我而言,我在开发环境设置中使用它,因此我可以在设置时创建一个具有
Dockerfile
的用户,以便可以删除 /etc/passwd
和 /etc/group
绑定,
因此创建了一个像这样的
docker compose
配置,
composer:
build:
context: .
dockerfile: ./dockerfiles/composer.dockerfile
args:
USER_ID: ${C_UID}
GROUP_ID: ${C_GID}
UNAME: ${C_USER}
container_name: util-composer
user: "${C_UID}:${C_GID}"
# For the container
environment:
SSH_AUTH_SOCK: "/ssh-auth.sock"
volumes:
- "$PWD:/app"
- "util_composer_cache:/tmp"
# docker host ssh forwarding
- "$SSH_AUTH_SOCK:/ssh-auth.sock"
command: "update --no-progress --no-interaction --ignore-platform-reqs"
stdin_open: true
tty: true
networks:
- my-network
--ignore-platform-reqs
是必需的,因为源代码 php 依赖库不会出现在您的 Composer 实用程序容器中。util_composer_cache:/tmp
- 命名卷附加到 /tmp
,这是 Composer 存储缓存的路径。这是
Dockerfile
。
FROM composer
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG UNAME=nonrootuser
RUN addgroup -g $GROUP_ID $UNAME \
&& adduser -G $UNAME -g $UNAME -s /bin/sh -u $USER_ID -D $UNAME \
&& mkdir -p /home/$UNAME/.ssh \
&& chmod 700 /home/$UNAME/.ssh \
&& chown $USER_ID:$GROUP_ID /home/$UNAME/.ssh \
&& su - $UNAME -c "ssh-keyscan github.com >> /home/$UNAME/.ssh/known_hosts"
known_hosts
列表现在运行这样的默认命令,
eval $(ssh-agent -s) && \
ssh-add ~/.ssh/id_rsa && \
C_USER=$(whoami) C_UID=$(id -u) C_GID=$(id -g) docker compose run --rm composer
现在终于要简化命令了 - 将其添加到
~/.zshrc
/~/.bashrc
中以用作别名
composer-util() {
eval $(ssh-agent -s)
ssh-add "${HOME}/.ssh/id_rsa"
C_USER=$(whoami) C_UID=$(id -u) C_GID=$(id -g) docker compose run --rm composer "$@"
}
最后,这样使用,
# This will run the default command - "update --no-progress --no-interaction --ignore-platform-reqs" in my case
composer-util
# but can be override with any composer command (as the composer is the ENTRYPOINT set)
composer-util dump-autoload -o