[Docker CE] dockerfile 명령어 정리 (3) (COPY, ADD, ENV, ARG, WORKDIR)
1편 (RUN, CMD, ENTRYPOINT) : https://nirsa.tistory.com/66?category=868315
2편 (ONBUILD, STOPSIGNAL, HEALTHCHECK) : https://nirsa.tistory.com/68?category=868315
4편 (USER, LABEL, EXPOSE, VOLUME) : https://nirsa.tistory.com/70?category=868315
-
들어가기전에...
간혹 override 라는 단어가 등장 하는데, 일반적으로 override는 물려받은 값(변수 등)을 다르게 만들어 생성하는 개념입니다.
CMD에 선언한 명령을 ls라고 선언 후 conatiner run을 사용할 때 ps 를 사용 하거나, ENTRYPOINT에서 선언한 명령을 --entrypoint= 옵션을 사용하여 변경하는 경우 등 기존에 상속받은 정해진 값을 변경하여 사용할 때 override를 했다고 합니다.
-
7. COPY, ADD
명령 두개 다 호스트OS의 파일 또는 디렉토리를 컨테이너 안의 경로로 복사 합니다.
COPY의 경우 호스트OS에서 컨테이너 안으로 복사만 가능하지만, ADD의 경우 원격 파일 다운로드 또는 압축 해제 등과 같은 기능을 갖고 있습니다. 즉, 호스트OS에서 컨테이너로 단순히 복사만을 처리할 때 COPY를 사용 합니다.
ADD와 COPY 두 명령 모두 사용법은 아래와 같으며 소유자와 소유그룹도 수정이 가능 합니다.
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] (이 형식은 공백이 포함 된 경로에 필요합니다)
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] (이 형식은 공백이 포함 된 경로에 필요합니다)
소유자와 소유그룹 필요 없이 사용할때는 다음과 같이 사용하시면 됩니다.
## COPY <호스트OS 파일 경로> <Docker 컨테이너 안에서의 경로>
COPY test.sh /root/copy/test.sh
## ADD <호스트OS 파일 경로> <Docker 컨테이너 안에서의 경로>
ADD test.sh /root/add/test.sh
ADD 명령의 경우 아래와 같이 url을 입력하여 다운로드도 가능 합니다.
## ADD <다운 받을 URL> <Docker 컨테이너 안에서의 경로>
ADD http://~~~~~~/index.php /root/add_url/index.php
-
8. ENV, ARG
ENV와 ARG는 비슷해 보이지만 다른 명령 입니다.
ENV는 Dockerfile 또는 컨테이너 안에서 환경 변수로 사용이 가능하고, ARG는 Dockerfile 에서만 사용이 가능 합니다.
# ENV 사용 법
# ENV [key] [value]
ENV myName nirsa
ENV myAddress nirsa.tistory.com
# ENV [key]=[value] ## 한번에 여러개의 값을 설정할 때 사용
ENV myName=nirsa \
myAddress=nirsa.tistory.com
# ARG 사용법
# [key]=[value]
ARG myName=nirsa
ARG myAddress=nirsa.tistory.com
때문에 ARG의 경우 Dockerfile 작성하는데에 필요한 변수를 선언하여 Dockerfile을 좀 더 편하게 작성할 수 있고, ENV는 변수 선언은 물론, 컨테이너 안에서 사용할 환경 변수(작업 디렉토리 지정) 등 선언하여 사용할 수 있습니다.
ENV가 실제로 컨테이너 안에서 환경변수로 작동 하는지 알 기 위해 아래 스크립트를 사용해주세요. (Dockerfile 이 있는 경로에 test.sh 으로 생성)
FROM centos:7
COPY test.sh /root/mkdir/test.sh
ENV DIR=/root/mkdir/
RUN echo ${DIR}
CMD ${DIR}/test.sh
빌드할 때 DIR 변수를 정확히 /root/workdir 으로 인식하고 있고, container run을 할 때도 $DIR/test.sh 즉, /root/workdir/test.sh를 정확히 실행 하였습니다. (WORKDIR은 리눅스의 cd와 같이 작업 디렉토리로 이동 하지만 ENV는 환경 변수일 뿐이고, pwd 경로를 보시면 아시겠지만 루트 디렉토리에서 작업 합니다.)
test.sh 의 코드를 그대로 사용하되 ENV를 ARG로 변경해주세요.
FROM centos:7
COPY test.sh /root/mkdir/test.sh
ARG DIR=/root/mkdir/
RUN echo ${DIR}
CMD ${DIR}/test.sh
빌드할때엔 ARG로 선언한 변수 DIR가 재대로 /root/workdir를 선언 하였고, container run할때는 ARG로 선언한 변수가 사라져서 /root/workdir/test.sh 를 찾지 못하고, 루트 디렉토리 밑에서 test.sh를 찾지 못했다고 나옵니다.
* 이러한 설정들은 docker container inspect [컨테이너명] 을 입력하고 확인할 수 있습니다.
-
9. WORKDIR
WORKDIR은 명령을 실행하기 위한 디렉토리를 지정 합니다.
우선 WORKDIR을 확인하기 위해 Dockerfile이 있는 디렉토리 안에 아래와 같은 코드의 test.sh 생성 및 Dockerfile을 수정해 줍니다. (COPY 명령은 이후 ADD와 같이 업로드 할 것 입니다, 간단히 호스트OS test.sh를 컨테이너 안의 /root/mkdir/test.sh 으로 복사하는 명령 입니다.)
빌드 후 container run을 하시면 WORKDIR로 이동된 경로와 test.sh가 실행되어 Hello, world!가 출력 됩니다. 즉 WORKDIR 명령은 리눅스의 cd와 비슷한 개념이지만, 작업할 디렉토리를 지정 합니다.
#!/bin/bash
pwd
echo "Hello, world!"
FROM centos:7
COPY test.sh /root/mkdir/test.sh
WORKDIR /root/mkdir/
CMD ./test.sh