기존 시스템에서는 여러 애플리케이션을 구동하기 위해 다양한 패키지, 환경설정을 통일해야 했고, 이런 과정 속에서 패키지 끼리의 충돌이나 환경변수 충돌과 같은 문제가 많이 발생되어 시스템을 운영하기가 힘이 들었습니다.
이러한 문제점을 해결하기 위해 애플리케이션별로 환경변수와 패키지를 분리해 가상화시켜 구동하는 VM(Virtual Machine)이 나왔습니다.

하지만 VM은 Hypervisor를 통해 여러개의 운영체제를 생성하고 관리하며, 시스템 자원을 가상화하고 독립된 공간을 생성하는 작업도 Hypervisor를 거치며 성능 손실이 컸습니다.
또한, VM은 Guest OS를 사용하기 위한 라이브러리,커널 등을 포함 함으로 배포할 때 용량이 컸습니다.
이러한 단점을 보안하기 위해 나온 것이 Docker입니다.
Docker continer는 가상화된 공간을 생성할 때 리눅스 자체 기능인 chroot와 namespace와 cgroup을 사용하여 프로세스 단위의 격리 환경을 만들어 성능 손실을 줄였습니다.
또한, VM과 달리 커널을 공유해서 사용하므로 컨테이너에는 라이브러리 및 실행파일만 있어 용량이 적어지고 배포 시간이 빨라졌습니다.
어플리케이션 실행에 필요한 모든 것들을 도커 컨테이너에 담아 어떠한 런타임 환경에서도 실행 가능하도록 만들어 주는 프로그램.
즉, 어플리케이션을 패키징하고 배포하는데 유용한 프로그램.
구성 (Configuration)
애플리케이션이 실행되는 데 필요한 설정 파일이나 환경 변수들이 포함됩니다.
예: config.json, .env 파일, Nginx/Apache 설정 파일.
소스 코드 (Source code)
애플리케이션의 핵심 코드가 컨테이너에 들어갑니다.
예: Python 스크립트(.py), Java 파일, Node.js 코드.
플랫폼 (Platform)
애플리케이션이 실행되는 런타임 환경 또는 개발 플랫폼이 포함됩니다.
예: Python, Node.js, PHP, Java, Go 등의 런타임 환경.
패키지 관리자 (Package manager)
애플리케이션이 의존하는 라이브러리와 모듈을 관리하기 위해 패키지 관리자가 포함됩니다.
예: Python의 pip, Node.js의 npm, Java의 maven 또는 gradle.
의존성 (Dependencies)
실행하고자 하는 어플리케이션에 필요한 라이브러리 버전 등
기타 소스 자료
애플리케이션 동작에 필요한 데이터, 이미지, 설정 파일 등이 포함될 수 있습니다.
예: 데이터베이스 초기화 파일, 정적 이미지 파일, CSS/JS 파일.


Docker를 작동 후 "docker info"와 같은 명령어로 확인을 해보면 Client와 Server로 나뉘어 설치된 것을 확인할 수 있습니다.
Server (Docker daemon)
- Docker 이미지를 Docker container로 만들고 실행하게 해주는 daemon
- Docker daemon과 통신하거나 Docker API 요청을 기다리고 이미지, 컨테이너, 네트워크, 볼륨 등을 관리하는 역할
- REST API를 통해 Docker Client와 통신
Client (Docker CLI)
- Docker daemon과 통신 할 수 있는 명령 도구
- 사용자가 Docker와 상호작용할 수 있는 가장 우선적인 방법
- REST API를 통해 Docker daemon에 명령 송신

아래는 실제 Docker client에서 명령어를 보내 Docker daemon을 거쳐 이미지를 컨테이너로 생성하는 과정을 나타냅니다.

Docker Client : Docker를 설치하면 그것이 Client이며 build, pull, run 등의 도커 명령어를 수행합니다.
DOCKER_HOST : Docker가 띄어져있는 Server를 의미합니다. Container와 Image를 관리합니다.
Docker daemon: Docker 엔진입니다.
Registry : 외부 이미지 저장소입니다. 다른 사람들이 공유한 이미지를 내부 Docker 호스트에 pull 할 수 있다. (Docker Hub, QUAY)
고유한 이미지를 빌드하려면 이미지를 만들고 실행하는데 필요한 단계를 정의한 Dockerfile이 필요합니다.
Docker Image는 하나의 큰 바이너리 덩어리가 아니라 여러 개의 레이어로 구성되어 있습니다. 서로 다른 이미지가 여러 개의 레이어를 공유해 이미지의 저장과 전송에 효과적이며, Dockerfile 내의 각 command가 각 레이어를 구성하게 됩니다.
Dockerfile 기본 명령어 (문법)
* FROM : 컨테이너의 BASE IMAGE (운영환경)
* LABEL : 컨테이너 이미지에 컨테이너의 정보를 저장
* RUN : 컨테이너 빌드를 위해 BASE IMAGE에서 실행할 명령어
* COPY : 컨테이너 빌드 시 호스트의 파일을 컨테이너로 복사
* ADD : 컨테이너 빌드 시 호스트의 파일(tar, url 포함)을 컨테이너로 복사
ENTRYPOINT : 컨테이너 시작 시 명령어 실행 (CLI에 의해 변경 불가능한 인자를 가진 명령 수행 시 사용)
* CMD : 컨테이너 시작 시 명령어 실행 (CLI에 의해 변경 가능한 인자를 가진 명령 수행 시 사용)
* EXPOSE : Host와 연결할 포트 번호 설정
* WORKDIR : 컨테이너 빌드 시 명령이 실행될 작업 디렉토리 설정
* ENV : 환경변수 설정
VOLUME : 파일 또는 디렉토리를 호스트의 디렉토리로 마운트
* USER : 명령을 실행할 사용자 계정 설정
예시:
FROM python:3.10-slim
LABEL maintainer="이성민 <example@email.com>"
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 8080
CMD ["python", "app.py"]
컨테이너를 생성할 때 필요한 요소이며, container를 생성하고 실행할 때 읽기 전용으로 사용되며, 여러 계층으로 된 바이너리 파일로 존재합니다.
Docker Image 형태 :
[저장소 이름]/[이미지 이름]:[태그]
* 저장소 이름 : 이미지가 저장된 장소
* 이미지 이름 : 해당 이미지가 어떤 역활을 하는지 나타냄(필수)
* 태그 : 이미지 버전을 의미
Docker Image로 생성할 수 있습니다. 호스트와 다른 컨테이너로부터 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간이 생성됩니다.

Docker Desktop은 도커 컨테이너를 관리할 수 있는 그래픽 사용자 인터페이스(GUI)를 제공하는 애플리케이션입니다.
Docker Desktop의 주요 기능
1) GUI 기반의 컨테이너 관리
컨테이너 실행, 중지, 삭제, 이미지 빌드 등의 작업을 클릭만으로 쉽게 수행 가능.
터미널 명령어를 입력하지 않고도 시각적으로 컨테이너 상태를 확인.
2) Docker Compose 통합
Docker Compose를 기본 제공하여 여러 컨테이너를 동시에 구성하고 실행할 수 있음.
docker-compose.yml 파일로 컨테이너 정의 및 실행.
3) Kubernetes 통합 지원
Kubernetes 클러스터를 활성화하고 관리할 수 있는 기능 제공.
Docker와 Kubernetes를 함께 사용하는 DevOps 환경에서 유용.
4) 리소스 모니터링
GUI에서 컨테이너별 CPU, 메모리 사용량을 실시간으로 확인.
컨테이너 및 이미지의 크기와 네트워크 상태를 시각적으로 관리.
5) 개발 환경 통합
Visual Studio Code, IntelliJ IDEA 등 IDE와 연동하여 로컬 개발에 사용 가능.
CI/CD 파이프라인 설정 및 테스트에 유리.
6) Cross-Platform 지원
Windows와 macOS에서 동일하게 사용할 수 있으며, Linux 가상화 환경도 포함.
Docker Desktop의 장점
Docker Desktop의 단점
결론 :