리눅스는 커널은 같고, 생태계는 다양한 구조이다.
패키지나 라이브러리에 따라서 배포반의 종류가 다양하다.
도커에서 격리라는 개념에서
OS는 하드웨어를 관장하는 부분(커널: 안정성에 관한 부분으로 업데이트 관련 크지 않음)과 소프트웨어를 관장하는 부분(여러 라이브러리, 도구 등으로 확장판) 으로 나눈다.
그위에 APP를 동작시키면 어떤 OS인가에 따라서 종속된다.
(jenkins 는 리눅스 배포판 별로 설치환경에 따라서 설정값과 라이브러리가 다 다르다. )
=> App는 주변환경에 영향을 받는다.
과거에 App에 OS까지 묶어서 배포를 하자. => VM
가상머신의 특징
앱 + OS + 필요한 도구까지 전부 포함하여 격리된 가상 환경에서 실행
Hypervisor가 하드웨어를 가상으로 분리해 여러 개의 OS를 동시에 실행
VM 위에 올라간 OS: Guest OS, 실제 OS: Host OS
App입장에서는 현재 운영되고 있는 환경이 가상인지 실제인지 알 수 없다.
독립된 공간에서 혼자 돌고 있어서 오류가 없다.
| 장점 | 단점 |
|---|---|
| 완전 격리, 안정성, 보안 | 느림, 용량 큼, 중복 많음 (OS 전체 포함) |
OS의 커널은 공유하고, OS의 실행환경(lib, bin)은 컨테이너마다 격리한다.
Docker는 컨테이너 기반 가상화 도구이다.
| 비교 | 가상머신 | Docker 컨테이너 |
|---|---|---|
| 커널 | Guest OS 포함 (별도) | Host OS 커널 공유 |
| 실행 속도 | 느림 | 빠름 |
| 용량 | 큼 (GB 단위) | 작음 (MB 단위) |
| 부팅 시간 | 수십 초 | 수 초 내외 |
| 격리 방식 | 하드웨어 수준 | 운영체제 수준 (namespace, cgroup 등) |
격리와 가상화
완전한 가상화를 위해서 docker가 host os를 공유해서 쓴다.
도커는 커널은 공유하고 바이너리와 라이브러리는 각자 격리한다.
docker는 리눅스 커널을 사용해야 하기 때문에
Window/macOS 에서는 내부적으로 리눅스 커널이 없다.
docker를 사용하기 위해서는 가상 리눅스 환경(WSL)을 만들어서 docker를 구동해야한다.
컨테이너를 실행하기 위한 실행 환경의 설계도
docker image는 레이어로 이루어져 있다.
잘 만들어 놓은 읽기 전용이고 여러 개의 층을 위에 올려서 구성한다.
도커 이미지를 저장하고 있는 저장소 : 레지스트리 (대표적으로 도커 허브)
도메인 주소 / 저장소 이름 / 이미지 이름 : 이미지 버전
Docker.io/library 는 도커이미지의 공식 이미지 Namespace이다.
Azure에서 받으려면 gdhong.azurecr.io/order:1.0
도커 이미지를 실행한 인스턴스
실행 컴퓨터에서는 pull로 도커 이미지를 다운로드 받아서 하드디스크에 저장된다.
가상 CD를 CD룸에 넣는 것 처럼 run으로 이미지를 메모리에 올려서 구동한다.
기존의 만들어진 것을 재활용하는 관점
차이점을 기록하는 형태로 레이어링을 한다.
Base layer
레이어를 만들어서 이미지를 만드는 스크립트
하나의 명령어가 하나의 레이어로 추가된다.
FROM : 사용할 기본 이미지(베이스 이미지)
RUN : 읽기 전용 이미지 위에 올릴 추가 레이어 (RUN 당 하나의 레이어 추가)
WOEKDIR : 작업할 디렉토리 지정
COPY : 로컬 파일/폴더를 이미지로 복사(앞에 있는 것을 뒤에 있는 것으로 복사한다. )
ENTRYPOINT : 아무 조건을 안주고 이미지를 컨테이너화 시킬 때 구동할 명령어
Docker는 백그라우드에서 도는 데몬(서버) 와 사용자가 명령을 보내느 CLI(도커 명령줄 도구) 로 구성된다.
사용자가 docker image 을 입력하면, CLI가 데몬에게 명령을 전달해 작업을 처리한다.
| 명령어 | 설명 |
|---|---|
docker images | 로컬 PC에 다운로드된 이미지 목록 확인 |
docker pull 이미지명 | Docker Hub에서 이미지 다운로드 |
docker rmi 이미지명 | 이미지 삭제 (rmi = remove image) |
docker image rm 이미지명 | 위 명령과 동일 (권장 사용 방식) |
컨테이너 제어 : docker run
container run 으로 컨테이너 실행
docker run [옵션] [이미지명] [명령어]
--name : 컨테이너 이름을 지정한다.
-d : 백그라운드 실행한다.
-p 8080:80 : 호스트(8080)와 컨테이너(80)를 연결한다.
docker run --name my-nginx -d -p 8080:80 nginx
컨테이너는 메모리에 올라가 실행됨
실행 중인 컨테이너는 docker ps로 확인 가능
중지된 컨테이너는 docker ps -a로 확인 가능
컨테이너를 완전히 제거해야 해당 이미지도 안전하게 삭제 가능함
이미지 빌드 : docker build
도커 빌드는 도커 파일을 이용해서 이미지를 만드는 행위를 bulid라고 한다.
docker build --tag[생성할 이미지의 이름]:[태그 이름].
. 은 도커 파일의 위치이다.
. 만 작성할 경우 해당 명령어를 터미널에서 입력할 때 터미널의 위치가 dockerfile이 있는 위치여야 한다.
이미지 푸시 : docker push
image push는 하드 안에 저장된 이미지를 만천하에 공개하고 싶으면 push한다.
push를 하려면 권한이 있어야 한다.
1. docker login
2. docker tag myapp:1.0 [도커허브 아이디]/myapp:1.0
3. docker push [도커허브 아이디]/myapp:1.0
docker image pull nginx:latest
도커 이미지 nginx:latest를 하드디스크에 다운받는다.

docker run --name my-nginx -d -p 8080:80 nginx:latest
-d 는 데몬으로 백그라운드에서 실행
-p 는 container 내에 실행(80)할 때 내 서버의 포트(8080)와 연결해주는 역할(서버포트와 컨테이너 안에 포트와 연결한다.) -> 8080 -> 80 으로 컨테이너에 들어온다.
docker run --name my-new-nginx -d -p 8081:80 nginx:latest
다른 nginx 컨테이너 페이지를 열어서 동시에 실행 가능하다.
docker container ls로 실행 중인 모든 컨테이너의 목록을 확인할 수 있다.

pip install httpie
http GET http://localhost:8080
http GET http://localhost:8081
으로 서로 다른 것을 확인할 수 있다.
docker 이미지를 삭제할 때는 해당 이미지를 사용하는 컨테이너를 먼저 정리 해야한다.
docker container stop [컨테이너명]
docker container ls -a 으로 stop된 결과를 확인할 수 있다.

docker container rm [컨테이너명]
docker image rm [이미지명]
컨테이너 이름이나 컨테이너 ID을 넣어서 정지할 수 있다.
/Docker/index.html
<html>
<body>
<center>
<br/></br>
<img src="https://raw.githubusercontent.com/acmexii/demo/master/materials/smile.jpg">
<br/></br>
<h1> Hi~ My name is Hong Gil-Dong...~~~ </h1>
</center>
</body>
</html>
</center>
</body>
</html>
/Docker/Dockerfile
FROM nginx
COPY index.html /usr/share/nginx/html/
만든 도커 이미지를 빌드한다.
docker build -t [도커허브 아이디]/welcome:v1 .

도커허브에 만든 도커이미지를 push한다.
docker login

docker push [도커허브아이디]/welcome:v1

docker run --name=welcome -d -p 8080:80 [도커허브아이디]/welcome:v1

mvn spring-boot:run 했던거를 mvn package 으로 해서
컴파일 -> test 코드 컴파일 -> 실제 test -> jar로 만들기 을 자동으로 수행한다.
해당 과정의 결과가 target/ 폴더에 들어가게 된다.
실제 실행을 할 수 있다.
✅ 결과
java -jar target/inventory-0.0.1-SNAPSHOT.jar 으로 동일하게 mvn spring-boot:run 처럼 실행된다.
.jar 는 독립 실행 가능한 spring-boot의 앱이다. /inventory/Dockerfile
FROM openjdk:15-jdk-alpine
COPY target/*SNAPSHOT.jar app.jar
EXPOSE 8080
ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENTRYPOINT ["java","-Xmx400M","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar","--spring.profiles.active=docker"]
터미널에서 order, gateway 폴더로 이동해서
각각의 Dockerfile이 있는 위치에서 아래를 실행한다. (cd order, cd gateway 각각에서 실행)
mvn package
docker build -t [dockerhub ID]/inventory:[오늘날짜] .
docker push [dockerhub ID]/inventory:[오늘날짜]

방법 1 : 바로 Dockerfile -> build -> run -> push
dockfile 내부에 직접 빌드가 있으면 그때 실행된다.
FROM nginx:latest
COPY ./index.html /usr/share/nginx/html
방법 2 : mvn package 후 dockerfile -> build -> push
dockerfile 을 실행하기 전에 Jar 를 생성한다.
FROM openjdk:17
COPY target/myapp.jar /app/app.jar
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
| 구분 | 방식 1 | 방식 2 |
|---|---|---|
| 개요 | Dockerfile만으로 이미지 생성 및 실행 | Java 프로젝트를 먼저 mvn package로 빌드 후 Docker 이미지 생성 |
| JAR 파일 생성 시점 | Dockerfile 내부에서 직접 빌드 (있다면) | Dockerfile 실행 전에 미리 JAR 생성 (mvn package) |
| 장점 | Docker 하나로 모든 작업 처리 가능 (CI/CD에 적합) | 빌드 결과를 미리 확인 가능, 실패 시 빠르게 디버깅 |
| 예시 대상 | 정적인 nginx 같은 이미지 | Java/Spring Boot 앱과 같이 빌드가 필요한 프로젝트 |