【问题标题】:Dockerfile - ENTRYPOINT don´t save variablesDockerfile - 入口点不保存变量
【发布时间】:2021-01-17 12:09:23
【问题描述】:

我的 Ubuntu 容器有下一个 Dockerfile

FROM ubuntu:14.04

# Install.
RUN \
  sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu curl git htop man unzip vim wget jq && \
  rm -rf /var/lib/apt/lists/*

# Set environment variables.
ENV HOME /root

# Define working directory.
WORKDIR /root

# Define default command.
ENTRYPOINT ["/bin/bash"]

#First create an Auth token for Sonar server
ENTRYPOINT [ "token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "name=WindowsTokenFinal" -u admin:pass 10.0.0.2:9000/api/user_tokens/generate | jq -r '.token')"]
#
# #Save session cookies
ENTRYPOINT ["COOKIEJAR="$(mktemp)""]
#
# #Generate crumb of Jenkins
ENTRYPOINT ["CRUMB=$(curl -u "admin:pass" --cookie-jar "$COOKIEJAR" "http://10.0.0.3:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")"]
#
# #Create Credentials on Jenkins Server
ENTRYPOINT ["curl -X POST -u "admin:pass" --cookie "$COOKIEJAR" -H "$CRUMB" 'http://10.0.0.3:8080/credentials/store/system/domain/_/createCredentials' --data-urlencode 'json={"": "0","credentials": {"scope": "GLOBAL","id": "WindowsAutoToken","description": "Automatically generated sonar token from windows","secret": "$Token", "$class": "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl"}}'"]

第一个问题是它只执行最后一个ENTRYPOINT,但如果我只运行第一个,

ENTRYPOINT [ "token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "name=WindowsTokenFinal" -u admin:pass 10.0.0.2:9000/api/user_tokens/generate | jq -r '.token')" ]

它不保存令牌变量。

如果我在容器内执行命令就没有问题并且它运行良好,但是我需要在容器启动后运行这些命令,而不是自己运行它们。

【问题讨论】:

    标签: docker ubuntu jenkins curl dockerfile


    【解决方案1】:

    我发现一个有用的模式是使用ENTRYPOINT 作为包装脚本来进行首次设置,然后使用CMD 来实际说明主进程是什么。这将允许您在入口点包装脚本中执行您需要执行的任何操作,然后将主进程作为前台作业运行。

    根据您在 Dockerfile 中显示的内容,您可以将其打包到 shell 脚本中:

    #!/bin/sh
    
    #First create an Auth token for Sonar server
    token=$(curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "name=WindowsTokenFinal" -u admin:pass 10.0.0.2:9000/api/user_tokens/generate | jq -r '.token')
    
    #Save session cookies
    COOKIEJAR="$(mktemp)"
    
    #Generate crumb of Jenkins
    CRUMB=$(curl -u "admin:pass" --cookie-jar "$COOKIEJAR" "http://10.0.0.3:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,%22:%22,//crumb)")
    
    #Create Credentials on Jenkins Server
    curl -X POST -u "admin:pass" --cookie "$COOKIEJAR" -H "$CRUMB" 'http://10.0.0.3:8080/credentials/store/system/domain/_/createCredentials' --data-urlencode 'json={"": "0","credentials": {"scope": "GLOBAL","id": "WindowsAutoToken","description": "Automatically generated sonar token from windows","secret": "$Token", "$class": "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl"}}'
    
    # Launch the main container process
    exec "$@"
    

    然后在 Dockerfile 中,COPY 这个脚本进入,将其设置为 ENTRYPOINT,并将 CMD 设置为您希望容器运行的单个进程(可能不是交互式 shell)。

    COPY entrypoint.sh /usr/local/bin
    ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] # must be JSON-array syntax
    CMD ["my_application", "--foreground"]
    

    请记住,一个容器只运行一个进程。如果你有ENTRYPOINTCMD指令,the CMD gets passed as arguments to the ENTRYPOINT,如果你有多个ENTRYPOINTCMD,只有最后一个生效,前面的被忽略。还要记住 JSON-array syntax 不做任何类型的处理或替换,所以像 $(subprocess) 调用这样的东西不适用于该语法;此外,JSON 数组语法在嵌套引号之类的东西上可能很挑剔,如果你弄错了也没有反馈,Docker 只是默默地回退到 shell-command form

    【讨论】:

    • 非常感谢!!这是个好主意!
    猜你喜欢
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-17
    相关资源
    最近更新 更多