Thymeleaf 템플릿 에러와 GitHub Actions를 사용한 해결 방법

song yuheon·2023년 9월 26일
0

Trouble Shooting

목록 보기
22/57
post-thumbnail
post-custom-banner

Thymeleaf 템플릿 에러와 GitHub Actions를 사용한 해결 방법


1. 문제 상황



로컬에서는 정상적으로 작동하던 Spring Boot 웹 애플리케이션을 EC2에 배포 후 접속을 시도했을 때 아래와 같은 오류가 발생하였다.

org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/user/login], template might not exist or might not be accessible by any of the configured Template Resolvers

2. 문제 파악


오류 메시지를 보면, Thymeleaf 템플릿 엔진이 /user/login 템플릿을 찾지 못하는 것으로 판단된다.
서버 내에서 해당 파일이 존재하는지 확인하기 위해 EC2 내부를 탐색하였고 /home/ubuntu/resources/templates/user 디렉터리에 login.html 파일이 올바르게 존재하는 것을 확인하였다.


3. 원인 분석


로컬에서는 잘 작동하던 것이 서버에서는 동작하지 않는다면 파일 경로의 차이나 설정의 차이가 있을 가능성이 높다고 판단하였다.
Spring Boot 애플리케이션의 경우 내부적으로 classpath:/templates/ 경로를 템플릿으로 사용하게 설정되어 있다.
하지만 EC2에 배포된 애플리케이션은 JAR 파일 외부의 resources 디렉터리에 템플릿 파일들이 위치하게 되었기 때문에 참조 경로에 문제가 생긴 것으로 판단하였다.


4. 해결



Spring Boot의 property를 사용해 외부의 resources 디렉터리를 올바르게 참조하도록 설정하였다.
아래와 같이 JAR 파일 실행 시에 Thymeleaf와 static resources의 경로를 직접 지정하여 해결하였다.

java -Dspring.thymeleaf.prefix=file:/home/ubuntu/resources/templates/ -jar trelloServer.jar

5. GitHub Actions 워크플로우 업데이트

배포 과정을 자동화하기 위해 사용하던 GitHub Actions 워크플로우에 위의 해결 방법을 적용하였다.
Deploy to EC2 단계에서 JAR 파일 실행 명령어를 수정하여 외부 resources 디렉터리를 올바르게 참조하도록 설정하였다.


name: Java CI with Gradle

on:
  push:
    branches: [ "main","develop" ]
  pull_request:
    branches: [ "main","develop" ]

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        uses: gradle/gradle-build-action@v2.6.0
        with:
          arguments: build

      # 리소스 파일 복사
      - name: Copy resources
        run: cp -r src/main/resources/* build/resources/

      - name: Upload build artifact
        uses: actions/upload-artifact@v2
        with:
          name: trelloServer
          path: build/libs/trelloServer-0.0.1-SNAPSHOT.jar

      # 리소스 아티팩트로 업로드
      - name: Upload resource artifact
        uses: actions/upload-artifact@v2
        with:
          name: resources
          path: build/resources/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download build artifact
        uses: actions/download-artifact@v2
        with:
          name: trelloServer
          path: build/libs/

      # 리소스 파일 다운로드
      - name: Download resource artifact
        uses: actions/download-artifact@v2
        with:
          name: resources
          path: build/resources/

      - name: Deploy to EC2
        run: |
          echo "${{ secrets.EC2_SSH_KEY }}" > private_key.pem
          chmod 600 private_key.pem
          scp -i private_key.pem -o StrictHostKeyChecking=no build/libs/trelloServer-0.0.1-SNAPSHOT.jar ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USERNAME }}/trelloServer.jar
          # EC2에서 resources 디렉터리 생성
          ssh -i private_key.pem -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "mkdir -p /home/${{ secrets.EC2_USERNAME }}/resources/"
          # 리소스 파일 EC2로 복사
          scp -i private_key.pem -o StrictHostKeyChecking=no -r build/resources/static ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USERNAME }}/resources/
          scp -i private_key.pem -o StrictHostKeyChecking=no -r build/resources/templates ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USERNAME }}/resources/
          ssh -i private_key.pem -o StrictHostKeyChecking=no ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }} "pgrep java | xargs kill -9; nohup java -Dspring.resources.static-locations=file:/home/${{ secrets.EC2_USERNAME }}/resources/static/ -Dspring.thymeleaf.prefix=file:/home/${{ secrets.EC2_USERNAME }}/resources/templates/ -jar /home/${{ secrets.EC2_USERNAME }}/trelloServer.jar > app.log 2>&1 &"

          rm -f private_key.pem


profile
backend_Devloper
post-custom-banner

0개의 댓글