在 docker 容器中使用 PHP Composer 通过 SSH 构建私有存储库

问题描述 投票:0回答:1

我需要在 docker 实用程序容器中运行 php Composer,作为设置 PHP 开发环境的一部分。

我正在使用官方

composer
docker镜像,并按照dockerhub文档中的步骤进行操作。

  • 我需要以当前本地用户身份运行
    composer install
    ,以便使用相同的权限创建供应商目录。
  • 我在 github 中有几个通过 SSH 授权的私有依赖项,如果我使用本地安装,作曲家可以毫无问题地获取这些依赖项。

这似乎是一个常见的要求,并且在 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 来做到这一点?

docker github ssh composer-php
1个回答
0
投票

回答我自己的问题,

问题出在

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"
  • 这将 github 添加到
    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
  • 需要在运行时设置User相关的变量。

现在终于要简化命令了 - 将其添加到

~/.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
© www.soinside.com 2019 - 2024. All rights reserved.