본문 바로가기
Spring boot

Route 53없이 가비아 DNS 레코드를 통해 EC2 도메인 연결 및 Nginx로 서버 배포하기

by 리버🐦‍🔥 2024. 6. 17.

이번 포스팅은 EC2 인스턴스에 도메인을 연결하는 방법에 대해서 알아보고자 한다. 기존에는 Nginx를 사용하지 않고, Route 53(DNS)을 사용하여 호스팅 영역을 생성하고, 해당 영역에서 만들어진 레코드의 네임 서버 주소를 가비아의 네임 서버에 연결시켜 도메인을 연결했었다. 이번에는 가비아와 직접 도메인을 연결하여 AWS EC2 로드밸런서 없이 Nginx를 사용하여 로드밸런싱까지 진행해보려고 한다. 일단은 로드밸런싱까지는 양이 너무 방대하여 이번 포스팅에서는 가비아의 DNS 서버를 활용하여 도메인을 연결하는 내용만 다루도록 하겠다.

(본 포스팅은 이미 EC2 인스턴스 및 탄력적 IP가 설정되어있다고 가정하고 진행한다. 혹시라도 인스턴스를 생성하는 방법을 모른다면, “https://kyxxgsoo.tistory.com/entry/AWS-EC2인스턴스에-Spring-Boot-서버-배포하기” 포스팅을 참고하기 바란다.)

도메인 연결 순서

  1. 가비아에서 도메인 구입
  2. 네임서버 설정
  3. 가비아 DNS관리 툴에서 DNS 레코드 등록
  4. 도메인 연결 확인
  5. Nginx 설정을 통해 Spring boot 서버에 redirect하기

1. 가비아에서 도메인 구입

가비아에 보면 1년에 500원(?)밖에 안하는 행사중인 싼 도메인들이 많다. 가볍게 사이드 프로젝트를 진행할 생각이라면 이벤트 중인 도메인을 활용해보도록 하자!

2. 네임서버 설정

1. My가비아에서 이용 중인 서비스에서 도메인을 클릭(구매한 도메인이 있다면 도메인이 표시된다.)

2. 본인이 관리하고 싶은 도메인을 선택

3. 네임서버 기본 가비아 네임서버로 설정(아마 일반적으로는 기본 가비아 네임서버로 설정이 되어있다.)

3. 가비아 DNS관리 툴에서 DNS 레코드 등록

1. DNS정보 → DNS 관리

이 때, 여기 1번처럼 DNS 정보가 설정되지 않은 상태여야 한다.

2. DNS 레코드를 설정할 도메인을 선택

3. 레코드 수정 클릭

4. 레코드 추가를 눌러 아래와 같이 레코드를 추가한다.

이 때, 값/위치에는 AWS EC2 인스턴스에 할당된 탄력적 IP를 넣어준다.

이 때, TTL을 길게 설정하게 되면 추후에 DNS 레코드를 수정할 때, 기존 DNS가 갖는 수정사항의 유효기간이 오래 유지될 수 있다. 필자의 경우 레코드를 모두 삭제했음에도 불구하고 해당 도메인으로 계속 접근이 가능한 오류(?)가 있었는데, 이 원인이 TTL(Time to live)을 길게(3600초) 설정해놔서 해당 시간동안 DNS 레코드의 변경이 일어나도 실제 DNS서버에 적용되기까지는 시간이 걸려 문제가 발생했다. 아무튼… 혹시라도 레코드 수정이 필요할 때는 TTL을 잘 확인하고 적용하도록 하자!…

 

(추가적으로 위 DNS레코드 수정이 전 세계 DNS 서버에 전파되는데 최대 48시간이 걸릴 수 있다고 한다... 필자는 이걸 모르고 계속 안되는 줄 알고 설정을 만지작만지작 하며 삽질을 한 경험이 있다... 위 순서대로 설정을 잘 했다면 차분히 마음을 가다듬고 기다려보도록 하자...)
이 사이트(https://www.whatsmydns.net/)에서 내 DNS 레코드 설정이 현재 전 세계에 분포되어있는 서버들에 어떻게 적용이 되고있는지 실시간으로 확인할 수 있다.

 

또한 아래 명령어를 터미널에서 실행시키면 현재 내가 영향받고있는 DNS를 조회할 수 있다. 

nslookup -type=ns {내 도메인}

4. 도메인 연결 확인

가비아에 등록한 도메인을 활용하여 직접 접근해본다.

필자의 경우 이미 EC2 인스턴스에 Nginx가 설치되어 있어서 Nginx 페이지로 바로 이동했다.

Welcome to nginx 페이지가 뜨면 성공

5. Nginx 설정을 통해 Spring boot 서버에 redirect하기

1. sudo vi /etc/nginx/proxy_params 를 통해 proxy params를 설정(자세한 내용은 추후에 다루도록 하겠다.)

# proxy_params
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;

client_max_body_size 256M; # 클라이언트 버퍼 사이즈
client_body_buffer_size 1m;

# 버퍼가 제공하는 메모리 공간을 통해 데이터를 메모리에 저장
proxy_buffering on; 

# 백엔드 서버로부터 응답 데이터를 읽는 때 사용할 버퍼의 수 & 크기 설정
proxy_buffers 256 16k; 

# 프록시 서버로부터 수신된 응답의 첫 번째 부분을 읽는 데 사용되는 버퍼의 크기 설정
proxy_buffer_size 128k;

# 사용 중인 프록시 버퍼의 최대 크기
proxy_busy_buffers_size 256k;

# 한 번에 임시 파일에 기록되는 데이터의 수
proxy_temp_file_write_size 256k;

# 임시 파일의 최대값
proxy_max_temp_file_size 1024m;

# 프록시 서버와의 연결 설정에 대한 제한시간 
proxy_connect_timeout 300;

#프록시 서버로 요청을 전송하기 위한 제한 시간
proxy_send_timeout 300;

# 프록시 서버에서 응답을 읽는 데 대한 제한 시간
proxy_read_timeout 300;

# 프록시 응답 중 오류를 인터셉트하여 사용자 정의 오류 페이지를 표시하도록 설정
proxy_intercept_errors on;

2. sudo mkdir /var/log/nginx/proxy를 통해 access.log, error.log 파일 저장을 위한 proxy 디렉토리를 생성

3. sudo vi /etc/nginx/nginx.conf를 통해 설정파일을 수정

아래 사진과 같이 server_names_hash_bucket_size 64;의 주석을 해제하면 된다.

 http {

         ##
         # Basic Settings
         ##

         sendfile on;
         tcp_nopush on;
         types_hash_max_size 2048;
         # server_tokens off;

         server_names_hash_bucket_size 64;
         # server_name_in_redirect off;
         default_type application/octet-stream;

         ##

         ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
         ssl_prefer_server_ciphers on;

         ##
         # Logging Settings
         ##

         access_log /var/log/nginx/access.log;
         error_log /var/log/nginx/error.log;

         ##
         ##
         # Virtual Host Configs
         ##

         include /etc/nginx/conf.d/*.conf;
         include /etc/nginx/sites-enabled/*;
 }

 #mail {
 #       # See sample authentication script at:
 #       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
 #
 #       # auth_http localhost/auth.php;
 #       # pop3_capabilities "TOP" "USER";
 #       # imap_capabilities "IMAP4rev1" "UIDPLUS";
 #
 #       server {
 #               listen     localhost:110;
 #               protocol   pop3;
 #               proxy      on;
 #       }
 #
 #       server {
 #               listen     localhost:143;
 #               protocol   imap;
 #               proxy      on;
 #       }
 #}

해당 설정을 하는 이유는 nginx는 listen에 의해 80번 포트로 넘어오는 요청을 위 /etc/nginx/sites-available/{domain} 부분에서 설정한 server_name 값과 일치하는 서버 블록을 찾는다. 이 때, server_name을 추가하게 되는데 이 과정에서 해시 버킷 메모리 문제가 발생할 수 있다. 그래서 server_name_hash_bucket_size를 따로 설정해주었다.

 

4. sudo vi /etc/nginx/sites-available/{도메인} 명령어를 통해 server block을 설정한다.

server { # server block
	listen 80;

	server_name {도메인} www.{도메인}; # 가비아 DNS 레코드에서 설정한 도메인을 넣어준다.

	access_log /var/log/nginx/proxy/access.log;
	error_log /var/log/nginx/proxy/error.log;

	location / { # location block
		include /etc/nginx/proxy_params;
		proxy_pass http://{AWS EC2 탄력적 IP}:{리다이렉트 할 포트(스프링 부트 실행 포트)}; # reverse proxy에 필요한 변수이다. IP:PORT 형태로 특정 포트로 연결을 리다이렉트할 수 있다.
	}
}

5. 현재까지 설정 및 변경한 nginx 설정 파일들을 활성화

    a. sudo ln -s /etc/nginx/sites-avaliable/{도메인} /etc/nginx/sites-enabled/명령을 통해 심볼릭 링크 추가

    /etc/nginx/sites-available 디렉터리에 있는 도메인 설정 파일에 대한 심볼릭 링크가 /etc/nginx/sites-enabled 디렉터리에 생성된다. NGINX는 sites-enabled 디렉터리 내의 설정 파일들을 읽어 서버 설정에 반영한다. 따라서 sites-available 디렉터리에 설정 파일을 작성하고, 이를 sites-enabled 디렉터리로 링크함으로써, 설정의 활성화/비활성화를 간편하게 관리할 수 있다. 이렇게 하면 설정 파일을 복사하거나 옮기지 않고도 필요에 따라 서버 구성을 쉽게 변경할 수 있다.

    b. sudo rm /etc/nginx/sites-available/default, sudo rm /etc/nginx/sites-enabled/default 를 통해 각 디렉토리에 존재하던 default 파일 삭제

    c. sudo nginx -t 를 통해 설정 파일을 테스트

설정 파일이 정상적이라면 아래와 같은 문구가 나온다.

    d. sudo service nginx reload를 통해 nginx 리로드

6. Spring boot 서버를 켜고 Nginx 설정이 제대로 적용됐는지 확인

제대로 설정이 되었다면 아래와 같은 화면이 출력된다. 혹시라도 제대로 설정이 안돼서 “502 bad gateway” 와 같은 에러가 뜬다면 /etc/nginx/sites-available/{도메인}의 설정 파일을 다시 한 번 확인하길 바란다. (보통 여기서 server_name이나 proxy_pass를 잘못 설정해서 에러가 많이 난다.)

6. Spring boot 서버에 테스트 컨트롤러를 통해 확인

1. 테스트 컨트롤러 코드 작성

@RestController
@RequiredArgsConstructor
@RequestMapping("/tests")
public class TestController {

    @GetMapping
    private String printTest() {

        return "test";
    }
}

 

2. 테스트 성공

끝!

다음은 nginx를 활용해 https를 설정하는 포스팅을 올려보도록 하겠다.