- 여러 컨테이너가 함께 실행되는 환경에서, 하나의 파일 내에 정의하여 여러 컨테이너를 관리하기 위한 도구를 의미합니다. 즉, 여러 컨테이너를 관리할 때, 단일 명령어를 통해 생성-관리-배포하는 기능을 수행하는 역할을 합니다.
- 기존의 Dockerfile을 통해 단일 컨테이너를 ‘생성-관리-배포’하는 과정에서의 처리과정은 간단하였으나 여러 컨테이너를 일괄 띄우는데 시간 소요가 많이 되기에 이를 사용합니다. - 이러한 컨테이너 관리는 YAML 파일 형식을 사용하여 서비스, 네트워크 및 볼륨 같은 애플리케이션 서비스를 구성할 수 있습니다. 또한 개발, 테스트, 스테이징, 운영 및 CI 워크플로우 환경에서 애플리케이션을 이동하여 배포가 가능하기에 관리가 매우 편리합니다.
[ 더 알아보기 ] 💡 단일 컨테이너를 관리하는데 Dockerfile로 구성을 하였는데, 그럼 Docker Compose에서는 YAML/YML 파일을 사용하면 Dockerfile을 사용 안 해도 되는 것일까?
- 결론적으로, Docker Compose를 사용할 때에도 Dockerfile은 필요합니다. - Docker Compose의 YAML 파일은 서비스의 구성을 정의하지만, 각 서비스가 사용하는 개별 도커 이미지를 빌드하기 위해서는 Dockerfile이 필요합니다. - 그렇기에 Docker Compose는 여러 Dockerfile을 관리하는데 도움이 되는 도구라고 생각하면 됩니다.
1. Docker Compose 사용 목적
💡 Docker Compose 사용 목적 - 단일 컨테이너를 구성하는 Dockerfile만으로도 Docker를 실행하고 관리할 수 있지만, Docker Compose를 사용해야 하는 목적에 대해 알아봅니다.
사용 목적
설명
단순화된 제어
단일 YAML 파일에서 다중 컨테이너 애플리케이션을 정의하고 관리할 수 있어 복잡한 작업이 단순화됩니다.
효율적인 협업
Docker Compose 구성 파일은 쉽게 공유할 수 있어 협업을 촉진합니다.
신속한 애플리케이션 개발
Compose는 컨테이너를 생성하는 데 사용된 구성을 캐시하며 변경되지 않은 서비스를 다시 시작하면 기존 컨테이너를 재사용합니다.
환경 간 이식성
Compose는 Compose 파일의 변수를 지원합니다. 이러한 변수를 사용하여 다양한 환경이나 다양한 사용자에 맞게 구성을 사용자 정의할 수 있습니다.
광범위한 커뮤니티 및 지원
Docker Compose는 활기차고 활동적인 커뮤니티의 이점을 누리며, 이는 풍부한 리소스, 튜토리얼 및 지원을 의미합니다.
1. Dockerfile에 필요한 모든 서비스를 정의합니다. (Define all your required services in a Dockerfile)
- Dockerfile 내에 각 다운로드 할 이미지와 실행 할 컨테이너에 대해 정의합니다.
2. Compose 파일(YAML/YML) 내에 각 서비스 간의 관계를 정의합니다. (Define the releationship between each service in a Compose file)
- 이 파일에는 실행할 서비스(컨테이너)들과 그 설정들을 포함하고 있습니다. - 사용 할 파일 내용은 Docker 이미지, 포트 매핑, 볼륨 마운트, 네트워크 설정, 환경 변수 등이 정의됩니다.
3. Docker Compose를 사용하여 애플리케이션을 시작합니다. (Use Docker Compose to start the application)
- Docker Compose의 실행 명령어 ‘docker-compose up’ 명령어를 수행하여 일괄 서비스를 실행합니다. - 이 명령어를 통해서 Docker Compose 파일에 정의된 모든 서비스를 시작합니다. - 필요한 Docker 이미지가 로컬에 없으면 자동으로 다운로드하고, 컨테이너를 생성하고 시작합니다.
+ Docker Compose의 서비스 상태를 확인합니다.
- Docker Compose의 상태 확인 명령어 ‘docker-compose ps’ 명령어를 수행하여 서비스의 상태를 확인합니다. - 현재 실행 중인 서비스의 상태를 확인할 수 있습니다.
+ 필요에 따라 Docker Compose의 서비스를 중지합니다.
- Docker Compose의 중지 명령어 ‘docker-compose stop’ 명령어를 수행하거나 ‘docker-compose down’ 명령어를 수행하여 모든 서비스를 중지하고 컨테이너, 네트워크, 볼륨을 삭제합니다.
3. Docker Compose 명령어
Docker Compose 명령어
설명
docker-compose up
Docker Compose 파일에 정의된 모든 서비스를 시작합니다. 필요한 이미지를 자동으로 다운로드하고 컨테이너를 생성, 시작합니다.
💡 version 속성 - Docker Compose 내의 ‘파일 형식에 대한 버전’을 의미합니다. 즉, 파일 내에서 버전 별로 사용할 수 있는 특정 설정이나 기능이 달라지기에 이에 맞는 버전을 이용합니다.
- 각 버전은 특정 Docker release와 관련이 있으며 다른 버전들보다 더 많은 기능을 지원하거나 더 많은 설정 옵션을 제공할 수 있습니다. 예를 들어 ‘3.x’ 버전의 Compose 파일은 Docker Swarm을 사용하여 서비스를 배포하는 데 필요한 설정을 지원합니다. - 버전을 지정하지 않으면, Docker Compose는 기본적으로 가장 낮은 버전을 사용합니다. 이것은 오래된 설정을 호환성을 유지하지만, 최신 설정을 사용할 수 없을 수 있음을 의미합니다. - 이 버전은 Docker Compose 파일의 최상단에 지정하며, Docker Compose 도구 자체의 버전과 다르게 적용이 됩니다. - 버전은 시멘틱 버저닝을 이용하며 Major, Minor, Patch 형태로 구성되어 설정이 됩니다.
💡 사용 예시
- 해당 예시에서는 Compose 파일 내에서 파일 형식을 version을 3.8으로 사용함을 지정하였습니다.
[ 더 알아보기 ] 💡 그래서 Docker Compose Version을 몇 버전을 사용하는 게 제일 좋은가? 최신 버전을 사용하면 docker compose를 구성하는 파일 형식이 많이 바뀌는 거 아닌가?
- 최신 버전을 사용하는 것이 좋습니다. 단, Docker Compose 버전을 최신으로 유지하더라도 매번 형식이 바뀌는 것은 아닙니다. - Docker Compose의 버전 업데이트는 주로 새로운 기능을 추가하거나 기존 기능을 개선하기 위한 것으로, 대부분의 경우 기존에 사용하던 Docker Compose 파일의 형식을 계속 사용할 수 있습니다. - 하지만 새로운 버전에서는 일부 더 이상 지원되지 않는 기능이 있을 수 있으므로, 항상 릴리스 노트를 확인하고 필요한 경우 Docker Compose 파일을 업데이트하는 것이 좋습니다.
3. services 속성
💡 services 속성
- 도커 컨테이너의 그룹을 정의하는 데 사용됩니다. 그룹 내에는 애플리케이션의 서비스가 포함되며, 각 서비스는 독립적으로 실행되는 컨테이너를 나타냅니다.
- 이러한 서비스는 Docker 이미지를 기반으로 Dockerfile을 참조하여 빌드가 되거나 Docker Hub에서 해당 이미지를 가져옵니다. - 예를 들어, 간단한 웹 애플리케이션의 Docker Compose 파일에는 웹 서버와 데이터베이스라는 두 개의 서비스가 포함될 수 있습니다. 웹 서버는 웹 애플리케이션을 호스팅 하고, 데이터베이스는 데이터를 저장하는 역할을 합니다.
💡 사용 예시
- 해당 예시에서는 services 속성을 통해 web, redis라는 서비스를 그룹화합니다. - web, redis는 독립적으로 실행되는 컨테이너입니다.
💡 networks 속성 - 서비스 간의 네트워킹을 정의하고 관리하는 데 사용되는 속성을 의미합니다. - 이를 통해 도커 컨테이너 간에 별도의 네트워크를 생성하고 구성할 수 있어서 각 컨테이너가 서로 통신을 할 수 있습니다. - 또한 이를 사용하여 서비스 간의 연결을 보다 세밀하게 제어하고 보안을 강화하여 서비스 간의 의존성을 관리할 수 있습니다.
사용자 인터페이스와 관련된 서비스에 사용되는 네트워크. 이 네트워크에 연결된 서비스는 사용자 인터페이스를 제공하는 데 필요한 기능을 실행합니다.
back-tier
데이터베이스와 같은 백엔드 서비스에 사용되는 네트워크. 이 네트워크에 연결된 서비스는 데이터 처리와 같은 백엔드 기능을 실행합니다.
💡 [참고] networks의 하위 속성
네트워크 하위 속성
설명
name
사용자 정의 네트워크의 이름을 명시합니다.
driver
네트워크 드라이버 유형을 지정합니다. (예: bridge, host, overlay, none 등)
driver_opts
네트워크 드라이버에 전달할 추가 옵션을 지정합니다.
attachable
Swarm 서비스가 아닌 컨테이너들이 이 네트워크에 연결될 수 있도록 합니다.
enable_ipv6
이 네트워크에서 IPv6 네트워킹을 활성화합니다.
external
외부에서 이미 만들어진 네트워크를 사용하는 경우 이 옵션을 사용합니다.
ipam
네트워크의 IP 주소 관리 옵션을 지정합니다.
internal
이 네트워크가 외부 네트워크에 연결되지 않도록 합니다.
labels
네트워크에 메타데이터를 추가하는 데 사용되는 라벨을 지정합니다.
💡 사용 예시
- 해당 Compose 파일 내에서는 두 개의 네트워크와 하나의 서비스를 정의합니다.
1. frontend(service)
- image 속성 : "frontend" 서비스에서 사용할 Docker 이미지를 지정합니다. 이 경우 "example/webapp" 이미지를 사용합니다. - network 속성 : 이 서비스가 속한 네트워크를 지정합니다. "frontend" 서비스는 "front-tier"와 "back-tier"라는 두 개의 네트워크에 연결됩니다.
2. networks
- 사용할 네트워크를 정의하며, "front-tier"와 "back-tier"라는 두 개의 네트워크를 정의하고 있습니다.
💡 Configs 속성 - 서비스(컨테이너) 간에 서비스 구성에 필요한 설정을 공유하는 데 사용이 됩니다.
- 해당 속성을 통해 도커 서비스의 설정을 외부화하고 중앙화하는 데 도움이 됩니다. 이를 통해 애플리케이션 코드에서 설정을 분리하고, 동일한 설정을 여러 서비스에 재사용하거나, 서비스를 다양한 환경에서 실행하는 데 필요한 다양한 설정을 관리할 수 있습니다. - 서비스 내에 configs 속성을 사용하면 서비스 별로 설정을 다르게 지정하거나, 동일한 설정을 여러 서비스에 제공하는 등의 유연성을 제공합니다.
yarn 명령을 실행하여 필요한 패키지들을 설치 (npm을 사용할 경우 RUN npm install)
COPY . .
호스트 컴퓨터의 모든 파일을 작업 디렉토리에 복사
EXPOSE 3000
컨테이너의 3000번 포트를 외부에 노출. 애플리케이션이 해당 포트에서 실행될 것임을 나타냄
CMD [ "yarn", "start" ]
컨테이너가 실행되면 yarn start 명령을 실행 (npm을 사용할 경우 CMD [ "npm", "start" ])
FROM node:18-alpine
# Set the working directory in the container
WORKDIR /src
COPY package*.json ./
RUN yarn
# or
# RUN npm install
COPY . .
EXPOSE 3000
CMD [ "yarn", "start" ]
# or
# CMD [ "npm", "start" ]
4. spring-boot-app/Dockerfile 구성
💡 spring-boot-app/Dockerfile 구성
- 아래와 같은 구조를 설정하였습니다.
명령어
설명
FROM bellsoft/liberica-openjdk-alpine:17
베이스 이미지로 Java 17버전이 포함된 Docker 이미지를 사용
# FROM openjdk:8-jdk-alpine
필요시, OpenJDK 8 버전을 기반으로 하는 이미지를 설정할 수 있습니다.
# FROM openjdk:11-jdk-alpine
필요시,OpenJDK 11 버전을 기반으로 하는 이미지를 설정할 수 있습니다.
CMD ["./gradlew", "clean", "build"]
Gradle을 사용해 빌드를 실행하는 명령어
# CMD ["./mvnw", "clean", "package"]
필요시, Mavne을 사용해 빌드를 실행하는 명령어
VOLUME /tmp
컨테이너 내에 /tmp 디렉터리를 볼륨으로 설정
ARG JAR_FILE=build/libs/*.jar
Gradle로 빌드한 jar 파일의 위치를 변수로 설정
ARG JAR_FILE_PATH=target/*.jar
필요시, Maven으로 빌드한 jar 파일의 위치를 변수로 설정
COPY ${JAR_FILE} app.jar
JAR_FILE 변수에 지정된 파일을 app.jar라는 이름으로 컨테이너에 추가
EXPOSE 8080
컨테이너가 사용할 포트를 설정, 이 경우에는 8080 포트를 사용
ENTRYPOINT ["java","-jar","/app.jar"]
컨테이너가 실행될 때 기본적으로 실행될 명령어를 설정, 이 경우에는 Java 애플리케이션을 실행하는 명령어
FROM bellsoft/liberica-openjdk-alpine:17
# or
# FROM openjdk:8-jdk-alpine
# FROM openjdk:11-jdk-alpine
CMD ["./gradlew", "clean", "build"]
# or Maven
# CMD ["./mvnw", "clean", "package"]
VOLUME /tmp
ARG JAR_FILE_PATH=build/libs/*.jar
# or Maven
# ARG JAR_FILE_PATH=target/*.jar
COPY ${JAR_FILE_PATH} app.jar
EXPOSE 8081
ENTRYPOINT ["java","-jar","/app.jar"]