Docker

[Docker] Docker References - RUN

patrick-star 2023. 9. 13. 22:08
728x90

RUN 명령어는 2개의 형태를 가진다.

RUN <command> 
⇒ 여기서의 command는 shell 형식의 명령어다. Linux에서는 /bin/sh -c, Windows 에서는 cmd /S /C가 생략된 거라 보면 된다. 

RUN ["executable", "param1", "param2"]
⇒ 이를 exec form 이라고 함 

RUN 명령어(instruction)는 현재의 이미지 위에 새로운 층(layer)에서 명령을 실행하고 결과를 커밋한다. 커밋된 결과 이미지는 Dockerfile의 다음 단계에서 사용된다. 이렇게 층층이 쌓이는 RUN 명령어와 커밋들은 커밋이 간편하고 컨테이너가 Docker의 핵심적인 개념을 준수한다.

exec form을 통해 shell string을 처리해야 하는 작업을 피할 수 있고 shell을 실행할 수 없는 base image를 사용하는 명령어들을 사용할 수 있도록 한다.

ex)

  • \를 이용해서 바로 다음 줄에 있는 명령어를 사용함
  • RUN /bin/bash -c 'source $HOME/.bashrc && \ echo $HOME'
  • 물론 한 줄에 모든 명령어를 다 실행시킬 수도 있음 (shell 명령어를 생각하면 됨)
  • RUN /bin/bash -c 'source $HOME/.bashrc && echo $HOME'
  • exec form을 사용한 경우 (exec form은 JSON 배열로 파싱되기 때문에 반드시 큰 따옴표를 사용해야 한다)
  • RUN ["/bin/bash", "-c", "echo hello"]

exec form은 shell을 호출하지 않는다. 즉, 일반적인 shell 처리 방식을 사용하지 않는다.
예를 들어 RUN [ "echo", "$HOME" ]에서는 $HOME 변수를 shell에서와 같이 변수로 사용할 수 없다.
만약에 shell 처리 방식을 사용하고 싶다면 shell 명령어를 사용하거나 RUN [ "sh", "-c", "echo $HOME" ]와 같이 shell을 실행해야 한다.

cf) JSON 형식에서는 \(백슬래시)를 사용하지 않아야 한다. 특히 Windows 환경에서 주의해줘야 한다.
즉, RUN ["c:\windows\system32\tasklist.exe"]가 아니라 RUN ["c:\\windows\\system32\\tasklist.exe"]가 맞다.

RUN 명령어에 대한 cache는 다음 빌드동안 무효화되지 않고 재사용된다. 만약에 --no-cache 플래그를 사용한다면 cache를 사용하지 않는다는 거니까 RUN 명령어에 대한 cache는 다음 빌드에서 사용되지 않을 것이다. 또한 ADD, COPY instruction에서 무효화될 수 있다.

더 자세한 내용