본문 바로가기
카테고리 없음

[OpenVidu] OpenVidu 커스텀 애플리케이션 서버 배포하기 (트러블 슈팅)

by 웅대 2023. 11. 2.
728x90
반응형

https://growth-coder.tistory.com/262

이전 포스팅에서 EC2에 OpenVidu를 배포하는 과정을 진행해보았다.

 

이번 포스팅에서는 커스텀 애플리케이션 서버를 배포하는 과정을 작성해보려고 한다.

 

의도치 않게 정말 많은 오류가 발생하였고 너무 많은 시간이 걸렸다...

 

혹시라도 커스텀 애플리케이션 서버를 배포하려는 분들을 위해 트러블 슈팅 과정을 모두 작성해보려고 한다.

 

우선 커스텀 애플리케이션 서버 배포를 이해하기 위해서는 docker, docker-compose, docker hub, Dockerfile, nginx에 대한 이해가 필요하다. (이전 포스팅 참고)

계기

이전 포스팅의 마지막 부분에 다음과 같이 5개의 컨테이너가 배포되어 있는 모습을 확인했었다.

각각의 역할은 아래와 같다.

  1. openvidu-openvidu-server : openvidu 서버 (시그널링 서버)
  2. openvidu-kms : kms 서버 (미디어 서버)
  3. openvidu-coturn : coturn 서버 (TURN 및 STUN 서버)
  4. openvidu-nginx : 웹 서버 (https 담당)
  5. openvidu-app : 애플리케이션 서버

대부분의 프로젝트에서는 커스텀 애플리케이션 서버를 사용하지 않고 위 컨테이너들을 그대로 사용하여도 큰 문제가 없을 것이다.

 

그런데 내가 진행하려는 프로젝트에서는 Session에 접속한 유저들끼리 통신하는 과정에서 Session이 유지되는 동안 데이터베이스에 접근해야 일이 필요했다.

 

그러기 위해서는 위에서 보이는 openvidu-app 컨테이너를 삭제하고 자신의 애플리케이션 서버 컨테이너를 띄우면 된다.

 

사실 처음에는 위 설정을 바꾸지 않고 추가로 애플리케이션 서버를 만들어서 OpenVidu Session에 접속할 때 내가 만든 서버에서도 소켓 통신을 사용하려고 했었다.

 

그런데 이미 OpenVidu에서 Session이 존재하고 여기서 실시간 통신을 할 수 있는데 또 다른 서버에서도 소켓 통신을 통해 실시간 정보를 주고받는다는 것이 부자연스럽게 느껴져서 조금 번거롭더라도 기존 OpenVidu 구성에서 애플리케이션 서버만 갈아끼우는 방식을 선택했다.

 

이 방법은 공식문서에도 설명이 나와있었기 때문에 금방 할 줄 알았으나 예상치 못한 에러들을 너무 많이 마주쳤다...

 

그래도 에러를 해결하는 과정에서 OpenVidu 구조를 더욱 이해할 수 있었던 것에 의의를 두려고 한다.

 

우선 공식 문서 링크는 다음과 같다.

https://docs.openvidu.io/en/2.29.0/deployment/deploying-openvidu-apps/

 

Deploy OpenVidu applications - OpenVidu Docs

From here you can search these documents. Enter your search terms below.

docs.openvidu.io

포트 열기

먼저 aws EC2의 보안 그룹 인바운드 규칙에서 다음과 같은 포트들을 열어준다.

https://docs.openvidu.io/en/2.29.0/deployment/ce/on-premises/

TCP 뿐만 아니라 UDP 포트도 열어줘야 한다는 사실을 잊지 말자. 

 

포트들을 모두 열어줬다면 OpenVidu를 배포하자. (이전 포스팅 참고)

 

 

https 설정 제거

openvidu를 배포했다면 기본적으로 NGINX에서 https 통신을 지원해준다.

 

그래서 자신의 서버 애플리케이션 자체에서 https 설정을 해두었다면 설정을 꺼야 한다.

 

나는 로컬에서 https를 적용하기 위해 jks 파일을 넣어두고 application.properties에 아래와 같이 https 설정을 해두었다.

server.port=${SERVER_PORT}
server.ssl.enabled=true
server.ssl.key-store=classpath:openvidu-selfsigned.jks
server.ssl.key-store-password=openvidu
server.ssl.key-store-type=JKS
server.ssl.key-alias=openvidu-selfsigned
openvidu.url=${OPENVIDU_URL}
openvidu.secret=${OPENVIDU_SECRET}

이 설정을 그대로 두고 애플리케이션 서버를 갈아끼울 경우 에러 메시지가 발생하기 때문에 아래와 같이 설정을 제거해주자.

server.port=${SERVER_PORT}
server.ssl.enabled=false
openvidu.url=${OPENVIDU_URL}
openvidu.secret=${OPENVIDU_SECRET}
반응형

버전 맞추기 

openvidu-browser와 openvidu-server의 버전을 맞춰야 한다.

 

처음에 openvidu-browser는 2.21, openvidu-server는 2.29를 사용했더니 콘솔 창에 에러 메시지가 발생했다.

 

두 개는 같은 버전으로 맞추는 것을 잊지 말자.

 

만약 세션에 접속할 수 없다면 버전이 다르지 않은지 확인해보자.

내 애플리케이션 서버 이미지 생성

이제 내 애플리케이션 서버를 도커 이미지로 만들 차례이다.

 

도커 이미지로 만드는 파일의 경우 권한을 부여하여 화상 회의를 할 수 있는 openvidu-roles-java 참고하였다.

https://github.com/OpenVidu/openvidu-tutorials/tree/master/openvidu-roles-java

 

위 튜토리얼에서는 이미지 생성을 위해 총 3개의 파일을 사용하였다.

 

<create_image.sh>

#!/bin/bash
if [ $# -eq 0 ]; then
    echo "No version argument provided. Usage: \"./create_image.sh <IMAGE_NAME>\""
    exit 1
fi

pushd ../
docker build --pull --no-cache --rm=true -f docker/Dockerfile -t "$1" .

<Dockerfile>

FROM maven:3.6.3 as build
WORKDIR /basic-webinar
COPY ./pom.xml pom.xml
COPY ./src/main src/main

RUN mvn clean install
RUN mvn -o package

FROM alpine:3.11

RUN apk update && \
    apk add openjdk11-jre && \
    rm -rf /var/cache/apk/*

# Install basic-webinar
RUN mkdir -p /opt/openvidu-basic-webinar
COPY --from=build /basic-webinar/target/openvidu-roles-java-*.jar /opt/openvidu-basic-webinar/openvidu-basic-webinar.jar
# Entrypoint
COPY ./docker/entrypoint.sh /usr/local/bin
RUN chmod +x /usr/local/bin/entrypoint.sh

CMD /usr/local/bin/entrypoint.sh

<entrypoint.sh>

#!/bin/sh

[ ! -z "${OPENVIDU_URL}" ] && echo "OPENVIDU_URL: ${OPENVIDU_URL}" || echo "OPENVIDU_URL: default"
[ ! -z "${OPENVIDU_SECRET}" ] && echo "OPENVIDU_SECRET: ${OPENVIDU_SECRET}" || echo "OPENVIDU_SECRET: default"
[ ! -z "${SERVER_PORT}" ] && echo "SERVER_PORT: ${SERVER_PORT}" || echo "SERVER_PORT: default"

# Run Application
JAVA_PROPERTIES="-Djava.security.egd=file:/dev/./urandom"
[ ! -z "${OPENVIDU_URL}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.url=${OPENVIDU_URL}"
[ ! -z "${OPENVIDU_SECRET}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dopenvidu.secret=${OPENVIDU_SECRET}"
[ ! -z "${SERVER_PORT}" ] && JAVA_PROPERTIES=" ${JAVA_PROPERTIES} -Dserver.port=${SERVER_PORT}"

java ${JAVA_PROPERTIES} -jar /opt/openvidu-basic-webinar/openvidu-basic-webinar.jar

기본적으로 빌드 관리 도구로 maven을 사용했는데 나는 gradle을 사용했기 때문에 위 코드들을 약간 변형하였다.

 

본인들의 서버에 맞게끔 적당히 변형하면 될 것 같다. (maven을 사용했다면 변경하지 않아도 될 것 같다.)

 

이제 create_image.sh를 실행해서 이미지를 만들고 도커 허브에 이미지를 올리자.

 

docker-compose.override.yml 파일 수정

docker-composes.override.yml 파일에서 애플리케이션 서버를 가져오는 부분을 수정하면 된다.

 

다른 부분은 변경할 필요 없고 image 부분만 자신의 이미지로 변경하면 된다.

NGINX 설정 조심하기

대망의 NGINX 설정...

 

내 하루를 통째로 날려버린 장본인이다...

 

OpenVidu에서 Nginx는 웹 서버로 사용하는데 https 적용 및 경로에 따라 트래픽을 라우팅하는 역할을 수행한다.

 

바로 트래픽을 라우팅하는 과정에서 에러가 발생하였고 이 에러를 찾지 못해 하루를 에러를 찾는데 날려버렸다.

 

먼저 내 서버는 roles-java 튜토리얼을 기반으로 조금 변형해서 만들었다.

 

서버에서 미리 만들어둔 계정으로 로그인을 하면 세션에 접속할 수 있는 화면이 나오고 여기서 세션에 접속하여 화상 회의를 할 수 있다.

 

로컬에서 테스트를 할 때는 로그인을 성공적으로 수행하고 세션에도 성공적으로 접속할 수 있었다.

 

그런데 이를 EC2에 올리니까 로그인 자체가 불가능했다.

 

분명 컨트롤러 경로는 틀리지 않았는데 404에러가 발생하는 것이었다.

 

내가 생각한 원인은 다음과 같았다.

 

처음에는 OpenVidu 서버 url이나 SECRET을 잘못 입력해서 OpenVidu에 연결하기 위한 SDK에서 오류가 났다고 생각했다.

 

그래서 내 애플리케이션 서버 로그를 찾아보았는데 애플리케이션 서버 로그에서는 에러 메시지를 찾아 볼 수가 없었다.

 

로그인 컨트롤러 부분에 로그를 찍도록 변경을 해서 재배포 해보았는데 로그인을 시도할 때 내 애플리케이션 서버로 요청 자체가 들어오지 않는 것을 확인했다.

 

도대체 어디에서 에러가 발생한 것인지 확인하기 위해서 모든 컨테이너의 로그를 찍어봤는데 오류가 발생한 곳은 OpenVidu 서버와 Nginx 서버였다.

 

로컬에서는 잘 작동되나 EC2에서 잘 작동되지 않는다는 점, 내 애플리케이션 서버까지 트래픽이 오지 않는다는 점을 고려했을 때 당연히 Nginx 설정을 의심해봤어야 했는데 그 생각을 미처하지 못했다...

 

Nginx의 역할이 애초에 요청을 받아서 애플리케이션 서버에 라우팅해주는 것인데 OpenVidu 구조를 제대로 파악하지 않고 배포를 하느라 이 생각을 하지 못한 것 같다...

 

뒤늦게 이 생각이 떠올라서 어서 Nginx 설정을 살펴보았다.

 

Nginx는 컨테이너로 배포가 되었기 때문에 docker exec -it 명령어로 컨테이너 내부로 들어갔다.

 

그리고 /etc/nginx/conf.d 디렉토리 내부의 default.conf 파일을 확인해보았다.

server 디렉티브 내부에 라우팅 내용이 적혀있다.

 

아래는 /dashboard로 시작하는 요청이 들어올 경우 트래픽을 OpenVidu 서버로 보낸다는 뜻이다.

공교롭게도 내가 사용한 LoginController는 튜토리얼에서 사용한 컨트롤러를 가져온 것이었고 그 컨트롤러는 로그인 요청을 "/dashboard"라는 경로로 받았다.

 

Nginx 설정에서 "/dashboard"로 들어온 요청은 전부 OpenVidu 서버로 보냈기 때문에 로그인 요청이 애플리케이션 서버에 도달하지 못하고 Nginx에 의해 OpenVidu 서버로 갔던 것이었다.

 

해결 방법은 단순했다.

 

그냥 내 애플리케이션 서버에서 "/dashboard" 경로를 쓰지 않으면 되는 것이다.

 

그렇게 로그인 요청을 "/login" 경로로 수정했고 EC2에서도 화상 회의에 성공했다.

 

OpenVidu 배포 전에 Nginx 설정을 보고 미리 설정되어있는 경로는 쓰지 않도록 하자.

 

괜히 내가 만든 애플리케이션 서버로 갈아끼우려다가 수많은 삽질을 경험했다.

 

그래도 삽질을 하면서 OpenVidu 구조에 대해서 깊은 이해를 할 수 있어서 마냥 삽질이라고 치부할 수는 없을 것 같다.

 

항상 뭐든지 구조를 꼼꼼하게 확인해보고 작업에 들어가자!!

 

 

728x90
반응형

댓글