Docker File 이란?
- docker image를 작성하는 기능
- Docker File 문법으로 스크립트를 작성하여 이미지를 생성할 수 있다.
- 나만의 이미지를 생성할 수 있고, 배포에서 자주 활용하게 된다.
[Docker File 기본 문법]
+@
자주 사용하지 않는 명령어들.
우선
vim Dockerfile
도커 파일을 만들자.
베이스 이미지: 기본이 되는 이미지를 설정한다.
docker build --tag 이름: 태그명 DockerFile경로
ex)
docker build --tag myFile: tag1 ./home/shyswy
* 도커 파일명은 디폴트로 Dockerfile라고 가정하고 찾는다.
만약 Dockerfile2와 같이 다른 이름으로 도커 file 생성 시, -f 옵션을 사용해서 파일명, 경로를 지정해줘야한다.
****보통은 디폴트 이름인 Dockerfile을 사용하고, 디렉토리를 나눠서 각 Dockerfile을 현재 디렉토리에서 사용하는게 일반적
docker build --tag myimage2 -f Dockerfile2 ./
-f 도커파일명 으로 파일 이름지정
label은 일종의 주석 같은 것. 도커 자체에 기능적 영향은 없다. 명시 용도(like README)
FROM httpd:alpine # 해당 base 이미지에다가
COPY ./2021_DEV /usr/local/apache2/htdocs #이런 폴더의 내용을 레이어로 추가하겠다( 복사)
#주의 COPY는 Dockerfile에 대한 상대 경로를 작성해야 한다.
위의 Dockerfile은 alpine을 베이스로, ./2021_DEV_HTML 내의 파일들의 내용을 가져와서( 레이어로 쌓아서 )
이미지를 생성하도록 Dockerfile을 만든 것이다.
위의 도커 파일을 기반으로 myweb 이라는 도커 이미지를 생성한 뒤, 이를 기반으로 실행해보자.
[CMD]
docker에서 시작할 때 실행되는 기본 명령어를 설정하는 커맨드.
Docker Image를 빌드할 때 1번만 지정 가능하며, Docker Container가 시작될때마다 실행된다.
CMD 명령어로 Dockerfile에 설정가능. ( 파이썬 리스트 처럼 여러가지 명령어를 묶어서 설정하는 것도 가능 )
CMD ["/bin/sh","-c","echo","Hello"]
CMD는 Dockerfile에서 "1개" 만 설정되며, 만약 CMD 설정이 여러개라면, 맨 마지막 CMD만 적용된다.
이제 실제로 어떤식으로 실행되었는지 체크해보자
docker inspect명령은 Docker 오브젝트(컨테이너, 이미지, 네트워크 등)의 상세한 정보를 JSON 형식으로 출력
docker inspect 이미지명
그럼 나오는 정보들 중, 아래와 같이 CMD 가 들어가있는 것을 확인할 수 있다.
이번엔 CMD 에 쉘 명령어를 제외하고 지워보자.
실행 중이지 않다.
다음과 같이 종료된 것을 확인 가능하다.
/bin/sh는 터미널이 붙어 있어야 대기 상태로 실행된다. 근데 -it 옵션을 주지 않았기에, 터미널이 붙지 않았고( 입력을 받아줄)
프로그램이 곧바로 종료되었기에 컨테이너도 곧바로 종료된 것.
+ 내ip:포트번호로 접속해도 페이지가 로드되지 않는다.
이 이미지는 httpd-foreground라는 웹 서버 프로그램을 실행해서 웹서버를 동작 시킨다.
CMD를 쉘만 실행하도록 변경했기에, 그런 것
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
[가끔 사용하는 Dockerfile 명령어]
docker logs Names
docker logs: 접속 기록등을 조회 가능.
ex) Container 내부 동작이 이해가 안될 때, Container 내부 에러에 발생 시 다음 명령어로 확인 할 수 있다.
docker stop: 즉시 컨테이너를 중단하지 않는다. ( 실행 중인 단계까지는 기다린 후에 중지된다)
docker kill: 즉시 중단한다.
[EntryPoint]
EntryPoint는 docker run 시에 함께 넣어지는 CMD 명령에 덮어 씌워지지 않고, 반드시 실행해야 하는 명령을 기입할 때 사용한다.
Dockerfile에 CMD 설정이 있고, 커맨드를 통해 CMD 를 덮어쓴 경우가 있을 때, 어떤 CMD가 최종 CMD가 될까?
EntryPoint 명령이 기록이 되있다면, 해당 Entry Point 명령어 뒤에 붙은 CMD가 최종 CMD가 된다.
따라서 EntryPoint에 컨테이너 실행 시, 반드시 실행되야하는 명령어를 넣고, 별도로 각 컨테이너 생성 시 필요한 인자는 docker run에 넣어서 사용하기도 한다.
ENTRYPOINT 로 변경했기에, CMD 는 Null ( 설정해준 것이 없기에)
hello: EntryPoint 로 인해 나온다.
run 으로 "/bin/sh" , "hi" 추가
따라서
ENTRYPOINT 명령어 + run에 붙은 명령어 모두 적용되는 것. ~~~ /bin/sh hi -> "/bin/sh", "hi" CMD가 덮어 씌워지는 것.
[Run]
docker는 이미지 생성 시, layer로 나누어 작성됨.
- 특정 단계가 변경되어도 전체 이미지를 다시 다운로드 받지 않아도 된다.
RUN 명령은 이미지 생성 시, 일종의 layer를 만들 수 있는 명령으로, 보통 베이스 이미지에 패키지를 설치하여, 새로운 이미지를 만들 때 이용한다.
베이스 ( httpd:alpine ) 에 추가적으로 이미지를 쌓는 것.
ex) 리눅스 베이스에 apache 웹서버를 추가적으로 사용해서 나의 웹페이지를 복사 하여 웹 서버 구동
FROM ubuntu:18.04
LABEL maintainer="shyswy@hnh.ai"
RUN apt-get update //리눅스에 기본적인 설치 실행
RUN apt-get install -y apache2 // -y로 모든 옵션에 Yes로 실행.
COPY ./2021_DEV_HTML /var/www/html/ //apache2는 기본 폴더가 /var/www/html/이다.
ENTRYPOINT ["/user/sbin/apache2ctl","-D","FOREGROUND"] //apache2 실행 명령어 ~~apache2ctl 추가
이제 docker build 명령어로 빌드한다.
FROM ubuntu:18.04
LABEL maintainer="shyswy@hnh.ai"
RUN apt-get update
RUN apt-get install -y apache2 apt-utils //apt-utils 추가 후 다시 빌드시, 캐시로 빠르게 중복 과정 스킵
COPY ./2021_DEV_HTML /var/www/html/
ENTRYPOINT ["/user/sbin/apache2ctl","-D","FOREGROUND"]
[EXPOSE]
-p 옵션
-p 9999:80
9999 포트 -> 내부 컨테이너의 포트에 연결
내부 컨테이너에 접속할 때 사용한다. [외부에서 사용할 때]
EXPOSE
다시 컨테이너의 특정 포트를 외부로 오픈하는 것
이미지의 특정 포트를 오픈 해 놓은 뒤, 해당 포트에 다른 컨테이너가 접속할 수 있도록 만들 때 사용 [내부에서 사용할 때]
Docker Compose: 여러 컨테이너를 놓고 컨테이너를 한번에 하나의 컨테이너로 작성한 뒤 실행하는 명령.
이렇게 1번에 실행한 도커들은 내부 네트워크망이 구축되어 서로 접속을 할 수 있다.
하지만 해당 이미지가 포트를 오픈해놓지 않는다면, 해당 컨테이너로 접속할 수 있는 방법이 없다.
이렇게 나만의 이미지를 만들 때 EXPOSE 옵션을 사용한다.
docker run -P -d myweb // - P ( 대문자 ) -> 랜덤한 포트가 EXPOSE로 오픈된 포트가 매핑된다.
ex) 424525->80 //EC2 사용 시, 해당 포트를 인바운드 규칙에 넣어놔야 접근 가능
[ENV]
컨테이너 내에 환경 변수를 설정하는 커맨드.
가장 자주 쓰는 경우: mysql 등 db를 도커로 만들때
mysql 을 베이스로, 루트 비밀번호, 데이터베이스 이름을 설정한다.
WORKDIR
-RUN,CMD, ENTRYPOINT 명령이 실행될 디렉토리 설정
기존에는 /usr/local/apache2/htdocs/index.html 과 같이 경로를 지정해야 했다.
WORKDIR 명령어 사용시, 기본적으로 해당 경로에서 시작하게 된다.
WORKDIR 명령어를 사용하지 않으면, 기본 디렉토리 ( ubuntu는 /root ) 에서 실행된다.
이러한 방식은 명령어에서 파일 경로를 절대 경로로 명시하지 않으면, 명령어에서 사용하는 파일이나 디렉토리의 위치가 예측하기 어렵고, 이식성이 낮아진다. 즉, 경로를 일일이 표기해줘야 안전하다는 것.
ARG: dockerfile 내에서 변수 설정. docker 파일내에서 반복적인 것에 변수명을 지정해서 사용 가능하지만 ,Dockerfile은 보통 짧기에 자주 쓰진 않는다.
USER:docker 이미지, 컨테이너에서 작업으 하는 사용자 ID를 지정한다.
ONBUILD: 생성한 이미지를 기반으로 새로운 이미지를 생성시 실해하는 명령어
VOLUME: 이미지를 위한 볼륨 생성. 이것을 호스트 PC의 특정 볼륨과 연결하는건 아니다.
Dockerfile에서 VOLUME 명령어를 사용하면 이미지 내부에 볼륨을 생성한다. VOLUME 명령어를 사용하면 호스트의 디렉토리나 파일을 컨테이너 내부에 마운트하는 것이 아니라, 컨테이너 내부에서 볼륨을 생성하여 사용한다. VOLUME 명령어를 사용하면 컨테이너가 종료되더라도 볼륨은 삭제되지 않는다.
docker run~~ -v 옵션 VS Dockerfile 내에 VOLUME 옵션
-v 옵션은 호스트와 컨테이너 간의 데이터 공유를 위해 사용되고, VOLUME 명령어는 컨테이너 내부에서 데이터를 저장하기 위해 사용.
또한, -v 옵션을 사용하면 컨테이너를 실행할 때마다 볼륨을 생성할 수 있지만, VOLUME 명령어를 사용하면 이미지를 빌드할 때 한 번만 볼륨을 생성하고, 이후에 생성된 컨테이너에서 사용할 수 있다.
'DevOps' 카테고리의 다른 글
[도커] Nginx 웹서버 설정 이해하기 (1) | 2023.04.20 |
---|---|
[도커] Docker Compose (0) | 2023.04.19 |
[도커] 도커 활용 (0) | 2023.04.19 |
[도커] Mac에서 도커 세팅법 (0) | 2023.04.14 |
[도커] 리눅스 기본 지식 (2) | 2023.04.14 |