
Docker
- 컨테이너화된 애플리케이션을 개발, 배포, 실행하기 위한 플랫폼
- 컨테이너 기반 가상화 기술을 사용하여 애플리케이션과 해당 환경을 격리된 컨테이너로 패키징
- 기존 가상화 방식은 가상머신을 사용해 호스트 시스템 위에 독립된 운영체제를 실행하였으나 도커는 호스트 운영체제와 리소스를 공유하면서 각 애플리케이션을 격리된 컨테이너로 실행해 빠르고 가볍게 애플리케이션을 실행시킬 수 있음
- 환경의 영향을 받지 않고 독립적인 컨테이너 단위로 사용될 수 있다
- https://docs.docker.com/reference/
1. Docker Container
- Docker Image를 기반으로 생성된 가볍고 독립적인 실행 단위
- 호스트 OS와 다른 컨테이너들과 격리되어 필요에 따라 자원을 할당받아 실행
1) 컨테이너 생성
$ docker run -it --name mycontainer -p 8080:8080 openjdk:11
- '-d' : 컨테이너를 백그라운드에서 실행
- '-i' : 컨테이너와 상호작용을 위해 표준 입력 연결
- '-t' : 터미널 연결
- '-p <호스트 포트>:<컨테이너 포트>' : 호스트 포트와 컨테이너 포트 연결
- '--name <컨테이너 이름>' : 컨테이너 이름을 설정
- '--rm' : 컨테이너 종료시 자동 삭제
- '-v <호스트 경로>:<컨테이너 경로>' : 호스트와 컨테이너의 디렉토리 연결
- '-e <환경변수>' : 컨테이너 내부의 환경변수 설정
- '--link <다른 컨테이너 이름>:<별명>' : 다른 컨테이너와 연결
- '--network <네트워크 이름>' : 컨테이너가 속한 네트워크 설정
- '--expose <포트>' : 컨테이너의 포트 노출
- '--entrypoint <명령어>' : 컨테이너 시작 시 실행될 명령어 설정
- '--user <사용자>' : 컨테이너 내부에서 실행될 사용자 설정
- '--restart <정책>' : 컨테이너 재시작 정책 설정
2) 컨테이너 시작
$ docker start [컨테이너 이름 또는 ID]
- '-a' : 컨테이너와 터미널을 연결
- '-i' : 컨테이너와 상호작용을 위해 표준 입력 연결
- '-p' : 호스트와 컨테이너의 포트 연결
- '-d' : 컨테이너를 백그라운드에서 실행
- '-e' : 컨테이너 내부 환경변수 설정
- '-u' : 컨테이너 내부에서 실행될 사용자 설정
- '-a' : 컨테이너 출력 표시
3) 컨테이너 중지
$ docker stop [컨테이너 이름 또는 ID]
- '-t' : 컨테이너 종료까지 대기시간 설정, 기본값 10초
4) 컨테이너 목록
$ docker ps
- 현재 실행중인 도커 컨테이너 목록 출력
- '-a' : 모든 컨테이너 목록 출력
- '-f' : 필터링하여 출력
- -f "name=찾을 컨테이너의 이름"
- label 커맨드에서 붙인 라벨
- exited 종료된 컨테이너의 종료 코드
- status 컨테이너의 상태(created, restarting, running 등)
- ancestor 이미지를 공유받은 컨테이너
- before 설정 컨테이너를 기준으로 전에 만들어진 컨테이너
- since 설정 컨테이너 기준 이후에 만들어진 컨테이너
5) 컨테이너 삭제
$ docker rm [컨테이너 이름 또는 ID]
- '-f' : 강제 삭제
- '-l' : 해당 컨테이너를 참조하는 링크 제거
- '-v' : 컨테이너와 관련된 볼륨 제거
- '-n' : 컨테이너 이름 지정
- '-q' : 컨테이너의 ID만 출력
2. Docker Image
- 도커 컨테이너를 생성하기 위한 템플릿
- 애플리케이션을 실행하는데 필요한 모든 환경과 라이브러리, 소스 코드 등을 포함
- 수정 불가
1) 이미지 목록 확인
$ docker images
2) 이미지 삭제
$ docker rmi [이미지 이름 또는 ID]
3) 이미지 pull
$ docker pull [이미지:버전]
4) 이미지 push
$ docker push {도커 유저 이름}/{이미지명}:{태그}
- 도커 허브에 이미지를 푸시하려면 해당 이미지와 동일한 이름을 가진 도커 허브 레포지토리가 있어야 함
3. Docker Build
-
프로젝트를 빌드하여 .jar 파일 생성
- Dockerfile 스크립트 내용대로 빌드된 jar 파일을 도커 컨테이너에 복사하여야 함
-
프로젝트 최상위 경로에 Dockerfile 생성

- FROM : 빌드할 이미지의 기반이 되는 도커 이미지 설정
- COPY < source> < directory> : 로컬 파일 시스템에서 파일 또는 디렉토리를 이미지에 복사
- ENRTYPOINT : 컨테이너 실행 시 실행할 명령 또는 스크립트 지정
- RUN : 이미지 빌드 단계에서 실행 할 명령어 지정
- LABEL : 이미지에 메타 데이터 추가
- 도커 빌드
$ docker build -t [dockerUserName/repository:tag . ]
- 마지막 "."은 현재 디렉토리에 있는 Dockerfile을 사용하겠다는 의미
Docker build 실습 중 빌드 후 해당 이미지로 컨테이너를 실행시키면
"Error: Invalid or corrupt jarfile /app.jar" 오류가 나서 한참 헤맸다.
어째서인지 프로젝트 내 build/libs에 애플리케이션 빌드 후에 생긴 .jar 파일과 이름이 같은
빈 디렉토리가 생성되어서 도커 빌드 부터 문제가 생겨서 실행이 되지 않았던 것 같다.
프로젝트 빌드시에 무언가 오류가 생겼던 것 같은데 해당 디렉토리를 삭제후 다시 도커 빌드 후 실행시키니
정상 작동 하였다.
같은 느낌으로 .jar;D 란 디렉토리도 같은 경로에 생성되었는데 아직 이유를 모르겠다......
도커 이미지는 클래스, 컨테이너는 클래스에서 생성된 인스턴스와 비슷하단 생각이 들었다.
4. Docker Compose
$ docker-compose up {특정 이미지}
여러 컨테이너를 동시에 실행 하기
- 동시에 실행할 컨테이너들을 생성
- 예시
nginx 이미지를 기반으로 한 sebcontents/client 이미지를 이용하여 client 컨테이너 생성
spring 이미지를 기반으로 한 0xnsky/server-spring 이미지를 이용하여 server 컨테이너 생성
- docker-compose.yml(.yaml) 파일 생성
version: '3.8'
services:
nginx:
image: sebcontents/client
restart: 'always'
ports:
- "8080:80"
container_name: client
spring:
image: 0xnsky/server-spring
restart: 'always'
ports:
- "4999:3000"
container_name: server-spring
- 생성한 yml 파일의 위치에서 명령어 입력해 컨테이너 구동
docker-compose up -d
- '-d' : 컨테이너를 백그라운드에서 실행
- yml 파일에 정의된 이미지를 컨테이너로 실행

- yml 파일에 정의한 대로 컨테이너가 함께 구동하는 것을 확인 가능
