이전 글에서는 deploy server인 GKE에서 MySQL의 IP를 할당받아서 사용했다.
그러나, 이 방법을 사용하면 test할 때 실 서버의 db를 이용하기 때문에 상당히 위험한 방식이라 생각한다. 이를 보완하기 위해 다른 방법을 이용하고자 한다.
지금 구축되어있는 서버는 크게 3가지이다. 로컬, CI 서버, Deploy 서버.
먼저 로컬과 CI 서버에 추가적으로 docker 위에 mysql을 올리고 임의로 id, pw를 지정한다. 그러면 로컬에서 빌드할 때는 로컬에 있는 docker의 mysql을, CI 서버에서 빌드할 때는 CI 서버의 docker에 있는 mysql을 참조할 것이다. 마지막으로 GKE는 deploy.yml 파일을 작성했을 때 만든, 실제 서비스 DB mysql을 참조하게 될 것이다. 암튼 하고싶은 건 환경에 따라 연결되는 url을 바꾸고 싶은데,,,
이렇게 만들어 보고자 한다. 해결은 profile을 이용해서 한다.
1. local
/local/src/main/resources/application.properties
spring.config.activate.on-profile=common
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#---
spring.config.activate.on-profile=localdb
spring.datasource.url=jdbc:mysql://localhost:3306/devboard?autoReconnect=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnectForPools=true&serverTimezone=UTC
spring.datasource.username=devroot
spring.datasource.password=devpw
#---
spring.config.activate.on-profile=cidb
spring.datasource.url=jdbc:mysql://ci-mysql:3306/devboard?autoReconnect=true&useSSL=false&useUnicode=yes&characterEncoding=UTF-8&autoReconnectForPools=true&serverTimezone=UTC
spring.datasource.username=devroot
spring.datasource.password=devpw
#---
spring.profiles.group.local=localdb,common
#---
spring.profiles.group.ci=cidb,common
#---
spring.profiles.active=ci
제일 위에 있는 것은 common, 그리고 localdb의 cidb의 정보를 profile로 저장한다.
먼저 application.properties를 localhost로 두자. schema 이름을 devboard, username은 devroot, pw는 devpw로 설정했다. 이 설정 그대로 local docker에 mysql을 올리고자 한다.
local/docker-compose.yml
version: "3"
services:
mysql:
image: mysql:5.6
environment:
MYSQL_DATABASE: devboard
MYSQL_ROOT_PASSWORD: rootpw
MYSQL_USER: devroot
MYSQL_PASSWORD: devpw
volumes:
- local-mysqlvol:/var/lib/mysql
ports:
- 3306:3306
container_name: local-mysql
volumes:
local-mysqlvol:
이후 docker-compose up -d를 이용해 이 명령어를 수행하고, mysql로 접속해 보자.
$ docker-compose up -d
$ docker ps
CONTAINER ID IMAGE COMMAND ...
78fd4f7aca99 mysql:5.6 "docker-entrypoint.s…" ...
$ docker exec -it 78fd4f7aca99 /bin/bash
# mysql -u devroot -p
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| devboard |
+--------------------+
자, 로컬에서 mysql이 수행되었고, devboard도 만들어졌고, 접속도 잘 되는 것을 확인했다. spring build를 해 보자.
$ gradlew build -x test
$ gradlew bootRun --args='--spring.profiles.active=local'
잘 실행되고, localhost:8000으로 접속하면 익숙한 그 화면이 보인다. 시험삼아 글을 쓰면 DB에 남겨지는 게 보인다.
/local/Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=build/libs/demo-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar", "--spring.profiles.active=ci"]
dockerfile도 수정하자.
2. CI server
CI server도 local과 동일하다. 기존 ci server의 경우 아래에 있는 docker compose를 사용했다.
ci-server/~/compose/docker-compose.yml
version: "3"
services:
jenkins:
container_name: jenkins-compose
image: jenkins/jenkins:lts
user: root
ports:
- "8081:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- jenkins_data:/var/jenkins_home
networks:
- backend-network
sonarqube:
image: sonarqube:lts
container_name: sonarqube
ports:
- "9000:9000"
volumes:
- sonarqube_conf:/opt/sonarqube/conf
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
mysql:
image: mysql:5.6
container_name: ci-mysql
environment:
MYSQL_DATABASE: bizschema
MYSQL_ROOT_PASSWORD: rootpw
MYSQL_USER: devroot
MYSQL_PASSWORD: devpw
LANG: C.UTF-8
ports:
- "3306:3306"
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
volumes:
- ciserver-mysqlvol:/var/lib/mysql
networks:
- backend-network
volumes:
ciserver-mysqlvol:
jenkins_data:
sonarqube_conf:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
networks:
backend-network:
여기에 mysql과, jenkins와 mysql이 통신할 수 있도록 network 관련해서 추가해 주면 된다. 여기에 있는 mysql service 부분은 local에서의 mysql container 사용문과 동일한 것이고, jenkins와 mysql의 network만 추가했다.
이후 docker-compose up -d를 이용해 위 docker-compose 파일을 실행하고, mysql로 접속해 보자.
$ docker-compose up -d
$ docker ps
CONTAINER ID IMAGE COMMAND ...
b33d39d614a5 mysql:5.6 "docker-entrypoint.s…" ...
42dd8d6f5d59 jenkins/jenkins:lts "/sbin/tini -- /usr/…" ...
d4984f7a0841 sonarqube:lts ...
$ docker exec -it b33d39d614a5 /bin/bash
# mysql -u devroot -p
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| devboard |
+--------------------+
자, ci server에서 mysql이 수행되었고, devboard도 만들어졌고, 접속도 잘 되는 것을 확인했다. 그러면 push해 보자. application.properties에서 active profile을 ci로 설정했고, local에서 실행할 때는 cmd에 값을 주기 때문에 ci 서버에서도 잘 돌아가는 것을 볼 수 있다.
3. Deploy server
deploy server에서는 deploy.yml 파일에 있는 것들이 제일 우선순위 인 것 같다. 별다른 설정 없이도 잘 수행된다.
정리하면,,,
총 5개의 profile을 만들었다.
- common : 공통 설정
- localdb : local db의 url, id, pw
- cidb : ci server db의 url, id, pw
- local : localdb, common을 합친 profile
- ci : cidb, common을 합친 profile
그리고 default는 ci를 적용했다.
local에서 test할 때는 아래 명령어를 이용해 build하고, 실행시킬 수 있다.
gradlew build -x test
gradlew bootRun --args='--spring.profiles.active=local'
java -jar build/libs/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=local
CI server에서는 별다른 설정 없이 실행할 수 있다.(default가 ci profille이기 때문)
deploy server에서도 별다른 설정 없이 실행할 수 있다.(deploy file에서 환경변수를 설정하기 때문)
작동하는 이유는, properties 우선순위가, cmd가 제일 위의 우선순위이고, spring 환경변수는 application properties의 우선순위보다 높기 때문이다.
아무튼 끝!