如何在容器中加载Docker环境变量

我正在使用systemd构建基于ubuntu图像的图像。我需要将TigerVNC作为服务启动,这取决于我在Dockerfile中定义的一些环境变量,例如密码。

FROM ubuntu-systemd

ENV VNC_PW="some-password"

ENTRYPOINT ["/lib/systemd/systemd"] 该服务的单位文件中的一行为:

ExecStart=/usr/sbin/runuser -l root -c "/some/script.sh" 由于systemd具有自己的环境,因此我无权访问Dockerfile中定义的环境变量。我期望使用登录外壳程序('-l'标志)以root身份运行脚本将使我能够访问这些变量,但事实并非如此。我知道我需要的变量在/ proc / 1 / environ中,但是我不知道如何加载它们,例如,在.profile文件中为root 添加一些内容。

谢谢。

展开
收起
被纵养的懒猫 2019-09-29 18:25:54 890 分享 版权
阿里云 AI 助理回答

在Docker容器中使用systemd并确保环境变量能被systemd管理的服务正确读取,确实需要一些额外的配置。由于systemd运行在一个独立的环境中,它不会自动继承Dockerfile或entrypoint中设置的环境变量。以下是一种方法来解决你的问题:

  1. 创建一个服务单元文件:你已经提到了服务单元文件中的ExecStart指令,但为了利用环境变量,我们可以在服务定义中直接引用这些变量。

    你可以修改或创建一个新的服务单元文件(例如/etc/systemd/system/vncserver.service),并在其中使用Environment指令来设置环境变量。这样,即使在systemd环境下,这些变量也会对服务可见。

    [Unit]
    Description=TigerVNC Service
    After=network.target
    
    [Service]
    User=root
    Environment=VNC_PW=$VNC_PW
    ExecStart=/usr/sbin/runuser -l root -c "/some/script.sh"
    
    [Install]
    WantedBy=multi-user.target
    

    注意这里的Environment=VNC_PW=$VNC_PW行,它从外部(比如启动容器时通过-e VNC_PW=some-password)传递的环境变量中获取值。

  2. 加载环境变量到root的profile:虽然不是最优解,但如果你坚持要通过root的profile加载环境变量,你可以在/root/.profile中添加脚本来导入这些变量。不过,请注意这通常不推荐用于systemd服务,因为服务通常应该自包含其所有依赖和配置。

    .profile中可以尝试如下操作:

    #!/bin/bash
    source /proc/1/environ | grep -z '^VNC_PW=' > /tmp/env_var
    export $(cat /tmp/env_var)
    

    这段脚本会从/proc/1/environ中提取VNC_PW环境变量,并将其导出到当前shell。但是,这种方法并不直接适用于systemd服务,因为它们通常不通过shell启动。

  3. 重启systemd并启用服务:在Dockerfile中确保执行了必要的命令来重新加载systemd配置并启动服务。

    RUN systemctl daemon-reload && \
       systemctl enable vncserver && \
       systemctl start vncserver
    
  4. 构建和运行Docker镜像:最后,确保在运行Docker容器时也传入环境变量。

    docker run -e VNC_PW=some-password your-image-name
    

通过上述步骤,你应该能够在systemd服务中访问到由Dockerfile或容器启动参数设置的环境变量。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答

国内唯一 Forrester 公共云容器平台领导者象限。

还有其他疑问?
咨询AI助理