我有一个本地开发环境,要求通过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会话中。
答案 0 :(得分:1)
您的问题实际上与docker
没有多大关系,而是由于sshd
的工作方式:对于每个连接sshd
都会建立一个新的环境,以自己清除所有变量环境,请参见Login Process in man sshd
。
(很容易理解为什么这是有道理的:sshd
由root用户启动,因此可能在其环境变量中包含敏感数据,这些数据不应泄漏给用户。其他变量则不合理传递给用户会话,例如HOME
,PATH
,SHELL
)
根据您的用例,有多种方法可以将环境变量传递到新的ssh
会话,具体取决于它是交互式会话还是非交互式会话,是否运行(登录)shell:>
~/.ssh/environment
:由ssh
注入的变量,请参见PermitUserEnvironment
/etc/environment
:pam_env
在登录时使用/etc/profile
,~/.bashrc
等:(登录)shell使用的配置,请参见bash
for example。另外,根据您的用例,您现在有各种选择如何将这些文件添加到容器中:
ADD
的相应文件添加到图像或在Dockerfile
中创建它ARG
s(或ENV
)将变量传递到构建并从构建中的文件创建相应的文件(如您在您的解决方案)ENTRYPOINT
脚本从传递的环境变量或命令行参数生成相应的文件docker secret
来获取敏感数据)答案 1 :(得分:0)
环境变量存在于RUN
命令中,并且在发出docker exec
命令时执行到的外壳中,但是当您将ssh放入运行在容器中的ssh服务器时,您实际上得到了一个全新的shell没有设置这些环境变量。