스프링 부트로 개발을 할 때 보통 개발단계에서는 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문을 실행하게 된다.
서버에서 사용하는 데이터베이스 스키마의 경우는 이런 식으로 따로 관리해주는 것이 용이하다.
'Spring Boot' 카테고리의 다른 글
[스프링] AWS S3에 이미지 업로드 하기 (0) | 2020.02.06 |
---|---|
[스프링] 프록시 기반 AOP(Aspect Oriented Programming) 정리 (0) | 2020.01.25 |
[스프링] IoC(Inversion of Control), DI(Dependency Injection), Spring Container, Bean 정리 (0) | 2020.01.25 |
[스프링] 오픈 api 사용해서 데이터 가져오기 (네이버 영화 검색 api) (7) | 2020.01.14 |
[스프링] Spring 웹 계층 (2) | 2020.01.03 |