Docker
Docker는 애플리케이션을 컨테이너라는 격리된 환경에서 실행하기 위한 오픈 소스 플랫폼입니다.
컨테이너는 가벼운, 실행 가능한 소프트웨어 패키지로,
애플리케이션이 실행되는데 필요한 코드, 런타임, 시스템 도구, 시스템 라이브러리, 설정 등 모든 것을 포함합니다.
Docker의 핵심 개념
이미지(Image)
Docker 이미지는 애플리케이션과 그 종속성을 포함하는 경량의, 독립적인, 실행 가능한 소프트웨어 패키지입니다.
이미지는 애플리케이션을 실행하는데 필요한 모든 것을 포함하고 있으며,
컨테이너를 생성하는 데 사용됩니다.
컨테이너(Container)
Docker 컨테이너는 Docker 이미지의 실행 인스턴스입니다.
이미지를 실행하면, 이미지의 스냅샷인 컨테이너가 메모리에서 실행됩니다.
각 컨테이너는 서로 격리되어 있으며,
자체 파일 시스템, 자체 네트워크 인터페이스를 가지며,
자체 프로세스 공간 내에서 실행됩니다.
도커 파일(Dockerfile)
Dockerfile은 Docker 이미지를 자동으로 빌드하기 위한 스크립트입니다.
이 파일에는 이미지를 생성하기 위한 명령어와 순서가 포함되어 있습니다.
Dockerfile을 사용하면 애플리케이션과 그 종속성을 코드 형식으로 관리할 수 있습니다.
Docker의 이점
일관성
Docker를 사용하면 개발, 테스트, 프로덕션 환경 간에 일관된 환경을 유지할 수 있습니다.
Docker 이미지는 모든 곳에서 동일하게 실행됩니다.
빠른 배포 및 확장성
Docker 컨테이너는 가볍고 빠르게 시작됩니다.
이를 통해 애플리케이션의 배포와 확장을 손쉽게 할 수 있습니다.
격리성
각 컨테이너는 서로 독립적으로 실행되며,
애플리케이션 간의 충돌을 줄이고 보안을 강화합니다.
자동화
Dockerfile과 Docker Compose를 사용하여 애플리케이션의 빌드, 배포, 실행 과정을 자동화할 수 있습니다.
Docker는 개발자와 시스템 관리자 모두에게 애플리케이션의 개발, 배포, 실행을 더 쉽고 빠르게 만들어주는 강력한 도구입니다.
Docker Compose 도커 컴포즈
Docker Compose는 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기 위한 도구입니다.
개발, 테스트, 스테이징 환경에서의 복잡성을 줄이고,
여러 컨테이너로 구성된 서비스의 관리를 단순화합니다.
YAML 파일로 서비스, 네트워크, 볼륨 등의 설정을 관리할 수 있습니다.
아래는 그 예제입니다.
아키텍처는 복잡해보여도,
docker compose로 작성하면 아주 단순해집니다.
version: '3.8'
services:
jenkins:
image: jenkins/jenkins:lts
container_name: jenkins
ports:
- "8081:8080" # Jenkins 웹 인터페이스에 접근하기 위한 포트 (스프링과 겹치므로 변경)
- "50000:50000" # Jenkins 에이전트를 위한 포트
volumes:
- jenkins_home:/var/jenkins_home # Jenkins 데이터의 영속성을 위한 볼륨
environment:
- TZ=Asia/Seoul
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80" # 호스트의 80 포트를 컨테이너의 80 포트에 매핑
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro # Nginx 설정 파일 매핑
environment:
- TZ=Asia/Seoul
depends_on:
- springboot-app
springboot-app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./src/main/resources/application.properties:/app/src/main/resources/application.properties
environment:
TZ: Asia/Seoul
ports:
- "8080:8080"
depends_on:
- mariadb1
- mariadb2
- redis
- redis2
redis:
image: redis:latest
container_name: redis
ports:
- "6379:6379"
command: ["redis-server", "--port", "6379"]
environment:
TZ: Asia/Seoul
redis2:
image: redis:latest
container_name: redis2
ports:
- "6380:6379"
command: ["redis-server", "--port", "6380"]
environment:
TZ: Asia/Seoul
mariadb1:
image: mariadb:latest
container_name: mariadb1
volumes:
- mariadb1_data:/var/lib/mysql
ports:
- "3306:3306"
environment:
MARIADB_ROOT_PASSWORD: mypassword
MARIADB_USER: ride
MARIADB_PASSWORD: mypassword
MARIADB_DATABASE: gas_station
TZ: Asia/Seoul
mariadb2:
image: mariadb:latest
container_name: mariadb2
volumes:
- mariadb2_data:/var/lib/mysql
ports:
- "3307:3306"
environment:
MARIADB_ROOT_PASSWORD: mypassword
MARIADB_USER: ride
MARIADB_PASSWORD: mypassword
MARIADB_DATABASE: member_post
TZ: Asia/Seoul
volumes:
mariadb1_data:
mariadb2_data:
jenkins_home:
위의 예시에서는 Jenkins, Nginx, Spring Boot, Redis, 그리고 MariaDB를 포함하는 아키텍처를,
Docker Compose를 사용하여 정의하고 있습니다.
각 서비스는 docker-compose.yml 파일 안에서 선언되며, 다음과 같은 주요 구성 요소로 나눌 수 있습니다:
- 서비스(Service): 각 서비스(예: jenkins, nginx, springboot-app, redis, mariadb1, mariadb2)는 별도의 컨테이너로 실행될 애플리케이션 또는 서비스를 나타냅니다. build 또는 image를 사용하여 Docker 이미지를 지정할 수 있습니다.
- 볼륨(Volume): 데이터 영속성을 위해 볼륨을 사용합니다. 예를 들어, jenkins_home, mariadb1_data, mariadb2_data 볼륨은 각각 Jenkins와 MariaDB 인스턴스의 데이터를 저장합니다.
- 네트워크(Network): ports 설정을 통해 컨테이너와 호스트 간의 포트 매핑을 정의합니다. 이를 통해 외부에서 컨테이너에 접근할 수 있습니다.
- 의존성(Dependency): depends_on 설정을 사용하여 컨테이너 간의 의존성을 정의합니다. 이는 Docker Compose가 서비스를 시작할 순서를 결정하는 데 사용됩니다.
Docker Compose의 장점
- 간소화된 관리: 여러 컨테이너와 서비스를 단일 파일에서 관리할 수 있어,
복잡성을 줄이고 일관성을 유지할 수 있습니다. - 개발 효율성: 개발, 테스트, 프로덕션 환경 간의 차이를 최소화하며,
새로운 서비스나 업데이트를 빠르게 반복할 수 있습니다. - 환경 일관성: docker-compose.yml 파일을 통해 어디에서나 동일한 환경을 재현할 수 있습니다.
(mac, linux, windows 등) - 자동화된 워크플로우: 빌드, 실행, 테스트 과정을 자동화하고, CI/CD 파이프라인과 쉽게 통합할 수 있습니다.
결론
Docker Compose는 멀티 컨테이너 애플리케이션을 간편하게 관리할 수 있는 강력한 도구입니다.
복잡한 아키텍처도 명확하고 간결한 설정 파일 하나로 관리할 수 있으며,
개발 및 운영 효율성을 크게 향상시킵니다.