programing

'source'와 함께 도커 파일에서 RUN 명령을 사용하면 작동하지 않습니다.

goodcopy 2023. 4. 8. 11:48
반응형

'source'와 함께 도커 파일에서 RUN 명령을 사용하면 작동하지 않습니다.

바닐라 파이썬 환경을 설치하기 위해 정리하고 있는 Docker 파일이 있습니다(어플리케이션을 설치할 예정이지만 나중에 설치 예정).

FROM ubuntu:12.04

# required to build certain python libraries
RUN apt-get install python-dev -y

# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip 

# install and configure virtualenv
RUN pip install virtualenv 
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh

빌드는 마지막 줄까지 정상적으로 실행되지만 다음 예외가 발생합니다.

[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
 ---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> Running in 8b0145d2c80d
 ---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
 ---> Running in 9d2552712ddf
 ---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> Running in c13a187261ec
/bin/sh: 1: source: not found

가 만약ls만으로) 을 알 수 ( ) 。

$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh

「 」를 ,source찾을 수 없다 소스는 다음과 같이 동작합니다.

$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]

대본을 접속할 수 .workon,mkvirtualenvsyslog.

조사를 좀 해봤는데 처음에는 Ubuntu 로그인 셸로서의 bash와 Ubuntu 시스템 셸로서의 대시, 지원되지 않는 대시 사이의 차이점에 문제가 있는 것처럼 보였습니다.source명령어를 입력합니다.

단, 이에 대한 답은 '.' 대신 '.'를 사용하는 것입니다.source당황하다

Dockerfile RUN 명령에서 셸 스크립트를 실행하여 이를 회피하는 가장 좋은 방법은 무엇입니까(Ubuntu 12.04 LTS 기본 이미지에서 실행됩니다).

원답

FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

이것은 모든 Ubuntu 도커 베이스 이미지에 대해 동작합니다.일반적으로 쓰는 도커 파일마다 이 행을 추가합니다.

관련 방관자가 편집

「」의bashsh이 Docker 파일 전체를 통해 컨테이너 내부의 OS를 변경하거나 손상시키지 않고 Docker에게 자신의 의도를 전달할 수 있습니다.그것은 다음과 같이 행해집니다.

SHELL ["/bin/bash", "-c"]

* Linux의 많은 스크립트가 파손될 수 있습니다(Ubuntu 신규 설치 시).grep -rHInE '/bin/sh' / 이상의 결과를 는 2700의 합니다./bin/sh. 와 추가 bash POSIX뿐만이 POSIX와 전혀 다른 동작을 하는 빌트인(및 그 이상)이 있습니다.POSIX(그리고 다른 셸에서 테스트하지 않은 스크립트는 바시즘을 피한다고 생각하기 때문에 효과가 있다는 오류)를 피하고 bashism을 사용하는 것을 전적으로 지지합니다.하지만 대본에 제대로 된 쉐뱅이 있으면 그렇게 해요.OS POSIX의 POSIX입니다.(Linux에 부속되어 있는 모든 2700+스크립트와 설치하는 패키지의 모든 스크립트를 확인할 시간이 없는 한).

자세한 내용은 아래 답변을 참조하십시오.https://stackoverflow.com/a/45087082/117471

의 셸RUN는 「」입니다.["/bin/sh", "-c"].

RUN "source file"      # translates to: RUN /bin/sh -c "source file"

SHEL 명령을 사용하여 이후 기본 셸을 변경할 수 있습니다.RUNDockerfile dock순 :

SHELL ["/bin/bash", "-c"] 

기본 셸이 변경되어 모든 RUN 명령에서 명시적으로 정의할 필요가 없습니다.

RUN "source file"    # now translates to: RUN /bin/bash -c "source file"

기타 주의사항:다음 항목을 추가할 수도 있습니다.--login옵션을 지정하면 로그인 셸이 시작됩니다.은 ①을 의미합니다.~/.bashrc, 앞에 를 밝히지.

가장 source 은 bash의 에 해당합니다.bash는 bash의 에 해당합니다.source★★★★★★★★★★★★★★★★★★:

대신:

RUN source /usr/local/bin/virtualenvwrapper.sh

용도:

RUN . /usr/local/bin/virtualenvwrapper.sh

1.하고 있는 는, 「1.12」를 사용해 주세요.SHELL!

단답:

일반:

SHELL ["/bin/bash", "-c"] 

python vituralenv의 경우:

SHELL ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

장황한 답변:

https://docs.docker.com/engine/reference/builder/ #shell에서

SHELL ["executable", "parameters"]

SHEL 명령어를 사용하면 명령어의 셸 형식에 사용되는 기본 셸을 덮어쓸 수 있습니다.Linux의 기본 셸은 ["/bin/sh", "-c"이고 Windows의 기본 셸은 ["cmd", "/S", "/C"]입니다.셸 명령은 도커 파일에 JSON 형식으로 작성해야 합니다.

SHEL 명령어는 cmd와 powershell, 그리고 sh를 포함한 대체 셸의 두 가지 매우 다른 네이티브 셸이 있는 Windows에서 특히 유용합니다.

SHEL 명령어는 여러 번 표시될 수 있습니다.각 SHEL 명령은 이전의 모든 SHEL 명령을 덮어쓰고 이후의 모든 명령에 영향을 줍니다.예를 들어 다음과 같습니다.

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

셸 명령의 셸 형식이 도커 파일에서 사용되는 경우 RUN, CMD 및 ENTERPOINT 명령의 영향을 받을 수 있습니다.

다음으로 SHEL 명령어를 사용하여 합리화할 수 있는 Windows의 일반적인 패턴 예를 나타냅니다.

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

도커에 의해 호출되는 명령어는 다음과 같습니다.

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

이것은 두 가지 이유로 비효율적이다.첫째, 불필요한 cmd가 있습니다.exe 명령어프로세서(쉘이라고도 함)가 호출됩니다.둘째, 셸 형식의 각 RUN 명령에는 명령어 앞에 powershell - 명령어가 추가로 필요합니다.

이를 보다 효율적으로 하기 위해 두 가지 메커니즘 중 하나를 사용할 수 있습니다.하나는 다음과 같은 RUN 명령어의 JSON 형식을 사용하는 것입니다.

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

JSON 형식은 명확하고 불필요한 cmd.exe를 사용하지 않지만 이중 따옴표와 이스케이프를 통해 보다 자세한 설명을 요구합니다.대체 메커니즘은 SHEL 명령 및 셸 형식을 사용하여 Windows 사용자에게 보다 자연스러운 구문을 만드는 것입니다.특히 이스케이프 파서 디렉티브와 조합하면 더욱 그렇습니다.

# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

결과:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
 ---> Running in 6fcdb6855ae2
 ---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in d0eef8386e97


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/28/2016  11:26 AM                Example


 ---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
 ---> Running in be6d8e63fe75
hello world
 ---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>

SHEL 명령어를 사용하여 셸의 동작 방식을 변경할 수도 있습니다.예를 들어 SHEL cmd /S /C /V를 사용하는 경우:Windows 에서는 ON | OFF, 지연된 환경 변수 확장 시멘틱을 변경할 수 있습니다.

셸 명령은 zsh, csh, tcsh 등의 대체 셸이 필요한 경우에도 Linux에서 사용할 수 있습니다.

셸 기능은 Docker 1.12에서 추가되었습니다.

같은 문제가 발생하여 virtualenv 내에서 pip install을 실행하려면 다음 명령을 사용해야 합니다.

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv myapp \
    && workon myapp \
    && pip install -r /mycode/myapp/requirements.txt"

도움이 됐으면 좋겠어요.

해, 각 RUN 는 다른 스테이트먼트와는 되어, RUN 스테이트먼트는 다른 와는 독립적으로 실행된다는 ./bin/sh -c따라서 일반적으로 로그인 셸에서 제공되는 환경 변수를 얻을 수 없습니다.

좋은 은 '입니다./etc/bash.bashrc"bash login" "bash login" "bash login" "bash login" 입니다.

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "your command"

예를 들어 virtualenvwrapper 설치 및 셋업, 가상 환경 생성, bash 로그인 사용 시 활성화, python 모듈 설치 등을 수행할 수 있습니다.

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "mkvirtualenv myapp"
RUN echo "workon mpyapp" >> /etc/bash.bashrc
RUN /bin/bash --login -c "pip install ..."

bash 스타트업 파일의 메뉴얼을 읽으면, 무엇을 언제 소스로 하는지를 이해하는 데 도움이 됩니다.

https://docs.docker.com/engine/reference/builder/#에 따르면 기본 [Linux]셸을 실행합니다.RUN/bin/sh -c bashism을 것 같기 에 bashism의형식을 .RUN셸을 지정합니다.

RUN ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

그렇지 않으면 RUN의 "쉘 형식"을 사용하여 다른 셸을 지정하면 중첩된 셸이 됩니다.

# don't do this...
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"
# because it is the same as this...
RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]

다른 셸이 필요한 명령어가 여러 개 있는 경우 https://docs.docker.com/engine/reference/builder/#shell을 읽고 RUN 명령어 앞에 다음 내용을 배치하여 기본 셸을 변경해야 합니다.

SHELL ["/bin/bash", "-c"]

사용자의 root 사용자 root root에 .bashrc할 수 .-lSHELL ★★★★★★★★★★★★★★★★★」RUN명령어를 사용하여 로그인 셸로 만들고 소스임을 확인합니다.

주의: 스크립트를 RUN의 유일한 명령어로 소싱하는 것은 무의미하다는 사실을 의도적으로 무시했습니다.

도커의 문서에 따라

'/bin/sh' 이외의 다른 셸을 사용하려면 원하는 셸에 전달되는 exec 폼을 사용합니다.예를들면,

RUN ["/bin/bash", "-c", "echo hello"]

https://docs.docker.com/engine/reference/builder/ #run을 참조해 주세요.

도 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★source

이것은 CentOS 6.6 Docker 컨테이너 구축에서는 완벽하게 작동하지만 Debian 컨테이너에서는 문제가 발생하였습니다.

RUN cd ansible && source ./hacking/env-setup

나는 이렇게 대처했다, 우아한 방법은 아닐지 모르지만, 이것은 나에게 효과가 있었다.

RUN echo "source /ansible/hacking/env-setup" >> /tmp/setup
RUN /bin/bash -C "/tmp/setup"
RUN rm -f /tmp/setup

「 」가 SHELL사용 가능한 경우 이 답변으로 진행하십시오. 승인된 답변은 사용하지 마십시오. 이 답변에 따라 나머지 도커 파일을 하나의 명령어로 입력해야 합니다.

도커 도커 버전에 수 SHELL아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.bashrc(Dockerfiles)

ENTRYPOINT ["bash", "--rcfile", "/usr/local/bin/virtualenvwrapper.sh", "-ci"]

해 주세요.-i합니다.

「 」를 .bash -v뭐가 나오는지 알아봐야지

symlinks를 가지고 노는 대신 다음을 수행합니다.

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc

이것이 'Ubuntu 20.04'에 대한 나의 솔루션이다.

RUN apt -y update
RUN apt -y install curl
SHELL ["/bin/bash", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN source /root/.bashrc
RUN bash -c ". /root/.nvm/nvm.sh && nvm install v16 && nvm alias default v16 && nvm use default"

은 아마도 '아까워서'가 일 수 있습니다.source는 파일 시스템의 어딘가에서 바이너리가 아닌 bash를 위한 빌트인입니다.나중에 컨테이너를 변경하는 것이 소싱하려는 스크립트의 의도입니까?

는 결국 를 env에 되었다..profile 변이했다.SHELL비슷한 것

SHELL ["/bin/bash", "-c", "-l"]

# Install ruby version specified in .ruby-version
RUN rvm install $(<.ruby-version)

# Install deps
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install

CMD rvm use $(<.ruby-version) && ./myscript.rb

pip을 사용하여 Virtualenv에 무언가를 설치하려는 경우 먼저 Virtualenv의 bin 폴더를 검색하도록 PATH env를 변경할 수 있습니다.

ENV PATH="/path/to/venv/bin:${PATH}"

, 임의의 「」, 「」가 됩니다.pip install도커 /path/to/venv/bin/pip.python은 virtualenv를 사용합니다.

은 Docker 파일마다 완전한 모든 몇입니다.여러 가지 기발한 기술을 활용하여 모든 고객을 대상으로 완전한 Conda 환경을 실행하고 있습니다.RUN 내의 할 수 .스크립트 파일 내의 임의의 준비도 같은 방법으로 실행할 수 있습니다.

비로그인/ 시그널, 「」, 「」, 「」, 「」, 「」/「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「인터랙티브」에는, 많은 뉘앙스가 .exec여러 Arg를 처리하는 방법, CMD와 ENTERPOINT의 상호작용 방법, 기타 수많은 사항을 인용하여 인용하므로 이러한 것들을 해킹할 때 문제가 발생하더라도 낙담하지 마십시오.나는 모든 종류의 문헌을 뒤지며 많은 좌절감을 주었지만 아직도 모든 문헌이 어떻게 이해되는지 잘 모르겠다.

## Conda with custom entrypoint from base ubuntu image
## Build with e.g. `docker build -t monoconda .`
## Run with `docker run --rm -it monoconda bash` to drop right into
## the environment `foo` !
FROM ubuntu:18.04

## Install things we need to install more things
RUN apt-get update -qq &&\
    apt-get install -qq curl wget git &&\
    apt-get install -qq --no-install-recommends \
        libssl-dev \
        software-properties-common \
    && rm -rf /var/lib/apt/lists/*

## Install miniconda
RUN wget -nv https://repo.anaconda.com/miniconda/Miniconda3-4.7.12-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh && \
    /opt/conda/bin/conda clean -tipsy && \
    ln -s /opt/conda/etc/profile.d/conda.sh /etc/profile.d/conda.sh

## add conda to the path so we can execute it by name
ENV PATH=/opt/conda/bin:$PATH

## Create /entry.sh which will be our new shell entry point. This performs actions to configure the environment
## before starting a new shell (which inherits the env).
## The exec is important! This allows signals to pass
RUN     (echo '#!/bin/bash' \
    &&   echo '__conda_setup="$(/opt/conda/bin/conda shell.bash hook 2> /dev/null)"' \
    &&   echo 'eval "$__conda_setup"' \
    &&   echo 'conda activate "${CONDA_TARGET_ENV:-base}"' \
    &&   echo '>&2 echo "ENTRYPOINT: CONDA_DEFAULT_ENV=${CONDA_DEFAULT_ENV}"' \
    &&   echo 'exec "$@"'\
        ) >> /entry.sh && chmod +x /entry.sh

## Tell the docker build process to use this for RUN.
## The default shell on Linux is ["/bin/sh", "-c"], and on Windows is ["cmd", "/S", "/C"]
SHELL ["/entry.sh", "/bin/bash", "-c"]
## Now, every following invocation of RUN will start with the entry script
RUN     conda update conda -y

## Create a dummy env
RUN     conda create --name foo

## I added this variable such that I have the entry script activate a specific env
ENV CONDA_TARGET_ENV=foo

## This will get installed in the env foo since it gets activated at the start of the RUN stanza
RUN  conda install pip

## Configure .bashrc to drop into a conda env and immediately activate our TARGET env
RUN conda init && echo 'conda activate "${CONDA_TARGET_ENV:-base}"' >>  ~/.bashrc
ENTRYPOINT ["/entry.sh"]

저는 Django 웹 프레임워크로 개발된 어플리케이션과 유사한 시나리오를 다루고 있습니다.이러한 절차는 저에게 딱 맞는 것입니다.

  • 도커 파일 내용
[mlazo@srvjenkins project_textile]$ cat docker/Dockerfile.debug 
FROM malazo/project_textile_ubuntu:latest 

ENV PROJECT_DIR=/proyectos/project_textile PROJECT_NAME=project_textile WRAPPER_PATH=/usr/share/virtualenvwrapper/virtualenvwrapper.sh

COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}

RUN echo "source ${WRAPPER_PATH}" > ~/.bashrc
SHELL ["/bin/bash","-c","-l"]
RUN     mkvirtualenv -p $(which python3) ${PROJECT_NAME} && \
        workon ${PROJECT_NAME} && \
        pip3 install -r requirements.txt 

EXPOSE 8000

ENTRYPOINT ["tests/container_entrypoint.sh"]
CMD ["public/manage.py","runserver","0:8000"]

  • ENTRIPOINT 파일 "tests/container_entrypoint.sh"의 내용:
[mlazo@srvjenkins project_textile]$ cat tests/container_entrypoint.sh
#!/bin/bash
# *-* encoding : UTF-8 *-*
sh tests/deliver_env.sh
source ~/.virtualenvs/project_textile/bin/activate 
exec python "$@"

  • 마지막으로 컨테이너를 전개하는 방법은 다음과 같습니다.
[mlazo@srvjenkins project_textile]$ cat ./tests/container_deployment.sh 
#!/bin/bash

CONT_NAME="cont_app_server"
IMG_NAME="malazo/project_textile_app"
[ $(docker ps -a |grep -i ${CONT_NAME} |wc -l) -gt 0 ] && docker rm -f ${CONT_NAME} 
docker run --name ${CONT_NAME} -p 8000:8000 -e DEBUG=${DEBUG} -e MYSQL_USER=${MYSQL_USER} -e MYSQL_PASSWORD=${MYSQL_PASSWORD} -e MYSQL_HOST=${MYSQL_HOST} -e MYSQL_DATABASE=${MYSQL_DATABASE} -e MYSQL_PORT=${MYSQL_PORT}  -d ${IMG_NAME}

이게 다른 사람에게 도움이 됐으면 좋겠어요.

인사말,

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★셸 행을 python으로 할 수 .#!/bin/bash를 들어, 「」를 해 주세요container_entrypoint.sh마누엘 라조에게서요

언급URL : https://stackoverflow.com/questions/20635472/using-the-run-instruction-in-a-dockerfile-with-source-does-not-work

반응형