이미지 레이어 이해하기
- Docker는 이미지 빌드 시 Dockerfile의 명령어를 실행 했을 때 결과가 이전과 다른 점이 없으면 캐시를 사용해 빠르게 생성함 (명령어를 수행 했을 때 디렉터리, 코드 등 변경 사항이 없으면 이전과 결과가 같다고 판단하기 때문)
- Docker는 레이어 기반 아키텍처를 수행하는데 Dockerfile의 하나의 명령어는 하나의 레이어를 나타냄
- Docker 이미지는 읽기 전용으로 명령이 실행되고 이미지가 빌드되면 이미지가 잠기고, 이미지를 다시 빌드하지 않는 한 그 코드를 변경할 수 없음 (새 이미지를 생성)
- 특정 레이어가 변경될 때마다 변경된 레이어 이후 모든 레이어는 빌드를 다시 수행 (캐시 사용 X)npm install과 같이 변경 사항이 자주 일어나지 않으나 한번 수행 시 오래 걸리는 작업은 앞쪽에 변경 사항이 자주 있는 코드 같은 경우는 뒤 쪽에 배치하여 효율적인 빌드를 수행하도록 작성
FROM node:12
WORKDIR /app
# package.json만 먼저 복사하여 변경사항 여부 체크
# 이미지 레이어에 의해 변경사항이 있는 경우는 변경 사항이 반영된 레이어 이후는 다시 실행명령어 수행
COPY package.json /app
# package.json에서 변경 사항이 있는 경우 수행 (없는 경우 캐시를 이용, 최적화&속도 향상)
# npm install 시간이 오래 걸리기에 [COPY . /app]을 항상 먼저 수행할 경우 코드 변경 시 마다 npm install 수행하여 속도 저하 요인
RUN npm install
# 모듈에서 변경 사항이 없는 경우 위의 COPY, RUN 명령은 캐시로 적용
# 나머지 코드 복사 수행
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
Attached & Detached 모드 이해하기
- Attached 모드
docker run 입력 시 Default 수행 모드
실행 중인 컨테이너와 연결이 되어있는 모드로 코드 상 콘솔 출력 시 터미널에 출력됨
docker run [ImageName]
docker start -a [ContainerName]
docker attach [ContainerName]
# 컨테이서 생성 및 실행 시 연결(Attached)
docker run 2ddf2ede7d6c
# 컨테이너 실행 시 연결(Attached)
% docker start -a goalsapp
# 실행 중인 컨테이너에 연결(Attached)
% docker attach goalsapp
- Detached 모드
docker start 입력 시 Default 수행 모드
컨테이너는 background로 실행하는 모드로 컨테이너 실행 하면서 다른 작업 수행 가능
docker run -d [ImageName]
docker start [ContainerName]
% docker run -p 8000:80 -d 2ddf2ede7d6c
% docker start goalsapp
- 컨테이너에 출력된 로그 확인
docker logs [ContainerName]
% docker logs goalsapp
Learn Docker in-depth!!
# -f : 출력 로그 확인 및 수신 대기 (Attached 모드 처럼 동작)
% docker logs -f goalsapp
Learn Docker in-depth!!
Learn Docker in-depth!!@@
인터렉티브 모드 들어가기
- Attached 모드로 컨테이너 연결 시 출력된 결과를 받을 수는 있지만 입력 값을 전달할 수는 없음
- Java, Python의 input()과 같이 어플리케이션에서 특정 값을 입력 받기 위한 경우가 있을 경우 인터렉티브 모드로 실행하여 입력 값을 컨테이너에 전달 할 수 있음
- docker run 옵션
-i : 인터렉티브 모드 수행, 입력 받기 위한 수신 상태를 활성화
-t : tty(터미널) 생성, 컨테이너에 터미널을 생성
-it를 결합해서 사용하여 생성한 터미널로 입력을 수신 - docker start 옵션
입력 값 전달이 필요해 인터렉티브 모드로 만들어진 컨테이너는 다시 시작 시 인터렉티브 모드로 시작해야 정상적으로 입력값을 전달 할 수 있음
-a : Attached모드로 컨테이너 시작
-i : 인터렉티브 모드로 컨테이너 시작
# 코드에 입력 값을 전달해야 하는 코드가 있으나 그냥 컨테이너 생성 시 에러 출력
% docker run 98a2e866e7b3
Please enter the min number: Traceback (most recent call last):
File "/app/rng.py", line 3, in <module>
min_number = int(input('Please enter the min number: '))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line
# 인터렉티브 모드로 수행 시 입력 값 정상적으로 전달
% docker run -it 98a2e866e7b3
Please enter the min number: 0
Please enter the max number: 10
3
# 컨테이너명 확인
% docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c87b5481d45 98a2e866e7b3 "python rng.py" About a minute ago Exited (0) About a minute ago naughty_dewdney
# Attached모드로 수행 시 처음 한번만 입력 후 무반응
% docker start -a naughty_dewdney
Please enter the min number: 10
1
^C
# 기존 컨테이너 중지
% docker stop naughty_dewdney
naughty_dewdney
# Attached + 인터렉티브 모드로 수행 시 정상적으로 입력 값 전달
% docker start -ai naughty_dewdney
Please enter the min number: 2
Please enter the max number: 10
9
이미지 및 컨테이너 삭제하기
- docker rm [ContainerName] : 컨테이너 제거
- docker rmi [ImageID] : 이미지 제거
- 이미지가 더 이상 컨테이너에 사용되지 않고 중지된 컨테이너에 포함된 경우만 제거할 수 있음
- 중지된 컨테이너가 있는 경우 해당 컨테이너가 사용 중인 이미지는 제거할 수 없음 (컨테이너 먼저 제거 필요)
docker images - 이미지 목록 출력
docker rm [ContainerName] - 컨테이너 제거
docker rmi [ImageID] - 이미지 제거
# 다수 컨테이너 동시 제거
docker rm quizzical_mendel thirsty_elgamal
# 이미지 제거
docker rmi ac20ab7789a9
# 사용되지 않는 이미지 모두 제거
docker image prune
중지된 컨테이너 자동 제거
- docker run --rm : 중지된 컨테이너를 자동으로 제거, 중지된 컨테이너를 수동으로 정리하지 않아도 됨
- 코드가 변경된 경우에만 컨테이너를 중지하는 경우가 많음 → 이미지를 다시 빌드 → 기존 컨테이너 중지 및 제거 필요
- docker run --rm 옵션 사용
docker run으로 컨테이너 생성 시 --rm 옵션을 넣으면 해당 컨테이너는 종료 시 자동으로 제거 됨
% docker run -p 3000:80 -d --rm 3057672a42f9
6d173c5e96dad52034fe7128477a830701ce29836c09b86e94dcff3d2c9f0a33
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d173c5e96da 3057672a42f9 "docker-entrypoint.s…" 22 seconds ago Up 21 seconds 3000/tcp, 0.0.0.0:3000->80/tcp sweet_dirac
% docker stop sweet_dirac
sweet_dirac
% docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fbc41cfcec49 98a2e866e7b3 "python rng.py" 21 minutes ago Exited (0) 20 minutes ago stupefied_volhard
0d7222657eab 3057672a42f9 "docker-entrypoint.s…" 2 days ago Exited (137) 18 minutes ago angry_solomon
이미지 검사
- docker image inspect : 이미지 구성 정보 확인
docker image inspect [Image ID]
docker image inspect 98a2e866e7b3
컨테이너에/컨테이너로 부터 파일 복사하기
- docker cp : 실행 중인 컨테이너로 또는 실행 중인 컨테이너 밖으로 파일 또는 폴더 복사
- 소스 코드가 변경된 경우 이미지 빌드 대신 변경된 코드를 컨테이너에 넣을 수도 있음
(오류 가능성으로 인해 잘 사용하지 않는 방법)
% docker cp [local_file_path] [container name]:[container file_path]
% docker cp [container name]:[container file_path] [local_file_path]
# local -> container
% docker cp dummy/. angry_solomon:/test
# container -> local
% docker cp angry_solomon:/test dummy
컨테이너, 이미지에 이름 & 태그 지정
- 컨테이너 이름 지정
- docker run -- name
docker run -p 3000:80 -d --rm --name [name] [Image ID]
docker run -p 3000:80 -d --rm --name goalsapp 2ddf2ede7d6c
docker start goalsapp
docker stop goalsapp
- 이미지 이름 지정
- docker build -t : [name : tag] 형식으로 작성하며 name을 통해 여러 개의 특정화된 이미지 그룹을 만듬 name(Repository) - 이미지 그룹명
tag - 이미지의 버전 정보
- docker build -t : [name : tag] 형식으로 작성하며 name을 통해 여러 개의 특정화된 이미지 그룹을 만듬 name(Repository) - 이미지 그룹명
docker build -t [name:tag] .
docker build -t goals:latest .
docker run -p 3000:80 -d --rm --name goalsapp goals:latest
docker start goalsapp
docker stop goalsapp
이미지 공유하기
- 이미지 공유 방식
- Dockerfile 공유 방식 Dockerfile과 App의 소스 코드를 제공하여 자체적으로 이미지를 빌드하고 컨테이너를 실행 이미지에 들어가는 코드 및 폴더 구조 필요
- 빌드된(완성된) 이미지 공유 방식 (일반적인 방법) 모든 것이 이미지에 포함되어 있기에 이미지 다운로드 시 즉시 컨테이너 실행 가능 또한 코드 및 폴더 구조 필요 하지 않음
이미지 Tag명 변경하기
- docker tag [name:tag] [name:tag]: 이미지 name, tag 변경 기존 변경 후이미지 이름 변경 시 기존
이미지의 이름을 변경하는 것이 아닌 변경할 이름으로 복제본을 생성
DockerHub에 이미지 Push
- docker push [Repository/ImageName] : 이미지 업로드
- 이미지를 push하기 위해 이미지 name은 [Repository/ImageName] 형식으로 작성
- 이미지 push 시 도커는 이미지의 전체 사이즈를 업로드 하는 것이 아님.
- 베이스 이미지는 Docker Hub에 존재하기에 베이스 이미지에 대한 연결 설정하고 베이스 이미지외에 추가 정보만 push 함으로써 레포지토리 공간 및 대역폭을 절약할 수 있음
% docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
node-demo latest fe7a8d0c5b43 3 minutes ago 869MB
<none> <none> 98a2e866e7b3 24 hours ago 881MB
<none> <none> 3057672a42f9 3 days ago 866MB
% docker tag node-demo:latest kkchan9210/node-demo
% docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
kkchan9210/node-demo latest fe7a8d0c5b43 3 minutes ago 869MB
node-demo latest fe7a8d0c5b43 3 minutes ago 869MB
<none> <none> 98a2e866e7b3 24 hours ago 881MB
<none> <none> 3057672a42f9 3 days ago 866MB
% docker push kkchan9210/node-demo
Using default tag: latest
The push refers to repository [docker.io/kkchan9210/node-demo]
82c80b0f09c5: Pushed
....
- docker push 입력 시 deny가 뜨는 경우 DockerHub에 접속하기 위한 로그인 설정이 필요
- docker login 입력 → Username, Password 입력하여 로그인
공유 이미지 가져오기 (Pull)
- docker pull [Repository/ImageName] : 이미지 다운로드
- push의 경우 로그인이 필요하지만 pull의 경우 Public Repository이면 로그인 없이 가능
- docker run [ImageName] 으로 실행 시
- 로컬 시스템에 찾는 이미지가 없다면 DockerHub에서 자동으로 이미지를 폴링 (tag 정보 미 입력 시 최신 버전 이미지를 가져옴)
- 로컬 시스템에 찾는 이미지가 있다면 로컬 이미지 사용 (최신 버전 검사 X)
- 따라서 최신 이미지 버전을 받기 위해 docker pull → docker run을 실행해야 함
docker pull [Repository/ImageName]
docker pull kkchan9210/node-demo
docker run kkchan9210/node-demo
'Docker' 카테고리의 다른 글
[Docker] M1맥북으로 EC2 배포 시 오류(linux/arm64, linux/amd64), does not match the detected host platform (linux/amd64) (0) | 2023.02.28 |
---|