들어가며
docker-compose를 이용하여 Spring Boot 애플리케이션과 MySQL 서버를 docker 컨테이너로 띄어보았다.
먼저 다음 두 파일은 같은 디렉토리에 있어야 한다.
- docker-compose
- Dockerfile
같은 위치에 있어야만 docker-compose.yml에서 Dockerfile 인식이 가능하다.
설정파일
다음으로 docker-compose.yml 내용을 살펴보겠다.
version: '3'
services:
database:
container_name: mysql_db
image: mysql/mysql-server:5.7
restart: unless-stopped # 수동으로 종료하지 않는이상 계속 재시작
environment:
MYSQL_DATABASE: users_db # 데이터베이스 이름
MYSQL_ROOT_HOST: '%'
MYSQL_ROOT_PASSWORD: 1234 # 루트 비밀번호
TZ: 'Asia/Seoul' # default time zone
ports:
- "3307:3306" # 필자는 3306포트가 host에서 사용중이라 3307로 대체
volumes:
- mysql-data:/var/lib/mysql # MySQL 데이터 저장 위치 연결 (이미지 삭제 후 다시 생성 하여도 기존에 데이터가 남아있도록 함)
command:
- "mysqld" # 데이터베이스 실행 명령어
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- test_network # 아래에서 정의한 network 적용
application:
container_name: docker-compose-test
restart: on-failure # 실패시에 재시작
build:
context: ./
dockerfile: Dockerfile # Dockerfile을 이용하여 build
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql_db:3306/users_db # 위에서 정의한 컨테이너 이름인 mysql_db로 연결
SPRING_DATASOURCE_USERNAME: "root"
SPRING_DATASOURCE_PASSWORD: "1234"
depends_on:
- database # database가 실행 되고 실행하도록 설정
networks:
- test_network # mysql과 같은 네트워크를 사용
networks:
test_network:
driver: bridge # bridge로 하여 mysql, spring boot app이 서로 통신 가능하도록 설정
volumes:
mysql-data: # "mysql-data"라는 이름의 볼륨 정의, MySQL 데이터 저장용
다음으로 Spring Boot Application 이미지를 만들 수 있도록 Dockerfile을 만들어줘야 한다.
# OpenJDK 17 JDK slim 이미지를 사용하여 Docker 이미지 생성
FROM openjdk:17-jdk-slim
# 이 이미지에 대한 작성자 정보 설정
LABEL authors="jyp"
# 컨테이너의 작업 디렉토리를 /app으로 지정
ENV APP_HOME=/app
WORKDIR $APP_HOME
# 현재 디렉토리의 모든 파일을 컨테이너의 작업 디렉토리에 복사
COPY . ./
# Gradle을 사용하여 애플리케이션 빌드, 테스트는 제외
RUN ./gradlew build -x test --stacktrace
# 빌드된 JAR 파일을 /app 디렉토리에 복사
COPY build/libs/study.management-0.0.1-SNAPSHOT.jar /app/study.management-0.0.1-SNAPSHOT.jar
# 8080번 포트를 외부에 노출
EXPOSE 8080
# JAR 파일을 실행하는 엔트리포인트 설정
ENTRYPOINT ["java", "-jar", "/app/study.management-0.0.1-SNAPSHOT.jar"]
docker compose 명령어
이제 docker-compose 명령어를 이용하여 실행시킬 일만 남았다.
우선 기본적으로 docker compose 명령어는 docker-compose.yml 파일이 있는 위치에서 실행해야 한다. 만약 실행 위치에 docker-compose.yml 파일이 없거나, 이름이 다르다면 -f 옵션을 통해 파일 경로를 주어야 한다.
ex)
docker compose -f ./docker-compose.prod.yml up
1. docker compose build
docker-compose.yml 파일에서 필요한 이미지를 찾아서 빌드한다.
2. docker compose up
docker-compose.yml 파일에서 서비스에 필요한 모든 컨테이너를 생성하고 시작한다. 만약 컨테이너가 빌드되지 않았거나, 혹은 빌드 된 이후 도커파일의 변동으로 다시 빌드되야 하는 경우, 이미지를 빌드한 후 컨테이너를 생성, 시작한다.
만약 이미지를 새로 빌드하고 싶다면 --build 옵션을 추가하면 된다.
docker compose up --build
3. docker compose down
해당 프로젝트의 컨테이너를 중단하고, 제거한다. network나 volume또한 제거된다. 따라서 단순히 잠시 중단한 뒤 나중에 다시 시작하고 싶다면 docker compose stop 혹은 docker compose 가 실행되고 있는 터미널에서 ctrl + C를 통해 중단해야 한다.
4. docker compose stop
명시한 서비스, 혹은 명시한 서비스가 없다면 전체 컨테이너를 중단한다.
down과는 다르게 단순 중단이므로 start 명령어로 다시 시작할 수 있다.
5. docker compose start
생성된 후에 멈췄던 컨테이너를 시작하는 명령어. 쉽게 말해 up을 통해 생성되고, 시작한 이후 docker compose stop 혹은 Ctrl + C를 통해 중단된 서비스를 다시 시작할 수 있다.
6. docker copmose restart
docker compose stop + docker compose start
만약 build 후 restart를 한다면 직전 생성된 이미지를 사용한다. 따라서 돌아가고 있는 컨테이너의 이미지를 바꿔야 한다면,
docker compose build <service>
docker compose restart <service>
위와 같이 빌드 한 후 재시작하면 된다.
7. docker compose ps
현재 동작하는 컨테이너를 보여준다.
8. docker compose logs
해당 서비스의 로그를 보여준다.
9. docker exec <container_id/name> <command>
현재 돌아가는 컨테이너에 명령어를 전달해준다.
만약 conatiner_name을 지정해주지 않았다면, docker ps를 통해 container id를 먼저 얻어야 한다.
이것을 활용해서 현재 컨테이너에 터미널을 접속할 수 있다.
-i는 interactive 옵션으로 터미널을 통한 입력이 가능하게 해주고, -t옵션은 컨테이너의 출력을 터미널로 전달해주므로 두 옵션을 함께 사용해 쉘을 열면 된다.
docker exec -it <container_id/name> /bin/bash
이미지에 따라, /bin/bash를 찾을 수 없다고 뜰 수 있다. 특히 alpine이미지에서 이렇게 뜨는 경우가 많은데, 이 때는 /bin/sh를 대신 써주면 된다.
10. docker exec config
설정 값 등을 보여준다. 환경변수 등이 제대로 들어갔는지 확인하고 싶을 때 사용하면 유용하다.
'DevOps' 카테고리의 다른 글
Nginx에 SSL 적용 및 Reverse Proxy 설정 (0) | 2024.11.21 |
---|---|
minikube service 외부 접속 안되는 이유 (0) | 2024.08.27 |
Jenkins CI/CD with github (0) | 2024.06.07 |
Docker에 nginx 컨테이너 올리기 (0) | 2024.03.28 |