docker.com에 들어가서 developer 메뉴에서 원하는 버전 다운로드
macOS와 windows의 경우에는
도커 데스크탑
도커 툴박스
설치가 필요함
linux의 경우 기본적으로 도커 엔진을 지원하기 때문에 바로 설치가 가능
macOS
https://docs.docker.com/desktop/install/mac-install/
windows
https://docs.docker.com/desktop/install/windows-install/
macOS 기준
도커 앱 실행. 우측 상단에 도커 아이콘 표시. 도커 엔진 실행중인 상황이다.
docker pull [이미지 이름]
이미지에는 이름과 태그가 있다. 태그는 node:17과 같이 주로 버전을 표기하는데 사용하는 옵션적인 이름이다.
# 도커로 로그인
docker login
# 도커에서 로그아웃
docker logout
# 도커에 이미지 푸시
# 이미지 태그 이름도 [docker username]/[repository]
docker push [docker username]/[repository]
# 이미지 이름 변경
docker tag [old name] [new name]
도커 이미지를 푸시 풀을 번갈아 가면서 해야 함. 안 그러면 docker run 시 로컬에 있는 이미지를 사용하게 됨
docker images
이미지 확인
docker image inspect [image]
docker run node
-> 원하는 디렉토리에서 명령어 실행하면 도커 허브에서 node 이미지를 가져와 컨테이너로 만들어 줌
이때 컨테이너의 이름은 무작위로 만들어 진다.
컨테이너의 이름을 별도로 지정하고 싶다면
docker run --name [이름] node
이런식으로 입력해 준다.
원래 이름을 바꾸고 싶다면
docker rename [oldname] [newname]
컨테이너 실행을 중단할 때는
docker stop [아이디] 또는 [컨테이너 이름]
실행을 재개할 때는
docker start [아이디] 또는 [컨테이너 이름]
컨테이너 내 노드 터미널 사용하기
docker run -it node
docker ps -a
docker rm [container id]
다만 실행중인 컨테이너는 stop 명령어로 중단을 시킨 뒤 삭제해야 한다.
강제로 삭제하려면
docker rm --force [id] or [name]
이미지를 삭제하려면
docker rmi [image]
사용하지 않는 이미지 삭제
docker image prune
컨테이너 중지할 때 자동 삭제
run에 --rm 옵션 추가
docker run --rm [image]
해당 디렉토리에 가서 Dockerfile이라는 파일을 생성
Dockerfile은 컨테이너 내에서 사용하는 일종의 셸 스크립트
Dockerfile과 같은 디렉토리에 있는 파일들을 컨텍스트라고 부름
FROM node
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD ["node", "server.js"]
# 특정 도커 이미지를 기반으로 한다.
FROM [base image]
# 파일들을 컨테이너로 복사. 보통 COPY . . 이나 COPY . /app 등의 형태로 사용
COPY [이미지로 복사할 파일들] [이미지 내 경로]
# Dockerfile은 기본 디렉토리가 루트이기 때문에 설정
# COPY . . 등으로 사용할 때 /app으로 경로가 지정됨
# 다만 COPY . . 보다는 COPY . /app 같이 명시적으로 하는 것을 추천
WORKDIR /app
# WORKDIR 에서 명령어 실행
RUN npm install
# RUN은 이미지를 빌드할 때 사용
# CMD는 컨테이너가 만들어지고 사용
# RUN과 달리 배열 형식으로 명령어를 입력
CMD ["node", "server.js"]
# 컨테이너가 호스트에 개방할 포트 번호를 입력
EXPOSE 80
이제 이미지를 빌드해야 한다.
# Dockerfile이 위치한 곳에서 해당하는 모든 파일들을 이미지로 빌드
docker build .
docker build . -t [이미지 이름]
# 도커와 호스트간 연결 포트인 80과 호스트와 외부 연결 포트인 8080을 연결(포트포워딩)
docker run -p 8080:80 [이미지]
도커는 레이어 기반이기 때문에 레이어가 바뀌지 않은 부분은 캐싱하여 사용한다.
그러나 index.html 등의 일부 소스가 바뀌어서 이미지를 다시 빌드할 때 npm install 등 패키지 까지 다시 빌드하는 경우가 있다.
이럴 경우 레이어를 세분화하여 최적화를 해줄 수 있다.
# package.json 내 dependencies가 바뀌지 않는다면 npm install 다시 빌드하지 않음
FROM node
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
docker create
docker start
docker run
docker attach
run = create + start + attach (default)
그러나 run (default = attached 모드)은 컨테이너를 foreground 실행하여 cli를 블로킹하고 출력값을 내줌. -d 옵션으로 background 실행
반면 start (default = detached 모드)는 컨테이너를 background 실행. -a 옵션으로 foreground 실행
아니면
docker logs [컨테이너] // 한번 로그 보기
docker logs -f [컨테이너] // 로그를 follow하여 attach 처럼 사용 가능
다음은 파이썬 코드이다.
from random import randint
min_number = int(input('Please enter the min number: '))
max_number = int(input('Please enter the max number: '))
if (max_number < min_number):
print('Invalid input - shutting down...')
else:
rnd_number = randint(min_number, max_number)
print(rnd_number)
Dockerfile이다.
FROM python
WORKDIR /app
COPY . /app
CMD ["python", "rng.py"]
해당 코드를 도커로 빌드하면 에러가 나타난다.
이 때 interactive 모드인 -i 옵션과 pseudo-terminal을 만들어 주는 -t 옵션을 결합해 빌드하면 입력값을 넣을 수 있는 상태가 된다.
재실행 하려면
# attach 옵션과 interacticve 옵션
# pseudo terminal(-t)은 빌드할 때 기억 된 상황
docker start -a -i [container]
# exdir 내 모든 파일 추가
docker cp exdir/. [container]:/app
# 특정 파일 추가
docker cp exdir/test.js [container]:/app
반대로 컨테이너 내에 있는 파일을 밖으로 복사하고 싶을때는 위치만 바꾸면 된다.
docker cp [container]:/app exdir/test.js