Intro
이전에 Docker 이미지 다운로드 및 컨테이너 실행 방법에 대해 알아봤었다.
하지만 하나의 PC에서 여러 컨테이너를 실행해야 하는 경우 일일이 다 관리하기도 힘들고, 네트워크 설정도 복잡하다.
이럴 때 docker-compose를 사용하면 yml 파일을 만드는것 만으로 간단하게 컨테이너들을 관리할 수 있다.
이번 시간엔 간단한 예제를 통해 docker-compose 사용 방법을 알아보자.
프로젝트 구조
소스 코드는 Github에 업로드 되어있다.
프로젝트 구조는 아래와 같이 설정했다.
docker-compose-test
├── backend
│ └── dockerfile
├── frontend
│ └── dockerfile
├── postgres
└── docker-compose.yml
- backend: Spring Backend 서버
- frontend: React Frontend 서버
- postgres: PostgreSQL database 폴더 (없어도 무방하다.)
위와 같이 컨테이너 3개를 생성할 것이며, backend와 PostgreSQL 컨테이너는 서로 통신이 가능하게 설정해볼 것이다.
Frontend 컨테이너 만들기
아래의 명령어로 Frontend 서버를 간단하게 만들 수 있다.
명령어를 실행하기 위해 NodeJS가 설치되어 있어야 한다.
npx create-react-app frontend
frontend 폴더가 생성됐다면 React 서버를 실행시켜보자.
cd frontend
npm start
http://localhost:3000으로 접속했을 때 아래와 같은 화면이 뜨면 된다.
실행이 잘 된다면 dockerfile을 생성하자.
FROM node:latest # Node 컨테이너 환경에서 실행한다.
RUN mkdir -p /usr/app/frontend # /usr/app/frontend 디렉터리를 생성한다.
WORKDIR /usr/app/frontend # 생성한 디렉터리를 Default 디렉터리로 설정한다.
COPY package.json . # WORKDIR에 package.json 파일을 복사한다.
RUN npm install # package.json의 패키지들을 설치한다.
COPY . . # 나머지 파일들을 WORKDIR에 복사해온다.
ENTRYPOINT [ "npm", "start" ] # 서버를 실행한다.
EXPOSE 3000 # 3000번 포트를 호스트와 공유한다.
Dockerfile이 잘 설정됐는지 확인하려면 아래의 명령어로 이미지를 만들어보면 된다.
docker build -t frontend . # Build
docker run --rm -itd -p 3000:3000 frontend # Run
Backend 컨테이너 만들기
Spring Boot Project를 생성하고, 아래와 같이 dependencies를 설정하자.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
프로젝트를 빌드하자. PostgreSQL이 없는 지금 상태로는 test가 fail나기 때문에 Build Task에서 제외시켜줘야 한다.
./gradlew build -x test
빌드가 완료됐다면 Dockerfile을 설정하자.
FROM openjdk:17-alpine
RUN mkdir -p /usr/app/backend
WORKDIR /usr/app/backend
# Build가 완료된 파일을 복사한다.
COPY ./build/libs/*.jar .
# Default DB Host를 localhost로 설정한다. 컨테이너 실행 시 변경할 수 있다.
ENV DATABASE_HOST=localhost
ENTRYPOINT [ "java", "-jar", "backend-0.0.1-SNAPSHOT.jar", "--DATABASE_HOST=${DATABASE_HOST}" ]
EXPOSE 8080
docker-compose 설정
이제 docker-compose로 만들어진 컨테이너들을 하나로 묶어서 실행해보자.
PostgreSQL은 이미 만들어진 이미지를 그대로 사용할 것이기 때문에 별도의 dockerfile은 필요없다.
프로젝트 폴더에 docker-compose.yml 파일을 생성한다.
version: "3" # docker-compose 버전
services: # 서비스 목록
frontend: # 서비스 이름
build: # 이미지 Build 옵션
context: ./frontend # Build될 프로젝트가 위치한 경로
dockerfile: dockerfile # 프로젝트 폴더의 dockerfile 이름
container_name: frontend # 컨테이너 이름
ports: # host와 공유할 포트 목록
- 3000:3000 # host:container
depends_on: # 아래의 서비스들이 모두 시작된 이후에 이 서비스를 시작
- backend # backend 서비스가 시작될 때 까지 기다림
backend:
build:
context: ./backend
dockerfile: dockerfile
container_name: backend
ports:
- 80:8080
environment: # 환경변수 설정
- SPRING_DATASOURCE_URL=jdbc:postgresql://database:5432/postgres
- SPRING_DATASOURCE_USERNAME=postgres
- SPRING_DATASOURCE_PASSWORD=postgres
depends_on:
- database # database 서비스가 시작될 때 까지 기다림
database:
image: postgres:latest # postgres 이미지 사용
environment: # 환경변수 설정
- POSTGRES_USERNAME=postgres
- POSTGRES_PASSWORD=postgres
volumes: # host와 container가 공유할 디렉터리 지정
- ./postgres:/var/lib/postgresql/data:rw # host의 postgres 폴더를 컨테이너의 /var/lib/postgresql/data와 공유하고, 읽기/쓰기가 가능하도록 설정
이제 아래의 명령어를 실행하면 docker-compose.yml 파일의 내용을 읽어들여 설정한 대로 컨테이너들을 실행시켜준다.
docker-compose up
실행하면 자동으로 이미지가 빌드되고 컨테이너가 실행된다.
아래와 같이 DB 때문에 실행되지 않았던 backend도 정상적으로 실행되는 것을 볼 수 있다.
backend | 2022-10-04 02:54:44.502 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
backend | 2022-10-04 02:54:44.543 INFO 1 --- [ main] com.example.backend.BackendApplication : Started BackendApplication in 10.311 seconds (JVM running for 12.19)
frontend | Compiled successfully!
frontend |
frontend | You can now view frontend in the browser.
frontend |
frontend | Local: http://localhost:3000
frontend | On Your Network: http://172.18.0.4:3000
frontend |
frontend | Note that the development build is not optimized.
frontend | To create a production build, use npm run build.
frontend |
frontend | webpack compiled successfully
frontend | Compiling...
frontend | Compiled successfully!
frontend | webpack compiled successfully
backend | 2022-10-04 04:06:25.344 INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
backend | 2022-10-04 04:06:25.355 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
backend | 2022-10-04 04:06:25.359 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms
컨테이너 동작 확인
Docker Desktop에서 컨테이너가 잘 뜨는지 확인해보자.
localhost에 접속하여 Backend 서버가 잘 실행됐는지 확인해보자.
http://localhost:3000에 접속하여 Frontend 서버가 잘 실행됐는지 확인해보자.
'Study > DevOps' 카테고리의 다른 글
[Docker] 도커 간단한 명령어 모음 (0) | 2022.09.08 |
---|---|
[Docker] 도커 설치하기 (0) | 2022.09.08 |
[Docker] Docker는 무엇이고, 왜 사용해야 할까? (0) | 2022.09.06 |
[DevOps] Github Actions로 Workflow 자동화하기 (0) | 2022.08.31 |