Search

기본 템플릿

Publish Date
2025/03/08
Category
Tags
Status
Not started
1 more property
주제
배경 및 목표에 대해 1문장으로 기재
도커 개발자 커뮤니티 데이 코리아 1회
실습에 사용된 코드:

Dockerfile

Dockerfile은 컨테이너 이미지를 빌드하는 명세서로, 컨테이너화된 애플리케이션을 정의하는 설정파일입니다. 컨테이너 이미지를 만들기 위해 다양한 명령어(Instructions)를 사용합니다.

 대표적인 명령어(Instructions)

명령어
설명
FROM
베이스 이미지 지정
WORKDIR
작업 디렉터리 설정
COPY
로컬 파일을 컨테이너로 복사
RUN
컨테이너 빌드 중 실행할 명령어 지정
ENV
환경 변수 설정
ENTRYPOINT
컨테이너 실행 시 시작할 명령 설정
Dockerfile을 사용하면 컨테이너 이미지를 일관성있게 관리하고, 자동화된 배포가 가능합니다. 하지만 작성 및 유지보수가 어렵다는 문제가 있기 때문에 이를 해결하기 위한 기술이 docker init 입니다.

Dockerfile을 자동으로 생성해주는 Docker init

 docker init 이란?

애플리케이션 코드를 분석하여 Best Practice 기반의 Dockerfile을 자동 생성하는 명령어
docker init 실행 후 생성된 Dockerfile을 커스터마이징 가능
단점: 멀티 프로젝트 인식 불가

 실습: docker init 사용하기

이번 실습에는 연사자의 Github에서 제공하는 샘플 코드를 사용합니다.
# monolith 프로젝트 디렉토리로 이동 cd ~/container-orchestration-sample-main/monolith # docker init 실행 docker init
Bash
복사
docker init을 실행하면 .NET을 감지하고 자동으로 추천해줍니다. 메인 프로젝트(eShopLite.Store)를 선택 후, 설정 값을 지정하면 자동으로 Dockerfile이 생성됩니다.
설정 항목
.NET 버전
9.0
Port
8080
자동 생성된 Dockerfile을 커스터마이징 해봅시다. 이번 실습에서 사용자 권한 설정과, 빈 데이터 베이스 파일 생성 부분을 추가해줍니다.
FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0-alpine AS build COPY . /source WORKDIR /source/src/eShopLite.Store ARG TARGETARCH RUN --mount=type=cache,id=nuget,target=/root/.nuget/packages \ dotnet publish -a ${TARGETARCH/amd64/x64} --use-current-runtime --self-contained false -o /app FROM mcr.microsoft.com/dotnet/aspnet:9.0-alpine AS final WORKDIR /app COPY --from=build /app . RUN chown $APP_UID /app # 사용자 권한 설정 USER $APP_UID RUN touch /app/Database.db # 빈 데이터베이스 파일 생성 ENTRYPOINT ["dotnet", "eShopLite.Store.dll"]
Bash
복사
컨테이너 이미지를 빌드해줍니다.
docker build -t eshoplite-store:latest . docker images
Bash
복사
컨테이너 이미지는 기본적으로 실행하는 컴퓨터의 아키텍처를 따르기 때문에, 배포 환경과 다를 경우 명시적으로 아키텍처를 설정해줘야 합니다. linux/amd64로 지정해보겠습니다.
docker build --platform=linux/amd64 --build-arg TARGET=amd64 -t eshoplite-stre:latest .
Bash
복사
컨테이너를 실행합니다.
docker run -d -p 8080:8080 --name store eshoplite-store:latest
Bash
복사
 Hello, world! 애플리케이션이 잘 동작합니다.

docker init의 장점과 한계

장점:
Dockerfile을 자동 생성하여 초보자도 쉽게 활용 가능
Best Practice 기반으로 최적화된 Dockerfile 제공
코드를 분석하여 적절한 환경 추천
단점:
멀티 프로젝트 인식 불가 (프로젝트가 복잡할 경우 수동 조정 필요)
자동 생성된 Dockerfile이 최적이 아닐 수도 있음 (커스터마이징 필요)

Dockerfile 없이 컨테이너 이미지 빌드하기

이번에는 Dockerfile을 직접 작성하지 않고도 컨테이너 이미지를 빌드하는 방법에 대해 소개합니다. 여러가지 방법들이 있지만 Java 애플리케이션의 Jib 패키지와 .NET의 dotnet publish를 이용하여 이미지를 빌드하는 방법에 대해 다룹니다.
실습 애플리케이션을 실행하기 위해서 3개 프로젝트를 실행해야 합니다.
프로젝트 명
빌드 방식
eshoplite-product
Dockerfile 직접 사용
eshoplite-weatherApi
Jib을 활용한 컨테이너 이미지 빌드
eshoplite-webApp
.NET dotnet pulbish 사용하여 이미지 빌드
프로젝트 경로: ~/container-orchestration-sample/msa

 Dockerfile 빌드 (eshoplite-product)

dockerfile을 사용하여 컨테이너를 실행합니다.
docker build -f Dockerfile.product --platform=linux/amd64 --build-arg TARGETARCH=amd64 -t eshoplite-product:latest .
Bash
복사
docker run -d -p 5051:8080 --name product eshoplite-product:latest
Bash
복사

Java 애플리케이션 - Jib 패키지 활용 (eshoplite-weatherApi)

 Jib란?

Google에서 제공하는 Maven/Gradle 플러그인으로 Dockerfile 없이 컨테이너 이미지를 직접 빌드할 수 있는 도구
제한: RUN 지시자를 사용할 수 없어, 컨테이너 내부에서 추가적인 명령 실행이 제한됨
./gradlew jib 또는 ./mvnw compile jib:build 실행

 실습: Jib을 활용한 컨테이너 이미지 빌드

Spring Boot 애플리케이션을 Jib을 활용해 Dockerfile 없이 컨테이너 이미지로 빌드하고 실행하는 방법을 실습해봅니다.
프로젝트 경로: ~/container-orchestration-sample/msa
Jib을 사용하기 위해 pom.xml에 Maven 플러그인 추가
아래 pom.xml 파일을 보면 jib-maven-plugin을 추가하여 빌드하도록 설정
pom.xml (Jib플러그인 추가)
pom.xml에서 jib-maven-plugin을 사용해 컨테이너 이미지를 빌드하도록 설정합니다.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.devkimchi.eshop.lite</groupId> <artifactId>weatherapi</artifactId> <version>0.0.1-SNAPSHOT</version> <name>weatherapi</name> <description>Demo project for Spring Boot</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.google.cloud.tools</groupId> <artifactId>jib-maven-plugin</artifactId> <!-- Jib 플러그인 --> <version>3.4.4</version> <configuration> <from> <image>mcr.microsoft.com/openjdk/jdk:17-ubuntu</image> <!-- JDK 17 기반 이미지 --> <!-- <image>eclipse-temurin:17-jre-alpine</image> --> </from> <to> <image>eshoplite-weather</image> <!-- 컨테이너 이미지 이름 --> <tags> <tag>latest</tag> </tags> </to> <container> <jvmFlags> <jvmFlag>-Djava.security.egd=file:/dev/./urandom</jvmFlag> <jvmFlag>-Xms512m</jvmFlag> </jvmFlags> <mainClass>com.devkimchi.eshop.lite.weatherapi.SpringMavenApplication</mainClass> <ports> <port>5050</port> </ports> </container> <extraDirectories> <paths> <path> <from>../../../agents</from> <into>/agents</into> </path> </paths> </extraDirectories> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
XML
복사
항목
설명
from.image
JDK 17이 포함된 mcr.microsoft.com/openjdk/jdk:17-ubuntu 이미지를 기반으로 컨테이너를 빌드
to.image
빌드된 컨테이너 이미지를 eshoplite-weather 라는 이름으로 생성
mainClass
실행할 메인 클래스 지정
ports
컨테이너가 사용하는 포트(5050)지정
Jib을 이용해 컨테이너 이비지를 빌드 및 실행하기 위해 아래 명령을 실행합니다.
./mvnw compile jib:build docker run -d -p 5050:5050 --name weather eshoplite-weather:latest
YAML
복사
(선택사항) 연사자께서는 컨테이너 이미지를 Docker Hub에 푸시하는 형태로 진행을 하였습니다.
# 도커 허브 계정으로 수정 후 실행 REGISTRY=<YOUR_DOCKERHUB_USERNAME> ./src/eShopLite.WeatherApi/mvnw clean package \ -f ./src/eShopLite.WeatherApi/pom.xml \ -Dimage="$REGISTRY/eshoplite-weather:latest"
Bash
복사
docker pull "$REGISTRY/eshoplite-weather:latest"
Bash
복사
docker tag "$REGISTRY/eshoplite-weather:latest" eshoplite-weather:latest
Bash
복사
docker run -d -p 5050:5050 --name weather "eshoplite-weather:latest"
Bash
복사

.NET - dotnet publish (eshoplite-webstore)

컨테이너 오케스트레이션이 필요하다

컨테이너는 기본적으로 독립적인 환경에서 실행되기 때문에, 서로 직접 통신할 수 없습니다. 이를 해결하기 위해서 컨테이너 오케스트레이션을 통해 네트워크를 구성해야 합니다.

Docker 네트워크 사용

Docker 네트워크를 활용하면 동일 네트워크에 속한 컨테이너들이 서로 통신할 수 있도록 설정할 수있습니다. 즉, 각 컨테이너에 개별 IP 주소를 부여하지 않고도, 컨테이너 이름 또는 별칭을 통해 다른 컨테이너에 접근 가능합니다.

 실습:

먼저 컨테이너 간 통신을 위한 네트워크(eshoplite)를 생성합니다.
docker network create eshoplite docker inspect eshoplite # 네트워크 설정 확인
Bash
복사
네트워크가 생성된 후, 컨테이너 실행 시 해당 네트워크를 지정하여 컨테이너들이 서로 통신할 수 있도록 설정합니다.
docker run -d -p 5001:8080 --network eshoplite --network-alias webstore --name websotre eshoplite-webstore:latest docker run -d -p 5050:5050 --network eshoplite --network-alias weather --name weather eshoplite-weather:latest docker run -d -p 5051:8080 --network eshoplite --network-alias product --name product eshoplite-product:latest
Bash
복사
항목
설명
--network
네트워크 지정
--network-alias <별칭>
컨테이너 네트워크 내에서 사용할 별칭 부여
컨테이너들이 네트워크에 정상적으로 연결되어 있으며, 이제 컨테이너 간 통신이 가능해집니다.
네트워크에 지정된 컨테이너가 없는 상태
지정된 컨테이너가 설정된 상태

Docker Compose 사용

Docker Compose는 여러 개의 컨테이너를 한 번에 실행하고 관리할 수 있는 도구입니다. docker run 명령을 여러 번 입력하는 대신, YAML파일을 이용해 컨테이너 설정을 자동화할 수 있습니다.

 실습:

아래와 같이 compose.yml 파일을 작성하여, 여러 컨테이너를 동시에 실행할 수 있도록 설정합니다.
name: eShopLite services: product: container_name: product image: eshoplite-product:latest ports: - 5051:8080 weather: container_name: weather image: eshoplite-weather:latest ports: - 5050:5050 webstore: container_name: webstore image: eshoplite-webstore:latest ports: - 5001:8080 depends_on: - product - weather
Bash
복사
항목
설명
services
실행할 컨테이너 목록
container_name
컨테이너 이름 지정
image
실행할 Docker 이미지
ports
컨테이너와 호스트 간 포트 매핑
depends_on
다른 컨테이너가 먼저 실행되도록 설정
networks
네트워크에 컨테이너를 연결
networks.eshoplite
eshoplite 네트워크를 생성하고 컨테이너들이 이 네트워크를 사용하도록 설정
아래 명령어를 실행하면 모든 컨테이너가 자동으로 네트워크에 연결된 상태에서 실행됩니다.
docker-compose up -d
Bash
복사
모든 컨테이너가 네트워크에 정상적으로 연결된 것을 확인할 수 있습니다.
방식
특징
사용 용도
Docker 네트워크
개별 컨테이너 실행 시 --network 옵션을 사용하여 연결
컨테이너 수가 적고, 개별적으로 실행할 경우 적합
Docker Compose
여러 컨테이너를 docker-compose.yml 파일로 관리
컨테이너 수가 많고, 여러 서비스를 한 번에 실행해야 할 경우 적합
컨테이너 오케스트레이션을 활용하면, 네트워크 설정을 통해 컨테이너 간 통신을 쉽게 설정
Docker Compose를 활용하면 여러 개의 컨테이너를 한 번에 실행할 수 있어 더욱 효율적

마무리 및 느낀점

이번 커뮤니티를 통해 Dockerfile 작성, 컨테이너 빌드, 그리고 컨테이너 간 통신 과정에 대해 전반적인 흐름을 파악할 수 있었습니다. 특히, Dockerfile 없이도 컨테이너를 빌드할 수 있는 방법과 컨테이너 간 네트워크 설정에 대한 개념을 정리할 수 있어 유익한 시간이었습니다.

 배운 점 요약

Dockerfile 작성의 대안docker init을 활용하면 초기에 Dockerfile 작성 부담을 줄일 수 있음
Dockerfile 없이도 컨테이너 빌드 가능 → Jib 플러그인(Java) 및 dotnet publish(.NET)를 활용하여 Dockerfile 없이도 컨테이너 이미지를 생성할 수 있음
컨테이너 간 통신을 위한 설정 필요 → Docker 네트워크 또는 Docker Compose를 활용하여 컨테이너 간 원활한 통신 가능

 커뮤니티를 통해 알게 된 점: docker init

이번 커뮤니티를 통해 docker init 명령어를 사용하면 보다 쉽게 Dockerfile을 작성할 수 있다는 점을 알게되었습니다. 처음 Dockerfile 작성할 때 시행착오를 겪었던 기억이 떠오르네요, 만약 이 기능을 진작알았다면 더 수월하게 작성할 수 있었을텐데 말이죠. 이제라도 알게되어 다행이고, 앞으로 적극적으로 활용하면 좋을듯 합니다. (이래서 커뮤니티를 다니면서 배우나 봅니다.)

 녹화 제공

보통 커뮤니티에서 녹화를 제공하지 않거나, 제공하더라도 업로드까지 시간이 오래 걸리는 경우가 많습니다. 하지만 일주일도 안되어 바로 업로드가 되어 복습할 수 있었던 점이 좋았습니다. ⇒ 놓쳤던 부분을 다시 확인할 수 있어서 학습 효과가 더욱 극대화!

 추가 학습 필요성

Dockerfile을 자동 생성하고, 컨테이너 이미지를 빌드하는 과정을 경험했지만, Dockerfile이 실제로 어떻게 이미지를 빌드하는지 동작 원리에 대한 추가 학습이 필요하다고 느꼈습니다.
Dockerfile의 빌드 단계 및 이미지 최적화 방법
Docker의 레이어 캐싱과 빌드 성능 최적화 방법
멀티 스테이지 빌드 활용법
Search
Main PageCategoryTagskkogggokkAbout MeContact