[Spring] docker compose 기본 사용법 기록

klmin·2024년 10월 5일
0

spring boot : 3.3.4
OS : Windows 10 pro

docker-compose 기본 사용법을 기록 해본다.

현재 windows 10 pro를 쓰고있고 인터넷 검색을 통해 docker desktop을 다운받았다.

윈도우에서 docker desktop을 사용하려면 hyper-v, mainboard 설정, wsl 설치 등을 해줘야 docker desktop을 사용할 수 있다.

설치 : https://www.lainyzine.com/ko/article/a-complete-guide-to-how-to-install-docker-desktop-on-windows-10/

https://velog.io/@hanjuli94/%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90%EC%84%9C-%EB%8F%84%EC%BB%A4-%EC%8B%A4%EC%8A%B5%ED%95%98%EA%B8%B0

https://jih0.medium.com/amd-cpu-%EA%B0%80%EC%83%81%ED%99%94-%EB%B0%8F-windows-10-wsl-2-docker-desktop-%EC%84%A4%EC%B9%98-beb2b7a09397

https://docs.docker.com/desktop/install/windows-install/

설치된 docker desktop 이다.

  • docker-compose
    외부 환경에서 spring boot실행시 참조하고있는 여러 서비스(mysql, redis 등)에 연동하려면 직접 설치 하고 설정을 해줘야 하는데 docker-compose를 사용하면 도커 컨테이너에 내가 작성한 서비스가 실행되고 spring boot에서 직접 연결을 할 수 있다.
    명령어를 작성만 하면 docker가 실행되는 환경에서는 명령어 기반으로 일관된 서비스 설정이 가능하다.(설정값, 버전 등)



  • 사용하는법
  1. gradle에
    developmentOnly 'org.springframework.boot:spring-boot-docker-compose'를 선언
    root 경로에 docker-compose.yml, compose.yaml 등 compose 파일을 추가

  2. 프로젝트 생성시
    Develop Tools -> Docker Compose Support 체크
    Compose.yaml 파일 자동 생성됨.

  • 환경별 compose on / off
    나는 application-local.yml과 application-docker.yml 2개로 분리해놓았고 local에는 false, docker에는 true로 해놓았다.
    만약 docker가 설치되어있지 않은 환경에서 compose가 true로 되어있다면 서버 실행시 오류가 발생한다.
# application-local.yml

spring:
  docker:
    compose:
      enabled: false
# application-docker.yml

spring:
  docker:
    compose:
      enabled: true

docker desktop close시 spring boot 실행시 오류 발생

  • compose.yaml
services:
  mysql:
    image: 'mysql:8.0'
    environment:
      MYSQL_USER: product
      MYSQL_PASSWORD: product@1234
      MYSQL_DATABASE: product
      MYSQL_ROOT_PASSWORD: product@5678
      TZ: Asia/Seoul
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    ports:
      - '3307:3306'
    volumes:
      - "./mysql/data:/var/lib/mysql"
      - "./src/main/sql:/docker-entrypoint-initdb.d"
    restart: always

  redis:
    image: 'redis:latest'
    command: ["redis-server", "--requirepass", "klmin6394"]
    volumes:
      - ./redis/data:/data
    ports:
      - '6379:6379'
    restart: always

여러 예제들을 보면 services 위에 version을 명시하는데
2.25 부터는 version을 지정하는 환경이 obsolete 되었다고 하는거 같다.

나도 버전을 명시해서 서버실행을 해보니 이런 문구가 나와서 제거했다.

참고 : https://github.com/docker/compose/issues/11628
https://github.com/mailcow/mailcow-dockerized/issues/5797

  • services : 도커 컨테이너에서 실행될 서비스

    • 로컬에서 실행 시에는 URL이나 호스트를 localhost로 매핑
      • url: jdbc:mysql://localhost:3307/product
      • host: localhost
    • 도커 파일로 애플리케이션이 도커 내부에 배포될 때는 MySQL URL과 Redis 호스트가 도커 서비스 이름과 일치해야 한다.
      • url: jdbc:mysql://mysql:3306/product
      • host: redis
    # application-docker.yml
    
    spring:
    docker:
      compose:
        enabled: true
    
    datasource:
      url: jdbc:mysql://localhost:3307/product
      username: product
      password: product@1234
      driver-class-name: com.mysql.cj.jdbc.Driver
    
    data:
      redis:
        host: localhost
        port: 6379
        password: klmin6394
  • image : 도커에서 가져올 이미지
  • environment: 환경변수 세팅
    • MYSQL_USER: mysql user 명
    • MYSQL_PASSWORD: mysql user password
    • MYSQL_DATABASE: mysql database명
    • MYSQL_ROOT_PASSWORD: mysql root password
    • .env 파일 : .env파일을 만들어 변수로도 가능하다


  • TZ: 시간대
    선언하지 않으면 기본적으로 UTC 시간대가 사용된다고 한다.

    Asia/Seoul 선언시
  • command : 컨테이너 실행시 명령어 작성
    • 나는 현재 redis의 비밀번호와 mysql의 캐릭터셋을 설정했다.
  • ports : 도커 컨테이너에 포트와 로컬에서 실행할 포트를 맵핑한다.
    mysql 로컬 3306이 있으면 3306이 충돌나기때문에 3307로 변경했다.
    3307(로컬):3306(도커컨테이너)
  • volumes : 도커컨테이너 환경에 경로를 로컬 경로와 맵핑한다.
    • docker desktop : bind mounts에서 확인 가능하다.
    • "./mysql/data:/var/lib/mysql" - 컨테이너 경로를 로컬에 마운트한다.
      ./mysql/data(로컬):/var/lib/mysql(컨테이너)
      - docker에서 생성된 파일이 마운트된 경로에 들어오는걸 확인할 수 있다.
      도커 컨테이너의 경우 remove 하면 데이터가 사라지기 때문에 로컬에 백업을 할 수 있고 도커컨테이너를 새로 실행하는데 로컬에 데이터가 있으면 로컬에 있는 파일을 copy한다.


      로컬에 파일이 있다면 init을 안해줘도 해당 데이터를 가져간다.

      로컬과 컨테이너 서로 데이터가 동기화된다. 로컬 데이터가 컨테이너보다 우선시 된다.
      "D:\\docker\\mysql\\data:/var/lib/mysql"
      이렇게 윈도우 절대경로를 줄수도 있다.

  • "./src/main/sql:/docker-entrypoint-initdb.d" - mysql에서 최초 컨테이너 실행시 sql, sh등 파일을 실행할 수 있다.
    ./src/main/sql 이 경로에 있는 sql이 실행된다. 기본적으로 알파벳 순으로 실행되서 넘버링을 해줬다.

    - ddl.sql

    ddl에서 user와 db를 새로 만들게 해놓고 최초 mysql service에
    MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE, MYSQL_ROOT_PASSWORD 중 필요없는걸 제거하고 init.sql에서 생성한걸로 쓰려고 했는데 datasource쪽에서 오류가 발생하거나 서버가 실행되어도 제대로 인식을 하지못해 스크립트가 동작하지 않는다.

    drop 하고 다시 만들거나 create database와 user localhost 생성을 제거해야한다.

    drop 하지 않으면 ddl의 create database나 user 쪽에서 오류가 발생하는지 생성이 되지 않는다.

    나는 drop 한다음에 다시 만들었다.

    기본적으로 MYSQL_USER의 '%' 계정이 생성되어 'localhost'는 따로 만들어 줘야한다.






    이런식으로 4개중에 하나라도 없으면 오류가 발생한다.

    만약 init ddl 이 없다면 서버 실행시 jpa에서 오류가 발생한다.


    이건 기본설정으로 인해 생성되는 계정과 db다.
    host '%' 와 db 인스턴스만 생긴다.


  • restart
    • no(기본값) : 컨테이너 종료시 자동 재시작 하지 않음.
    • on-failure : 컨테이너가 비정상적으로 종료될때만 재시작함.
    • always : 컨테이너가 비정상적으로 종료되거나 서버 재부팅시 자동 재시작.
    • unless-stopped 컨테이너가 수동으로 종료되지 않는 한 자동 재시작함
  • 컨테이너 관련
    • 컨테이너 삭제
      - 인텔리제이 터미널 : docker-compose down -v
      컨테이너는 최초 실행시 설정이 적용되기 때문에 컨테이너를 잘못생성하면 init sql과 volume이 적용되지 않아 명령어로 삭제하거나 docker desktop에서 수동으로 지우고 다시 실행해야 한다.
      만약 컨테이너 생성시 volume 연결을 했었다면 볼륨 디렉토리도 따로 없애줘야 한다.




  • 컨테이너 생성
    - 인텔리제이 터미널 : docker-compose up -d
    comose.yml에 선언된 내용 기반으로 컨테이너를 생성해준다. 스프링부트에서 서버를 실행하면 기본적으로 컴포즈 실행을 해주는데
    스프링부트 실행없이 compose.yml 검증을 위해 테스트하려면 명령어로 삭제와 생성을 반복하는게 효율적인거같다.


profile
웹 개발자

0개의 댓글