- Published on
AWS EC2 환경에서 Docker와 Nginx 설정시 겪은 문제점 개인적인 정리
- Authors

- Name
- 김민석
Introduction
- EC2 인스턴스에서 Docker를 설치 과정 문제
- PAT 문제
- 접근 권한 문제
- 문제점)
- 로컬 환경에서는 정상적으로 작동하고, 배포 환경에서는 문제 발생
- 배포 상황에서의 문제점)
- 도메인 설정해보기.
EC2 인스턴스에서 Docker를 설치 과정 문제

- 오류는 현재 사용 중인 Amazon Linux 2023 버전에서는
amazon-linux-extras명령이 지원되지 않기 때문에 발생하는 것이였다 . amazon-linux-extras는 Amazon Linux 2에서 사용되던 명령어로, Amazon Linux 2023 버전에서는 패키지 관리 방식이 변경해야 했다.
PAT 문제

오류 메시지는 GitHub가 2021년 8월 13일부터 패스워드를 이용한 인증을 지원하지 않기 때문에 발생한 것이다.
- 대신
GitHub Personal Access Token (PAT)을 사용해야 했다.
해결 방법
- GitHub에 Settings로 이동하여 →
Generate new token으로 이동한다. - 이름, 유효 기간, 권한을 설정하고 Generate 버튼을 클릭하여
토큰을 생성하는 것이다. - 생성된 토큰을 복사하여 EC2 인스턴스에서 GitHub에 접속할 때
GitHub 사용자 이름, 비밀번호 대신생성한 토큰을 입력하여 해결 하였다.
Personal Access Token (PAT) 란?
- GitHub에서 사용자 계정의 비밀번호 대신 사용할 수 있는
일종의 인증 토큰이다. - GitHub는 보안 강화를 위해
비밀번호 인증을 폐지하고, 대신Personal Access Token을 사용하도록 하고 있다고 한다 .
접근 권한 문제

오류 메시지에서 문제는 springboot-app 이미지를 찾을 수 없거나 접근 권한이 없다는 것이다.
springboot-app 이미지 확인
현재 docker-compose.yml 파일에서 application 서비스의 image로 springboot-app을 참조하고 있다.
로컬에서 직접 빌드한 Docker 이미지(Dockerfile을 사용하여 빌드)- Docker Hub 또는 기타 레지스트리에 존재하는 이미지
로컬에서 직접 빌드해야 하는 이미지이기에, docker-compose.yml에서 build 지시자를 추가.
application:
build:
context: .
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- 이렇게 하면
docker-compose가Dockerfile을 사용하여springboot-app이미지를 빌드한다. context: .는 현재 디렉토리에서Dockerfile을 찾는 것으로 해결 했다.
문제점)

이 오류는 현재 Dockerfile에서 COPY build/libs/resume-feedback-0.0.1-SNAPSHOT.jar /app/app.jar 명령어가 실패하고 있기 때문이다.
- 이 오류는 해당 파일이 존재하지 않아서 발생한 것이였다.
해결 방법
- 먼저, EC2 인스턴스에서 프로젝트의
build/libs디렉토리에 JAR 파일이 있는지 확인한다.
- 해당 파일이 없다면, JAR 파일을 빌드해야 한다.
- 만약
build/libs/resume-feedback-0.0.1-SNAPSHOT.jar파일이 없다면, 다음 명령어를 사용하여 프로젝트를 빌드한다.
./gradlew build
이 명령은 프로젝트를 빌드하고 build/libs/ 디렉토리에 JAR 파일을 생성한다.
하지만, 또 다시 문제가 발생했다.

지금 ./gradlew build 명령어를 실행하려고 했으나, Permission denied 오류가 발생했다.
이는 gradlew 파일에 실행 권한이 없기 때문에 발생하는 문제이다.
다음 명령어를 사용하여 gradlew 파일에 실행 권한을 추가하였다.
chmod +x ./gradlew
또한, Dockerfile의 JAR 파일 경로 수정
build.gradle에서 생성된 JAR 파일의 이름이 다를 수 있다.build/libs디렉토리에서 실제 파일 이름을 확인한 다음, Dockerfile의COPY경로를 수정해야 했다.build/libs/디렉토리에 있는 실제 JAR 파일 이름이 다르다면 Dockerfile에서 이를 반영한다.
COPY build/libs/your-actual-jar-name.jar /app/app.jar
Nginx 설정 파일 준비
nginx.conf 파일을 생성하여 Nginx가 트래픽을 애플리케이션으로 전달하도록 설정한다.
events { }
http {
server {
server_name your-ec2-public-dns; # EC2 퍼블릭 DNS 또는 IP 주소
// ... 생략
}
ssl디렉터리를 프로젝트 내에 생성하고,nginx-selfsigned.crt와nginx-selfsigned.key를 넣는다.
Docker Compose로 컨테이너 실행
프로젝트 디렉터리에서 다음 명령어로 Docker Compose를 실행하여 애플리케이션과 Nginx를 시작한다.
docker-compose up --build -d
로컬 환경에서는 정상적으로 작동하고, 배포 환경에서는 문제 발생

- 배포 환경에서 API 키가 올바르게 설정되지 않았을 수 있었다.
- 환경 변수나 설정 파일에서 API 키를 제대로 읽어오고 있는지 확인하였다.
즉, 문제를 해결하기 위해 배포 환경에서 API 키가 올바르게 설정되어 있는지를 다시 한 번 확인하고, 필요한 경우 docker-compose.yml에 환경 변수를 추가하여 설정해봤다.

docker-compose.yml 파일 수정
docker-compose.yml 파일에 환경 변수를 설정하여 Docker 컨테이너에서 OPENAI_API_KEY를 사용할 수 있도록 한다.
version: '3'
services:
application:
// ... 생략
environment:
- SPRING_PROFILES_ACTIVE=prod # 필요에 따라 프로파일 설정
- OPENAI_API_KEY=${OPENAI_API_KEY}
// ... 생략
Docker Compose 빌드 및 실행
환경 변수 설정 후 다음 명령어를 통해 Docker Compose를 재빌드 및 실행하세요.
docker-compose up --build -d
- 재빌드:
-build옵션이 포함되어 있기 때문에docker-compose는Dockerfile을 사용하여 필요한 이미지를 다시 빌드합니다. - 백그라운드 실행:
d옵션은 컨테이너를 백그라운드에서 실행합니다.
배포 상황에서의 문제점)
PDF 파일을 올리니깐, 이렇게 에러가 발생해서 동작을 제대로 하지 않는 이유.

이 오류 메시지는 Tesseract OCR 라이브러리가 특정 언어 데이터 파일(chi_tra)을 찾지 못해 발생하는 문제이다.
- Tesseract가 필요로 하는
chi_tra.traineddata파일이 서버에 없거나, 잘못된 경로에 위치해 있기 때문이라고 한다.
언어 데이터 파일 설치
- Tesseract가 필요한
traineddata파일(chi_tra.traineddata)이 있는지 확인한다. - 만약 없다면, 다음 명령어로 언어 데이터를 설치한다.
sudo apt-get update
sudo apt-get install tesseract-ocr-chi-tra
역시 없었던 것이다..

현재 사용 중인 EC2 인스턴스는 Amazon Linux를 기반으로 하고 있어서 apt-get이 아닌 yum 패키지 관리자를 사용해야 했다.
Amazon Linux에서 Tesseract와 관련된 패키지를 설치하려면 yum 명령어를 사용해야 한다는걸 알게 되었다.
현재 tessdata 파일을 임시 디렉토리에 복사하고 tessdata 경로를 설정하고 있는데,
임시 디렉토리는 재시작 시 삭제되기 때문에, 지속적인 경로로 설정하여야 했다.
tessdata 폴더에 eng.traineddata와 kor.traineddata 파일이 있는 것을 확인했다.
이제 이 경로를 Tesseract의 tessdata 경로로 정확히 설정해주면 된다.

application.yml 파일 설정
먼저 application.yml 파일에 다음과 같이 tessdata 경로를 지정한다.
tessdata:
prefix: src/main/resources/tessdata # 실제 tessdata 디렉토리 경로
OcrService 클래스 수정
OcrService 클래스에서 tessdata 경로를 application.yml 파일에서 읽어오도록 수정한다.
@Service
@RequiredArgsConstructor
public class OcrService {
@Value("${tessdata.prefix}")
private String tessDataPath;
private final Tesseract tesseract = new Tesseract();
@PostConstruct
public void init() {
// Tesseract 설정에 yml에서 주입받은 tessDataPath를 사용
tesseract.setDatapath(tessDataPath); // 설정 파일에서 경로 가져오기
tesseract.setLanguage("kor"); // 필요한 경우 "eng+kor"로 설정
}
public String extractTextFromPdfWithOcr(File pdfFile) throws IOException, TesseractException {
StringBuilder extractedText = new StringBuilder();
try (PDDocument document = PDDocument.load(pdfFile)) {
PDFRenderer renderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage image = renderer.renderImageWithDPI(page, 300, ImageType.GRAY);
String pageText = tesseract.doOCR(image);
extractedText.append(pageText);
}
}
return extractedText.toString();
}
}
@Value("${tessdata.prefix}")를 통해application.yml에서 설정한tessdata.prefix값을tessDataPath에 주입받는다.Tesseract객체의setDatapath()메서드에tessDataPath를 설정한다.init()메서드에서tessDataPath가 Tesseract의datapath로 사용되기 때문에, 임시 디렉토리로 복사하는 작업은 필요하지 않는다.
도커 컨테이너에 Tesseract 설치 및 설정하기
- Dockerfile 수정하기
# OpenJDK 17을 기반으로 한 Docker 이미지 사용
FROM openjdk:17-jdk-slim
# Tesseract 및 필수 패키지 설치
RUN apt-get update && apt-get install -y tesseract-ocr tesseract-ocr-kor tesseract-ocr-eng libtesseract-dev
// ... 생략
이렇게 하면 도커 이미지를 빌드할 때 Tesseract와 한국어 및 영어 언어 데이터도 함께 설치된다.
docker-compose.yml 수정
docker-compose.yml에서Dockerfile을 사용하여 애플리케이션을 빌드하고, 필요한 환경 변수를 설정해 준다.
version: '3'
services:
application:
// ... 생략
environment:
- SPRING_PROFILES_ACTIVE=prod
- TESSDATA_PREFIX=/usr/share/tesseract-ocr/4.00/tessdata # Tesseract 데이터 경로 설정
// ... 생략
위 설정에서 TESSDATA_PREFIX를 /usr/share/tesseract-ocr/4.00/tessdata로 설정했다.
이는 Tesseract의 언어 데이터 위치를 지정하는 환경 변수이다.
- 이제 변경 사항을 반영하여 도커 컨테이너를 다시 빌드하고 실행하여 에러를 해결 하였다.
도메인 설정해보기.
나는 밑에 있는 서비스를 통해 1년 동안 도메인을 공짜로 사용할 수 있게 되었다.

이 화면은 DNS 설정 페이지로, AWS EC2 서버에 도메인을 연결할 수 있다.
필요한 설정은 IP 연결 (A) 항목을 이용해 AWS EC2 인스턴스의 퍼블릭 IP 주소를 입력하는 것이다.
EC2 퍼블릭 IP 확인
- AWS EC2 콘솔로 이동하여, 도메인을 연결하고자 하는 EC2 인스턴스를 찾는다.
- 해당 인스턴스의
퍼블릭 IPv4 주소를 확인하면 되는 것이다.
IP 연결 (A) 항목 설정
IP연결 (A)항목 오른쪽의 빈칸에EC2 퍼블릭 IP 주소를 입력한다.
이렇게 IP 연결 (A) 항목에 EC2 퍼블릭 IP 주소를 입력하고 저장하면 기본적인 설정은 완료
Nginx 및 방화벽 설정 확인
- EC2 인스턴스에서 Nginx가 정상적으로 작동하고, 80번 포트(HTTP)가 열려 있어야 한다.
- AWS 보안 그룹 설정에서 인바운드 규칙에 80번 포트가 허용되어 있는지 확인한다.
이후 이력서가이드.웹.한국 주소로 접속하면 설정한 EC2 인스턴스에 연결된 애플리케이션이 표시 되었다.