깃허브에서 코드를 받아올 수 있게 EC2에 깃을 설치한다.
EC2로 접속해서 다음과 같이 명령어를 입력한다.
#리포지토리 확인
$ yum repolist
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
repo id repo name status
!amzn2-core/2/x86_64 Amazon Linux 2 core repository 29,823
amzn2extra-docker/2/x86_64 Amazon Extras repo for docker 79
amzn2extra-kernel-5.10/2/x86_64 Amazon Extras repo for kernel-5.10 245
repolist: 30,147
#git을 제공하는 패키지 검색
$ yum provides git |tail -5
git-2.39.1-1.amzn2.0.1.x86_64 : Fast Version Control System
Repo : amzn2-core
#현재 시스템에 git이 설치되어 있는지 확인
$ rpm -qa|grep git
lm_sensors-libs-3.4.0-8.20160601gitf9185e5.amzn2.x86_64
crontabs-1.11-6.20121102git.amzn2.noarch
net-tools-2.0-0.22.20131004git.amzn2.0.2.x86_64
screen-4.1.0-0.27.20120314git3c2946.amzn2.x86_64
python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.1.x86_64
#git 설치
$ sudo yum install git
...
Installed:
git.x86_64 0:2.39.1-1.amzn2.0.1
Dependency Installed:
git-core.x86_64 0:2.39.1-1.amzn2.0.1 git-core-doc.noarch 0:2.39.1-1.amzn2.0.1
perl-Error.noarch 1:0.17020-2.amzn2 perl-Git.noarch 0:2.39.1-1.amzn2.0.1
perl-TermReadKey.x86_64 0:2.30-20.amzn2.0.2
Complete!
#설치 후 git 버전확인
$ git --version
git version 2.39.1
git이 설치되면 git clone으로 프로젝트를 저장한다.
#프로젝트를 저장할 디렉터리 생성
$ mkdir -p ~/app/step1
$ ls -al ~/app/step1/
total 0
drwxrwxr-x 2 ec2-user ec2-user 6 Feb 7 15:44 .
drwxrwxr-x 3 ec2-user ec2-user 19 Feb 7 15:44 ..
$ cd ~/app/step1/
$ pwd
/home/ec2-user/app/step1
#github 웹페이지에서 https 주소를 복사해서 git clone을 진행
$ git clone https://github.com/KangJuHui/springboot2-webservice.git
Cloning into 'springboot2-webservice'...
remote: Enumerating objects: 912, done.
remote: Counting objects: 100% (912/912), done.
remote: Compressing objects: 100% (472/472), done.
remote: Total 912 (delta 291), reused 784 (delta 164), pack-reused 0
Receiving objects: 100% (912/912), 360.20 KiB | 2.08 MiB/s, done.
Resolving deltas: 100% (291/291), done.
#프로젝트들이 잘 복사되었는지 확인
$ ls
springboot2-webservice
$ cd springboot2-webservice/
$ ll
total 20
drwxrwxr-x 7 ec2-user ec2-user 84 Feb 7 15:46 build
-rw-rw-r-- 1 ec2-user ec2-user 1474 Feb 7 15:46 build.gradle
drwxrwxr-x 3 ec2-user ec2-user 21 Feb 7 15:46 gradle
-rwxrwxr-x 1 ec2-user ec2-user 5774 Feb 7 15:46 gradlew
-rw-rw-r-- 1 ec2-user ec2-user 2674 Feb 7 15:46 gradlew.bat
drwxrwxr-x 4 ec2-user ec2-user 36 Feb 7 15:46 out
-rw-rw-r-- 1 ec2-user ec2-user 45 Feb 7 15:46 settings.gradle
drwxrwxr-x 4 ec2-user ec2-user 30 Feb 7 15:46 src
#코드들이 잘 수행되는지 테스트로 검증
$ ./gradlew test
Downloading https://services.gradle.org/distributions/gradle-7.2-bin.zip
..........10%...........20%...........30%...........40%...........50%...........60%...........70%...........80%...........90%...........100%
Welcome to Gradle 7.2!
Here are the highlights of this release:
- Toolchain support for Scala
- More cache hits when Java source files have platform-specific line endings
- More resilient remote HTTP build cache behavior
For more details see https://docs.gradle.org/7.2/release-notes.html
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :compileJava
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
> Task :test
2023-02-07 15:50:10.958 INFO 27379 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2023-02-07 15:50:10.960 INFO 27379 --- [ionShutdownHook] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down'
Hibernate: drop table if exists posts
2023-02-07 15:50:10.966 WARN 27379 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 90121, SQLState: 90121
2023-02-07 15:50:10.966 ERROR 27379 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper : Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200]
2023-02-07 15:50:10.967 WARN 27379 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 90121, SQLState: 90121
2023-02-07 15:50:10.973 ERROR 27379 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper : Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200]
2023-02-07 15:50:10.974 WARN 27379 --- [ionShutdownHook] o.s.b.f.support.DisposableBeanAdapter : Invocation of destroy method failed on bean with name 'entityManagerFactory': org.hibernate.exception.JDBCConnectionException: Unable to release JDBC Connection used for DDL execution
2023-02-07 15:50:10.975 INFO 27379 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2023-02-07 15:50:10.991 INFO 27379 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
BUILD SUCCESSFUL in 2m 47s
5 actionable tasks: 5 executed
배포는 작성한 코드를 실제 서버에 반영하는 것이다.
배포 절차를 스크립트로 작성해서 진행할 것이다.
스크립트는 아래 과정을 통해 배포를 진행한다.
$ cat /home/ec2-user/app/step1/deploy.sh
#!/bin/bash
REPOSITORY=/home/ec2-user/app/step1
PROJECT_NAME=springboot2-webservice
cd $REPOSITORY/$PROJECT_NAME/
echo "> Git Pull"
git pull
echo "> 프로젝트 Build 시작"
./gradlew build
echo "> step1 디렉토리로 이동"
cd $REPOSITORY
echo "> Build 파일 복사"
cp $REPOSITORY/$PROJECT_NAME/build/libs/*.jar $REPOSITORY/
echo "> 현재 구동중인 애플리케이션 pid 확인"
CURRENT_PID=$(pgrep -f ${PROJECT_NAME}\*.jar)
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/ |grep jar |tail -n 1)
echo "> JAR Name: $JAR_NAME"
nohup java -jar $REPOSITORY/$JAR_NAME 2>&1 &
스크립트를 실행하고 로그를 확인해보자.
#스크립트에 실행 권한 추가
$ chmod +x ./deploy.sh
$ ll ~/app/step1/deploy.sh
-rwxrwxr-x 1 ec2-user ec2-user 1462 Feb 8 00:26 /home/ec2-user/app/step1/deploy.sh
#스크립트 실행
$ bash deploy.sh
> Git Pull
Already up to date.
> 프로젝트 Build 시작
BUILD SUCCESSFUL in 3s
8 actionable tasks: 8 up-to-date
> step1 디렉토리로 이동
> Build 파일 복사
> 현재 구동중인 애플리케이션 pid 확인
현재 구종 중인 애플리케이션 pid:
> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않았습니다.
> 새 애플리케이션 배포
> JAR Name: springboot2-webservice-1.0-SNAPSHOT.jar
$ nohup: appending output to ‘nohup.out’
#로그 확인
$ cat /home/ec2-user/app/step1/nohup.out
... 생략 ...
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-02-07 17:25:43.599 ERROR 25935 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Method springSecurityFilterChain in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration required a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' in your configuration.
nohup.out 파일의 내용을 보면 어플리케이션 실행이 실패하였고, ClientRegistrationRepository를 찾을 수 없다는 에러가 발생하였다.
“ClientRegistrationRepository를 찾을 수 없다는 에러”의 원인은 application-oauth.properties가 없기 때문이다. ClientRegistrationRepository를 생성하려면 clientId와 clientSecuret가 필요하다.
로컬 PC에서 실행할 때는 해당 설정들이 application-oauth.properties파일에 있었다.
하지만 .gitignore로 git에서 제외 대상이라 깃허브에는 올라가지 않았기 때문에 서버에 배포되지 않은 것이다.
애플리케이션을 실행하기 위해 공개된 저장소에 ClientId와 ClientSecret을 올릴 수는 없으니 서버에서 이 설정을 직접 생성해주도록 하자.
#application-oauth 설정 파일 생성
$ ls /home/ec2-user/app/application-oauth.properties
/home/ec2-user/app/application-oauth.properties
#애플리케이션이 application-oauth 파일을 참조하도록 실행명령 수정
$ vi ~/app/step1/deploy.sh
...
nohup java -jar \
-Dspring.config.location=classpath:/application.properties,/home/ec2-user/app/application-oauth.properties,/home/ec2-user/app/application-real-db.properties,classpath:/application-real.properties \
#배포 스크립트 실행
$ bash ~/app/step1/deploy.sh
> Git Pull
Already up to date.
> 프로젝트 Build 시작
BUILD SUCCESSFUL in 2s
8 actionable tasks: 8 up-to-date
> step1 디렉토리로 이동
> Build 파일 복사
> 현재 구동중인 애플리케이션 pid 확인
현재 구종 중인 애플리케이션 pid:
> 현재 구동 중인 애플리케이션이 없으므로 종료하지 않았습니다.
> 새 애플리케이션 배포
> JAR Name: springboot2-webservice-1.0-SNAPSHOT.jar
$ nohup: appending output to ‘nohup.out’
#로그 확인
$ cat nohup.out
...
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.3)
2023-02-07 17:57:42.859 INFO 11932 --- [ main] com.spring.book.Application : Starting Application using Java 17.0.6 on freelec-springboot2-webservice with PID 11932 (/home/ec2-user/app/step1/springboot2-webservice-1.0-SNAPSHOT.jar started by ec2-user in /home/ec2-user/app/step1)
2023-02-07 17:57:42.866 INFO 11932 --- [ main] com.spring.book.Application : The following profiles are active: oauth
2023-02-07 17:57:45.368 INFO 11932 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2023-02-07 17:57:45.505 INFO 11932 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 119 ms. Found 2 JPA repository interfaces.
2023-02-07 17:57:47.250 INFO 11932 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-02-07 17:57:47.275 INFO 11932 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-02-07 17:57:47.276 INFO 11932 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.56]
2023-02-07 17:57:47.417 INFO 11932 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-02-07 17:57:47.417 INFO 11932 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4365 ms
2023-02-07 17:57:47.521 INFO 11932 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2023-02-07 17:57:47.875 INFO 11932 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2023-02-07 17:57:47.905 INFO 11932 --- [ main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem://localhost/~/testdb'
2023-02-07 17:57:48.485 INFO 11932 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
로그 확인 결과 애플리케이션이 정상적으로 실행된 것을 확인할 수 있다.
다음 포스팅에서는 RDS 접근 설정을 추가하여 애플리케이션이 DB에 데이터를 영구적으로 저장하도록 설정해보자.