스프링부트 프로젝트 Docker Image 생성하기

dev-jjun·2023년 2월 26일
0

Server

목록 보기
7/33

Docker 빌드를 위한 실행 순서
1. Spring Boot 프로젝트 개발
2. jar 파일 생성(프로젝트 빌드하기)
3. Dockerfile 생성
4. Docker build하여 이미지 생성
5. Docker Run (→ 이를 EC2에 설치한 젠킨스에서 실행시켜 배포 자동화를 구현할 것!)

*️⃣ jar파일이란?

여러 개의 자바 클래스 파일과 클래스들이 이용하는 관련 리소스 등 메타데이터를 하나의 파일로 모아서 자바 플랫폼에 응용 소프트 웨어나 라이브러리를 배포하기 위한 소프트웨어 패키티 타일 포맷. → 즉, 쉽게 말하자면 일종의 자바 프로젝트 압축파일

Dockerfile

Docker, docker compose를 이용한 Spring boot, Mysql 배포 환경 구성해보기

도커 이미지를 실행시킬 때 부가적으로 지정해줘야 속성을 아래 명령어에 포함하여 전달하는데, 각각의 상세한 내용은 아래와 같다.

  • --name : 컨테이너명 지정
  • -p : 포트 매핑
  • --network : 네트워크 설정
  • -e : 환경변수 설정
  • -d : 백그라운드로 컨테이너 실행

VOLUME

Tomcat 로그를 저장할 Volume 설정

Docker #7. Docker Volume 활용하여 Tomcat 로그 저장하기

ENTRYPOINT

"Djava.security.egd=file:/dev/./urandom" : 자바에서 DB 연결 시, JDBC Driver에서 난수를 발생시키는 암호화 작업을 한다.

🐳 **'컨테이너가 시작되면 `java -Djava.security.egd=file:/dev/./urandom -jar /app.jar` shell 명령어를 실행'**

https://velog.io/@skygl/Docker-스프링-부트-사이트-가이드의-Docker-연동하는-명령어-이해하기

docker-compose.yml

mysql을 구동하려고 할 때, $ docker run —name db-mysql -p 3306:3306 —network springboot-mysql-net -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=mydb -e MYSQL_USER=user -e MYSQL_PASSWORD=user -d mysql:5.7 와 같이 길고 복잡한 명령어가 필요하다. 이를 가독성이 좋게 설정값들을 지정해주기 위해, 그리고 여러 개의 컨테이너를 동시에 구동해야 하는 경우에 docker-compose.yml 파일을 사용할 수 있다.

version: '3'

services:

  database:
    container_name: mysql_database
    image: mysql:5.7
    platform: linux/amd64
    restart: unless-stopped
    env_file:
      - .env

    volumes:
      - ./mysql/conf.d:/etc/mysql/conf.d   #mysql 설정파일 위치

    ports:
      - '13306:3306'

    command:
      - 'mysqld'
      - '--character-set-server=utf8mb4'
      - '--collation-server=utf8mb4_unicode_ci'

    networks:
      - test_network

  application:
    container_name: latenight-restaurant
    restart: always
    build:
      context: ./
      dockerfile: Dockerfile
    ports:
      - '8081:8081'
#    image: openjdk:11
    env_file:
      - .env
    environment:
      SPRING_DATASOURCE_URL: ${SPRING_DATABASE_URL}
      SPRING_DATASOURCE_USERNAME: ${SPRING_DATASOURCE_USERNAME}
      SPRING_DATASOURCE_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    depends_on:
      - database
      - redis
    networks:
      - test_network

  redis:
    image: redis:alpine
    command: redis-server --port 6379
    container_name: "redis-docker"
    labels:
      - "name=redis"
      - "mode=standalone"
    volumes:
      - ./redis:/data
    ports:
      - '6379:6379'
    env_file:
      - .env
    networks:
      - test_network

networks:
  test_network:
    driver: bridge

도커 네트워크 생성

도커 환경에서 여러 컨테이너를 동일한 환경에서 연동시키기 위해서 네트워크 설정이 필요하다.

services:
	application:
		networks:
      - test_network
	database:
		networks:
      - test_network
	redis:
		networks:
      - test_network

networks:
  test_network:
		driver: bridge

위와 같이 docker-compose.yml 파일에서 network를 생성하고 각 컨테이너의 네트워크 속성을 지정해주면 된다.

$ docker build {username}/{repo명} .   # DockerHub의 레포명과 동일한 이름의 이미지를 빌드한다.
$ docker push {username}/{repo명}  # 로컬에만 존재하던 이미지가 원격으로 올라가게 된다. (GitHub과 같은 개념)
$ docker-compose up -d  # 백그라운드에서 docker container 구동
$ docker-compose up --build  # 이미지 재빌드와 함께 컨테이너 구동

*만약 포트가 이미 사용중이라면 docker-compose.yml 파일의 {내서버포트}:{Host포트} 중 앞 부분을 바꿔주자!

Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "java": executable file not found in $PATH: unknown

😵‍💫 ISSUE 모음

1. Spring 프로젝트 내부에서 @Value 로 준 환경변수 값들은 어떻게 넘겨주지?

application.yml은 보안상 깃헙에 올라가지 않는다. 그렇다면 이 파일에 담긴 jwt secret key, kakao access token 등의 환경변수는 어떻게 넘겨줘야 할까?

@Value로 application.yml의 환경변수를 가져온 코드가 많기 때문에 ./gradlew build 등의 명령어로 빌드 시 이 값들이 부재하면 반드시 에러가 발생한다.

해결 방안

  1. jenkins 등 빌드 작업이 수행되는 곳에 yml 파일을 직접 작성하여 올려둔다.
  2. IntelliJ의 환경변수 설정 창에서 직접 주입시킨다.
  3. .env 파일 생성하여 안에 환경변수 적어주고 env_file: .env docker-compose에 적어주기

도움이 많이 된 참고 문서 - https://browndwarf.tistory.com/46

2. jpa가 동작하도록 설정해준 값들은 docker 이미지 빌드 시에 어떻게 넘겨줄까?

application.yml 파일을 직접적으로 읽을 수 있게 해줘야 한다.

3. jar 파일을 만들어온 것을 git에서 pull 받을까 아님 ec2 자체는 git과 직접적인 연결이 되지 않고 도커 파일을 가져와서 실행하는 것만 할까?

후자가 정석이긴 함.

참고 자료

[Springboot + MySQL + Docker] 도커를 이용한 멀티 컨테이너 환경 구성 (Docker-compose)

profile
서버 개발자를 꿈꾸며 성장하는 쭌입니다 😽

0개의 댓글