Spring Boot

[스프링] 배포용 서버에 데이터베이스 Schema 및 Data 초기 설정하기

728x90

 

 

스프링 부트로 개발을 할 때 보통 개발단계에서는 h2를 많이 사용한다.

또한 JPA를 사용하면 하이버네이트가 자동으로 테이블을 생성해주기 때문에 개발 단계에서는 DDL을 신경 쓸 필요가 없다.

하지만 실제 배포 단계에서는 하이버네이트가 자동으로 생성해주는 sql을 사용하는 것은 위험하다.

따라서 spring.jpa.hibernate.ddl-auto을 none으로 설정하고 schema.sql을 작성해주는 편이 좋다.

 

profile 파일 분리

우선 배포용 서버에서 사용하는 profile 파일이랑 개발 단계에서 사용하는 profile 파일을 분리해야 한다.

application.yml에서는 dev profile을 활성화시켜주고, 배포할 때는 스크립트 파일에서 따로 real profile을 활성화시켜줄 것이다.

 

application.yml

server:
  port: 9090

spring:
  profiles:
    active: dev

 

application-dev.yml

database: hsqldb

spring:
  datasource:
    schema: classpath*:db/${database}/schema.sql
    data: classpath*:db/${database}/data.sql

  jpa:
    show_spl: true
    hibernate:
      ddl-auto: none
      properties:
        hibernate:
          format_sql: true

  h2:
    console:
      enabled: true

logging:
  level:
    org:
      springframework.web: debug

 

application-real.yml

server:
  port: 8080

spring:
  profiles:
    include: real-db

  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect

  session:
    store-type: jdbc

 

 

schema.sql 작성

스키마와 데이터를 초기 설정해주기 위하여 schema.sql 파일을 작성한다.

개발 단계에서의 sql 파일과 배포 단계에서의 sql 파일을 분리하기 위해 폴더를 나눠서 작성해주었다.

개발할 때도 이런 식으로 미리 데이터 값을 넣어놓고 개발을 하면 편리하다.

 

resources/db/hsqldb/schema.sql

DROP TABLE user IF EXISTS;

create table user (
    id bigint generated by default as identity,
    create_date timestamp,
    modified_date timestamp,
    email varchar(255) not null,
    name varchar(255) not null,
    picture varchar(255),
    primary key (id)
);

 

resources/db/hsqldb/data.sql

INSERT INTO user values (1, '2020-01-31 22:10:44.712903', '2020-01-31 22:10:44.712903', 'tkdgusl94@gmail.com', 'jeong', 'picture');

 

resources/db/realdb/schema.sql

CREATE TABLE IF NOT EXISTS test(
    id bigint not null primary key,
    name varchar(255)
) engine=InnoDB;

insert into test values (1, 'name');

 

 

스크립트 파일 작성

배포 스크립트 파일에서 profile을 real로 활성화 시켜준다.

 

deploy.sh

#!/bin/bash

REPOSITORY=/home/ec2-user/project/chacha

echo "> Build 파일 복사"

cp $REPOSITORY/zip/*.jar $REPOSITORY/

echo "> 현재 구동중인 애플리케이션 pid 확인"

CURRENT_PID=$(pgrep -fl chacha | grep jar | awk '{print $1}')

echo "현재 구동중인 어플리케이션 pid: $CURRENT_PID"

if [ -z "$CURRENT_PID" ]; then
    echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다."
else
    echo "> kill -15 $CURRENT_PID"
    kill -15 $CURRENT_PID
    sleep 5
fi

echo "> 새 어플리케이션 배포"

JAR_NAME=$(ls -tr $REPOSITORY/*.jar | tail -n 1)

echo "> JAR Name: $JAR_NAME"

echo "> $JAR_NAME 에 실행권한 추가"

chmod +x $JAR_NAME

echo "> $JAR_NAME 실행"

nohup java -jar \
    -Dspring.config.location=classpath:/application.yml,classpath:/application-real.yml,/home/ec2-user/project/application-oauth.properties,/home/ec2-user/project/application-real-db.properties \
    -Dspring.profiles.active=real \
    $JAR_NAME > $REPOSITORY/nohup.out 2>&1 &

 

 

서버 설정

real profile이 real-db를 포함하고 있기 때문에 서버에서 application-real-db.properties를 수정해줘야 한다.

real-db에는 실제 데이터베이스의 url, 아이디, 비밀번호 등이 담겨 있다. 

real-db 파일이 깃허브에 올라가면 안 되기 때문에 서버에서 따로 관리한다.

프로젝트 폴더 안에 들어 있는 profile 파일들은 properties에서 yml으로 수정해줬는데, 서버에 있는 파일들은 귀찮아서 그냥 내버려 두었다. (어차피 수정할 일도 별로 없어서....)

application-real-db.properties

spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=[데이터베이스 url]
spring.datasource.username=[username]
spring.datasource.password=[password]
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.schema=classpath*:db/realdb/schema.sql
spring.datasource.initialization-mode=always

 

위의 설정 중에 spring.datasource.initialization-mode:always를 반드시 해줘야 한다.

로컬에서는 위의 설정을 안 해줘도 정상적으로 돌아간다. 그 이유는 로컬에서는 h2 데이터베이스를 사용하기 때문이다.

임베디드 데이터베이스를 사용할 때는 위의 설정을 안 해줘도 상관없지만 그 이외의 데이터베이스를 사용하려면 반드시 설정해줘야 한다.

 

 

위와 같이 세팅을 해주게 되면 프로젝트를 자동 빌드, 배포 환경을 세팅해놨기 때문에 코드를 수정한 후 깃허브에 push를 해주게 되면 서버에서 애플리케이션 배포 과정에서 sql문을 실행하게 된다.

서버에서 사용하는 데이터베이스 스키마의 경우는 이런 식으로 따로 관리해주는 것이 용이하다.

728x90