- 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 인스턴스에 연결된 애플리케이션이 표시 되었다.