DEV/Infrastructure

[NCP, 도커] 서버 생성부터 배포까지 (3 / 4)

Bi3a 2024. 1. 7. 18:14

728x90

 

이전 포스팅에서 이어집니다.

 

[NCP, 도커] 서버 생성부터 배포까지 (야매판, 2 / 4)

이전 포스팅에서 이어집니다. [NCP, 도커] 서버 생성부터 배포까지 (야매판, 1 / 3) NCP 서버 생성, 도메인 레코드 설정 및 IP 할당 NCP 서버 생성 공인 IP 추가 신청 Server > Public IP Q. 서버 접속용 공인 IP

doinitright.tistory.com

 

인프라에 대해 학습합시다.


 

NPM 리버스 프록시 설정

NPM 설치가 완료되었으므로
1. NPM을 통한 클라이언트가 접속할 도메인,
2. 도메인 접속 시 연결할 서버 내부의 포트,
3. 리다이렉트 경로까지
NPM을 통해 설정한다.

 

리버스 프록시 호스트 설정

 

  • Domain Names : 접속 도메인을 지정한다. 별도 포트를 미지정 시 디폴트 포트인 80으로 접속함을 의미한다.
  • Scheme : 통신 프토토콜을 지정한다. 웹 요청의 경우 별도 설정하지 않았을 시 디폴트 설정은 http이다.
  • Forward Hostname / IP : 해당 도메인으로 통신이 올 시 요청을 보낼 내부 IP를 지정한다.
    • 도커 내부의 호스트 IP는 항상 172.17.0.1 이다.
  • Forward Port : 해당 도메인으로 통신이 올 시 요청을 보낼 내부 포트를 지정한다.
  • Websockets Suppot : 클라이언트와 서버 실시간 양방향 통신을 제공하는 프로토콜인 웹소켓을 지정한다.
    • 주로, 실시간 업데이트, 채팅 어플리케이션, 라이브 스트리밍 등 양쪽에서 데이터 통신이 요구되는 상황일 시 Enable 한다.

 

SSL 설정

 

  • Force SSL : SSL을 통해 암호화된 연결을 강제한다.
    • 보안 강화와 중간자 공격을 방지하며, 클라이언트 ↔ 서버 간 통신이 안전한 채널을 통해 이뤄진다.
  • HTTP/2 Support : Http 프로토콜의 두번째 버전으로, 다수의 요청 및 응답을 동시 처리, 헤더 압축 등의 기술을 통해 네트워크 사용을 최적화한다. 
    • 웹 페이지 로딩 시간을 줄일 수 있다는 장점이 존재한다.
  • HSTS enabled : 웹 서버가 클라이언트에게 웹 사이트를 항상 HTTPS로 연결하도록 지시한다. 
    • 해당 설정을 enable할 시 HTTP 버전에 대한 엑세스를 차단한다.
    • default인 80 포트의 http로 요청을 하더라도 443 포트의 https 으로 자동으로 접속 요청이 변환된다.
  • DNS Challenge : 웹 서버에 대한 접근 권한이 없어도 SSL 인증서를 발급 할 수 있다. 

 

프록시 호스트 설정 결과

즉, 앞에서의 리버스 프록시 호스트 설정은 아래와 같은 의미의 동작을 실행한다.

[ if ]

gamedragons.api.bi3a.app의 80번 포트로(별도 미지정 시 디폴트 값) 외부에서 클라이언트가 요청을 보냄

[ then ]

  1. 자동적으로 http 요청이 HSTS enabled 된 SSL 설정에 의해 https 요청으로 변환되며, 443 포트로 요청을 보낸다.
  2. 리버스 프록시에서 SSL 설정을 위해 클라이언트 브라우저에 인증서를 설치해 암호화된 통신을 보장한다.
  3. 리버스 프록시는 해당 443 포트로 들어온 HTTPS 요청을 받아서 도커의 외부 서버(도커 호스트, 172.17.0.1)의 8080번 포트로 요청을 전송한다(프록시 패스)
  4. 도커 호스트는 도커 호스트의 8080으로 들어온 요청을 포트 포워딩 설정에 의해 도커 호스트의 8080번 포트와 연결되어 있는 도커 내부의 컨테이너의 특정 포트로 전송한다. (포트 포워딩 / 아직 설정 안함)

 

 

프론트, 백엔드 서버를 분리해 띄우기 위해 별도의 도메인와 이에 대한 프록시 설정을 진행했다.

 

Redirection Host 설정

 

리다이렉션 호스트 설정은 말 그대로 리다이렉트 설정이다.

해당 프로젝트에서는 www.gamedragons.bi3a.app -> gamedragons.bi3a.app 으로 요청을 리다이렉트하게 설정했다.

  

SSL 설정은 앞서 설명한 그대로 설정했다.

 

 

DB 서버 띄우고 연결하기

도커 호스트의 3306 포트에 컨테이너를 생성해 MYSQL DB 서버를 구동한다.

 

MySQL 이미지 pull, 컨테이너 생성 후 구동

# mysql 이미지 pull 및 컨테이너 구동

docker run --name mysql_1 \
    -e MYSQL_ROOT_PASSWORD=<설정할 비밀번호> \ # 접속 비밀번호 설정, 계정명은 ROOT
    -e TZ=Asia/Seoul \ # 지역
    -d \
    -p 3306:3306 \ # 외부: 내부 포트 설정
    # 볼륨 설정(백업), 외부 폴더(지정 가능) : 내부 폴더(MySQL 기본 설정이므로 변경 불가)
    -v /docker_projects/mysql_1/volumns/var/lib/mysql:/var/lib/mysql \ 
    --restart unless-stopped \ # 컨테이너가 시스템 재부팅이나 종료 시 자동으로 다시 시작되게 설정
    mysql \
    --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

 

해당 접속 비밀번호는 원격지인 개발 환경에서 DB 관리를 할 때 필요한 비밀번호이므로 절대 유출해서는 안된다. 

 

[구동 후 docker ps -a]

 

MySQL 접속 후 권한 부여

도커 run 시에 설정한 비밀번호와 root, 연결한 도메인과 포트를 입력하고 정상적으로 연결이 되었는지 확인한다.

 

 

아래의 질의어를 입력해 DB 제어 권한을 특정 IP에만 부여한다.

[MySQL / root@gamedragons.api.bi3a.app]

# 특정 IP에 따른 유저와 비밀번호 할당
CREATE USER 'lldjlocal'@'127.0.0.1' IDENTIFIED BY '1234'; # 현재 작업중인 본인 IP
CREATE USER 'lldjlocal'@'172.17.%.%' IDENTIFIED BY '1234'; # 도커 상의 IP

# 권한 부여
GRANT ALL PRIVILEGES ON *.* TO 'lldjlocal'@'127.0.0.1'; 
GRANT ALL PRIVILEGES ON *.* TO 'lldjlocal'@'172.17.%.%';

# 권한 부여 (FLUSH까지 완료되어야 권한이 부여됨)
FLUSH PRIVILEGES;

 

위의 권한을 부여함으로써 도커 run 시에 설정한 원격지 비밀번호를 알지 않는 이상

DB 제어 권한은 현재의 작업 환경(127.0.0.1) 과 도커 내부(127.17.xx.xx) 환경 밖에 없게끔 설정했다. 

 

Database 생성

스프링이 실행되며 자동으로 해당 DBMS의 데이터베이스를 찾을 수 있도록 yaml 파일 설정과 동일하게 MySQL 서버 상 데이터베이스를 생성해준다.

 

[application-prod.yml]

 

  • url : 도커의 3306 포트의 demo_prod 이름의 데이터베이스로 접속하겠다는 의미
  • username : 해당 DB 접속 시 도커 컨테이너 내부에서 사용할 ID / (위의 MySQL에서 권한 부여한 ID 입력)
  • password : 해당 DB 접속 시 ID에 상응하는 PW 입력 / (위의 MySQL에서 권한 부여한 PW 입력)

실습 환경이기에 로컬에서의 접속 권한과 ID / PW 를 하드코딩으로 공개했지만 결론적으로 이러한 환경 변수는 모두 별개의 파일에서 Secret key로 관리하면 좋을 듯 하다.

 

[MySQL / root@gamedragons.api.bi3a.app]

CREATE DATABASE demo_prod;

 

 MySQL에서도 datasource에 접근할 수 있도록 설정 파일과 동일하게 DB를 생성해준다.

SHOW DATABASES;

 

DB가 생성되었다.

 

 

다음 포스팅에서는 최종적으로 DockerFile을 통한 백, 프론트 작업 내용에 대한 이미지를 생성,

이후 이를 다운받아 각자의 컨테이너에 띄우는 과정을 진행할 예정이다.

 


틀린 부분이 있으면 댓글로 알려주세요!