通过SSH连接时,docker-compose env vars不可用

时间:2020-11-04 19:05:49

标签: docker ssh docker-compose environment-variables

我有一个本地开发环境,要求通过SSH可访问不同的主机,因此我设置了带有某些服务的docker-compose.yml:

services:
  ssh1:
    build:
      context: ./.project/docker/ssh1
      dockerfile: Dockerfile
    environment:
      MYSQL_USER: app1
      MYSQL_PASSWORD: app1

Dockerfile包含以下内容:

FROM ubuntu:20.04

RUN export DEBIAN_FRONTEND=noninteractive \
    && ln -fs /usr/share/zoneinfo/Europe/Berlin /etc/localtime \
    && apt update \
    && apt upgrade -y \
    && apt install -y openssh-server rsync php \
    && mkdir /run/sshd/ \
    && ssh-keygen -A \
    && for key in $(ls /etc/ssh/ssh_host_* | grep -v pub); do echo "HostKey $key" >> /etc/ssh/sshd_config; done \
    && addgroup --gid 1000 app \
    && adduser --gecos "" --disabled-password --shell /bin/bash --uid 1000 --gid 1000 app \
    && mkdir -m 700 /home/app/.ssh/ \
    && chown app:app /home/app/.ssh/ \
    && rm -rf /var/lib/apt/lists/*
COPY --chown=app:app ssh1_rsa.pub /home/app/.ssh/authorized_keys
CMD ["/usr/sbin/sshd", "-D"]
EXPOSE 22

我可以验证环境变量是否在容器中设置

$ docker-compose exec ssh1 printenv | grep MYSQL
MYSQL_USER=app1
MYSQL_PASSWORD=app1

docker inspect project_ssh1_1还显示了ENV变量。

但是当我通过ssh从另一个容器连接到ssh1时,没有设置我的环境变量。

为什么在ssh进入容器时为什么未设置环境变量?

我也非常感谢您提供有关如何通过docker在容器中设置环境变量以及如何从进程或“ OS”继承环境变量的任何深入意见。


解决方案编辑:

回答了实际问题。但是,我没有提出正确的问题。所以这是我的实际解决方案。我可以借助一个漂亮的解决方案在SSH会话中设置ENV VARS,该解决方案不应在PROD环境中使用,因为它可能导致信息泄露。

将所有ENV VARS添加为构建参数。 docker-compose.yml:

  ssh1:
    build:
      context: ./.project/docker/ssh1
      dockerfile: Dockerfile
      args:
        MYSQL_ROOT_PASSWORD: root
        MYSQL_DATABASE: app1
        MYSQL_USER: app1
        MYSQL_PASSWORD: app1
        MYSQL_HOST: mysql1

并将它们写入$ HOME / .ssh / environment并启用PermitUserEnvironment。 不要在生产中这样做

Dockerfile

FROM ubuntu:20.04

ARG MYSQL_ROOT_PASSWORD
ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_HOST

RUN echo "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" >> /home/app/.ssh/environment \
    && echo "MYSQL_DATABASE=$MYSQL_DATABASE" >> /home/app/.ssh/environment \
    && echo "MYSQL_USER=$MYSQL_USER" >> /home/app/.ssh/environment \
    && echo "MYSQL_PASSWORD=$MYSQL_PASSWORD" >> /home/app/.ssh/environment \
    && echo "MYSQL_HOST=$MYSQL_HOST" >> /home/app/.ssh/environment \
    && sed -i 's/#PermitUserEnvironment no/PermitUserEnvironment yes/g' /etc/ssh/sshd_config

现在,登录时,SSH将从用户.ssh / environment(在这种情况下为app)中读取环境变量,并将其设置在用户的SSH会话中。

2 个答案:

答案 0 :(得分:1)

您的问题实际上与docker没有多大关系,而是由于sshd的工作方式:对于每个连接sshd都会建立一个新的环境,以自己清除所有变量环境,请参见Login Process in man sshd

(很容易理解为什么这是有道理的:sshd由root用户启动,因此可能在其环境变量中包含敏感数据,这些数据不应泄漏给用户。其他变量则不合理传递给用户会话,例如HOMEPATHSHELL

根据您的用例,有多种方法可以将环境变量传递到新的ssh会话,具体取决于它是交互式会话还是非交互式会话,是否运行(登录)shell:

另外,根据您的用例,您现在有各种选择如何将这些文件添加到容器中:

  • 如果变量是静态的:仅将ADD的相应文件添加到图像或在Dockerfile中创建它
  • 如果变量是在构建时设置的:请使用ARG s(或ENV)将变量传递到构建并从构建中的文件创建相应的文件(如您在您的解决方案)
  • 如果应在容器运行时设置变量:
    • 在启动时使用自定义ENTRYPOINT脚本从传递的环境变量或命令行参数生成相应的文件
    • 将相应文件批量安装到容器中(您也可以在此处使用docker secret来获取敏感数据)

答案 1 :(得分:0)

环境变量存在于RUN命令中,并且在发出docker exec命令时执行到的外壳中,但是当您将ssh放入运行在容器中的ssh服务器时,您实际上得到了一个全新的shell没有设置这些环境变量。