Docker 공부 끄적(1)-이미지/컨테이너

JH Bang·2023년 2월 21일
0

개발 지식

목록 보기
6/11

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 [이미지 이름]

이미지 name:tag

이미지에는 이름과 태그가 있다. 태그는 node:17과 같이 주로 버전을 표기하는데 사용하는 옵션적인 이름이다.

이미지 푸시

# 도커로 로그인
docker login

# 도커에서 로그아웃
docker logout

# 도커에 이미지 푸시
# 이미지 태그 이름도 [docker username]/[repository]
docker push [docker username]/[repository]
# 이미지 이름 변경
docker tag [old name] [new name]

도커 이미지를 푸시 풀을 번갈아 가면서 해야 함. 안 그러면 docker run 시 로컬에 있는 이미지를 사용하게 됨

image list

docker images 

이미지 확인

image inspect

docker image inspect [image]

nodejs 환경 세팅

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은 컨테이너 내에서 사용하는 일종의 셸 스크립트
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 [이미지]

re-build

도커는 레이어 기반이기 때문에 레이어가 바뀌지 않은 부분은 캐싱하여 사용한다.
그러나 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 처럼 사용 가능

docker run -it

다음은 파이썬 코드이다.

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 
profile
의지와 행동

0개의 댓글