전에 했던 SkyLife_Transformation 프로젝트를 로컬에서 테스트를 해보고 AWS EC2 서버에 올렸는데 로컬에서는 되던 게 AWS EC2에서는 안되는 것입니다. 스프링은 오류 없이 서버에서 실행되고 매핑이 잘 되어있는데 404 Not Found Error로 페이지를 못 찾는 에러가 발생했다.
문제점
컨트롤러에 연결되는 jsp파일을 찾지 못하는 오류가 발생합니다. jsp로 만든 프로젝트를 jar로 패키징하면 jsp 파일이 패키징이 안되어 나는 오류인 것 같다.
해결 방법
프로젝트가 빌드될때 war로 빌드되게 변경하고 war패키지 안에 jsp 파일이 잘 들어있는지 확인한다.
1. build.gradle 파일에 war설정
plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.asciidoctor.convert' version '1.5.8'
id 'java'
id 'war' // 추가
}
apply plugin: 'war' // 추가
2. 인텔리제이에서 오른쪽 상단에 있는 gradle 탭에서 bootWar에서 오른쪽 클릭을 하고 애플리케이션 실행한다.
Docker 이미지를 만들기 위해 프로젝트 루트에 Dockerfile을 아래와 같이 생성합니다.
FROM openjdk:11
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
# FROM : Docker Base Image (기반이 되는 이미지, <이미지 이름>:<태그> 형식으로 설정, java8로 코드를 작성했다면 11대신 8로 넣어줘야 합니다.)
# ARG : 컨테이너 내에서 사용할 수 있는 변수를 지정할 수 있다.
# COPY : 위에 선언했던 JAR_FILE 변수를 컨테이너의 app.jar로 복사한다.
# ENTRYPOINT : 컨테이너가 시작되었을 때 스크립트 실행
cd 명령어를 통해 jar 파일이 있는 곳으로 터미널 위치를 옮긴다. (cd build/libs)
상위 메뉴의 Settings에 들어가 왼쪽 하단 메뉴의 Secrets의 Actions에 들어간다.
왼쪽 상단에 있는 New repository secret을 누른다.
이름을 지정하고 복사했던 토큰을 붙여넣어준다.
dockerHub USERNAME과 PASSWORD를 작성한다.
아래와 같이 workflow 파일을 작성합니다.
이것은 Github Container Registry를 이용해서 docker를 빌드하고 서버에 푸시해주는 역할을 합니다.(.github/workflows/main.yml)
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 # 수정해야함
with:
arguments: build
- name: Docker build
run: |
docker login -u ${{ secrets.USERNAME }} -p ${{ secrets.PASSWORD }}
docker build -t spring-cicd .
docker tag spring-cicd lusida0131/spring-cicd:latest
docker push lusida0131/spring-cicd:latest
deploy:
needs: build # build 후에 실행되도록 정의
name: Deploy
runs-on: [ self-hosted, label-go ] # AWS ./configure에서 사용할 label명
steps:
# 3000 -> 80 포트로 수행하도록 지정
- name: Docker run
run: |
docker login -u ${{ secrets.USERNAME }} -p ${{ secrets.PASSWORD }}
docker stop spring-cicd && docker rm spring-cicd && docker rmi lusida0131/spring-cicd:latest
docker run -d -p 8080:8080 --name spring-cicd --restart always lusida0131/spring-cicd:latest
workflow파일 설명
on:
push:
branches: [ main ]
여러 브랜치에서 개발 후 main 브랜치에 push or 병합될 때만 실행되도록 설정한다.
jobs:
build:
runs-on: ubuntu-latest
steps:
Workflow는 다양한 job으로 구성되고 위 yml은 build와 deploy라는 job을 생성한다.
runs-on은 어떤 OS에서 실행될지를 지정한다.
- uses: actions/checkout@v3
build의 step 첫 번째는 현재 상태의 소스코드를 가상의 컨테이너 안으로 checkout 해주는 역할
- name: Set up docker buildx
id: buildx
uses: docker/setup-buildx-action@v1
build의 step 두 번째는 가상의 컨테이너 안에 docker가 돌아갈 수 있는 환경을 설치하는 역할
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
sudo service docker start # Docker 서비스를 시작합니다.
ps -ef|grep docker # 프로세스 확인 명령어
sudo usermod -a -G docker ubuntu # sudo를 사용하지 않고도 Docker 명령을 실행할 수 있도록 docker 그룹에 ec2-user를 추가합니다.
sudo usermod -aG docker $USER
docker ps 명령어를 실행했을때 아래와 같은 오류가 발생하면 docker.sock 권한을 바꾸어준다.
docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
sudo chmod 666 /var/run/docker.sock # sudo를 사용하지 않고도 명령을 실행하게 docer.sock 권한을 바꾸어준다.
AWS에 Github Runner 설치
해당 Repository에 Settings에 들어가서 왼쪽 메뉴 Actions의 Runners를 클릭한다.
Download에 있는 내용, Configure을 EC2서버에 복사해서 한 줄씩 실행시킨다.
하단의 Configure도 위와 동일하게 실행
Enter the name of the runner group to add this runner to : 엔터
Enter the name of runner : 엔터
Configure 진행할 때 Enter any additional labels가 나오면 아래에 있는 label-go를 등록한다.
Enter name of work folder : 엔터
deploy:
needs: build # build 후에 실행되도록 정의
name: Deploy
runs-on: [ self-hosted, label-go ] # AWS ./configure에서 사용할 label명
Configure에 ./run.sh는 nohup으로 실행
nohup ./run.sh &
Runner 세팅이 끝나면 github의 Settings - Actions - Runner 메뉴에서 등록된 것을 확인할 수 있습니다.