안녕하세요. 이번 글에서는 기존에 배포해두었던 프로젝트에 도메인을 연결하는 과정을 정리해보겠습니다.
해당 프로젝트는 원래 앱 중심 프로젝트였기 때문에 서버 IP로만 접근해도 충분하다고 생각했습니다. 하지만 포트폴리오로 활용하거나 추후 웹에서도 함게 접근할 가능성을 고려했을 때 도메인을 연결해두는 편이 더 적절하다고 판단했습니다.
또한 이후 HTTPS 적용까지 진행하기 위해서는 먼저 도메인 연결이 필요하기 때문에 이번 글에서는 도메인 연결 과정까지만 정리해보겠습니다.
설정에 들어가기 앞서 이전에 작성했던 관련 내용은 아래에서 확인할 수 있습니다. 해당 내용을 참고하시면 도메인 연동에 많은 도움이 될 것 같습니다.
DNS
인터넷의 이해 2 - DNS와 그 작동 원리
DNS(Domain Name System)란?도메인 이름을 IP 주소로 변환하는 시스템전세계 도메인 정보를 효율적으로 관리하고 빠르게 조회하기 위해 계층구조로 나뉘어진 분산형 데이터 베이스 구조로 동작한다.앞
0110020321.tistory.com
CORS
웹 보안 지식(4) - CORS
안녕하세요. 다시 월요일이 돌아왔네요. 주말동안 약속이 있어서 나갔는데 깁스한 상태로 열심히 돌아다니니 발바닥이 불타는 기분이네요. 카페에서 작업할 생각이였는데, 한동안은 꼼짝 없이
0110020321.tistory.com
도메인을 선택하기 전 생각해볼 것
도메인을 연결하기 전에 먼저 어떤 방식으로 DNS 레코드를 설정할지 정해야 합니다.
대표적으로 사용할 수 있는 방식은 A Record와 CNAME입니다.
A Record VS CNAME
기존에는 'http://1.1.1.1'처럼 서버의 IP 주소를 직접 입력해 프로젝트에 접근했습니다. 하지만 실제 서비스처럼 접근성을 높이기 위해서는 사용자가 IP 주소를 기억하는 방식보다 도메인을 통해 접속할 수 있도록 구성하는 것이 더 적절합니다.
이때 도메인을 서버에 연결하는 방법은 크게 A Record와 CNAME을 생각해볼 수 있습니다.
A Record
도메인을 특정 IP 주소에 직접 연결하는 방식입니다.
예를 들어 'example.com' → '1.1.1.1'처럼 도메인이 서버의 고정 IP를 바라보도록 설정합니다.
CNAME
도메인을 다른 도메인 이름에 연결하는 방식입니다.
예를 들어 'www.example.com' → 'example.com'처럼 하나의 도메인이 다른 도메인을 따라가도록 설정할 때 사용합니다.
이번 프로젝트에서는 A Record 방식을 사용하기로 했습니다.
현재 서버는 OCI 인스턴스에 배포되어 있고, 고정 IP를 통해 접근할 수 있는 상태입니다. 따라서 도메인 설정에 해당 IP 주소를 직접 연결하는 A Record 방식이 가장 단순하고 명확하다고 판단했습니다. 또한 비용을 최소화하는 것도 중요한 기준이었습니다.
OCI 환경에서 추가적인 관리형 DNS 구성을 사용하는 것보다 구매한 도메인의 DNS 설정에서 A Record로 서버 IP를 직접 연결하는 방식이 현재 프로젝트 규모에는 더 적합하다고 판단했습니다.
그렇기에 이번 프로젝트에서는 다음과 같은 이유로 A Record를 선택했습니다.
| 구분 | 선택 이유 |
| 서버 구조 | OCI 인스턴스에 고정 IP로 배포되어 있음 |
| 설정 방식 | 도메인에 IP를 직접 연결하면 됨 |
| 비용 | 추가 비용 최소화 |
| 프로젝트 규모 | 포트폴리오용 프로젝트에 적합한 구조 |
도메인 등록 업체 선택
도메인을 연결하기 위해서는 먼저 도메인을 구매하고 관리할 수 있는 등록 업체가 필요합니다.
도메인 등록 업체는 가비아, 카페24, 후이즈, Cloudflare 등 다양하게 존재합니다. 그 중 이번 프로젝트에서는 가비아를 선택했습니다.
가비아를 선택한 이유
가비아를 선택한 가장 큰 이유는 비용과 접근성이었습니다.
개인 포트폴리오 프로젝트에서 사용하는 도메인이기 때문에 처음부터 비싼 도메인을 사용할 필요는 없다고 판단했습니다. 'com'과 같이 많이 사용되는 도메인은 상대적으로 비용이 높을 수 있지만, '.store', '.shop' 등 일부 도메인은 비교적 저렴하게 구매할 수 있습니다.
또한 가비아는 국내 서비스이기 떄문에 도메인 구매, DNS 설정, A Record 등록 과정을 한국어 화면으로 진행할 수 있는 점도 장점이었습니다. 처음 도메인을 연결하는 입장에서는 설정 메뉴를 이해하기 쉬운 것이 중요하다고 생각했습니다.
가비아를 선택한 이유는 다음과 같습니다.
| 선택 기준 | 이유 |
| 비용 | `.store`, `.shop` 등 비교적 저렴한 도메인 선택 가능 |
| 접근성 | 국내 서비스라 한국어로 설정 가능 |
| 관리 편의성 | 도메인 구매 후 DNS 설정까지 한 곳에서 관리 가능 |
| 프로젝트 목적 | 개인 포트폴리오 프로젝트에 적합한 수준의 비용과 기능 제공 |
.
도메인 구매하기
가비아(https://domain.gabia.com/)에 접속하여 화면과 같이 원하는 도메인을 검색합니다.
'.SHOP'이 현재 이벤트 할인으로 가장 저렴하지만 현재 진행중인 프로젝트는 쇼핑몰이 아닌 SNS 앱 프로젝트이기에 서비스 성격과 조금 더 잘 맞는 'site'도메인을 선택했습니다.

위와 같이 사용하고 싶은 도메인 이름을 입력해 검색하면 현재 등록 가능한 도메인과 각 확장자별 가격을 확인할 수 있습니다.
검색 결과를 확인한 후 원하는 도메인을 [선택]한 다음 [신청하기] 로 넘어갑니다.


[필수 정보]를 모두 작성한 후 [다음 단계]로 넘어가 결제를 완료합니다.
이후 구매한 도메인의 DNS 설정을 변경하기 위해 [도메인 정보 변경] → [DNS 관리] 메뉴로 이동합니다.


DNS 관리 화면에서 구매한 도메인을 선택한 다음 [DNS 설정]을 진행합니다.

A Record 방식을 사용할 것이기에 레코드 타입은 'A'로 선택합니다.
이때 호스트는 '@'와 'www'를 각각 등록했습니다.
- '@' : 루트 도메인을 의미합니다. 예를 들어 'example.com'처럼 'www' 없이 도메인만 입력했을 때 연결되도록 설정합니다.
- 'www' : 'www.example.com' 주소로 접속했을 때 연결되도록 설정합니다. 사용자가 주소 앞에 'www'를 붙여 접속하는 경우도 있기에 함께 등록하여 접근성을 높일 수 있습니다.

CORS 문제
도메인 연결 후 새 도메인으로 접속하면 아래와 같이 CORS 오류가 발생할 수 있습니다.
CORS는 이전 웹 보안 시리즈에서도 정리했던 내용입니다. 간단히 말하면 브라우저가 서로 다른 출처 간 요청을 제한하는 보안 정책입니다.
이번 경우에는 기존 IP 주소로 접근하던 구조에서 도메인 주소로 접근하도록 변경되면서 문제가 발생했습니다.
프론트엔드에 접속한 주소는 도메인으로 바뀌었지만, 백엔드 CORS 설정에는 아직 해당 도메인이 허용되지 않았기 때문입니다.
즉, 브라우저 입장에서는 허용되지 않은 출처에서 API 요청이 발생한 것으로 판단했고, 그 결과 CORS 오류가 발생했습니다.
따라서 도메인 연결 이후에는 백엔드 CORS 설정에 새 도메인을 추가해야 합니다.

해결 과정
도메인 연결 후 발생한 CORS 오류를 해결하기 위해 두 가지 작업을 진행했습니다.
첫 번째로는 프론트엔드에서 API를 요청하던 기존 IP 주소를 새로 연결한 도메인 주소로 변경했습니다. 기존에는 서버 IP를 직접 바라보는 방식이었지만 이제는 도메인을 연결했기 때문에 프론트엔드에서도 요청 주소를 도메인 기준으로 맞춰주어야 합니다.
두 번째로는 백엔드에 CORS 설정을 추가했습니다.
도메인을 연결하기 전에는 IP 주소 기준으로만 접근했기에 별도의 CORS 설정이 필요하지 않았습니다. 하지만 해당 도메인으로 접근하게 되면 브라우저는 이를 새로운 출처로 판단했기에 Spring Security 설정에서 해당 도메인을 허용 출처로 등록해주었습니다.
프론트엔드 설정

백엔드 CORS 설정
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final TokenProvider tokenProvider;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// Spring Security에서 아래에 직접 정의한 CORS 설정을 사용하도록 등록
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
// JWT 기반 인증을 사용하므로 CSRF 비활성화
.csrf(csrf -> csrf.disable())
...
.anyRequest().authenticated()
)
// 매 요청마다 JWT 토큰을 검사하는 필터 등록
.addFilterBefore(new TokenAuthenticationFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
// 프론트엔드에서 접근할 수 있는 출처 등록
// 현재는 http로 접속하지만, 이후 HTTPS 적용을 고려해 https 주소도 함께 추가
// www가 붙은 주소와 붙지 않은 주소 모두 허용
configuration.setAllowedOrigins(List.of(
"http://buddymate.site",
"http://www.buddymate.site",
"https://buddymate.site",
"https://www.buddymate.site"
));
// API 요청에 사용할 HTTP 메서드 허용
// OPTIONS는 CORS Preflight 요청에서 사용됨
configuration.setAllowedMethods(List.of(
"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"
));
// JWT 인증 요청에서 Authorization 헤더 등이 필요하므로 모든 요청 헤더 허용
configuration.setAllowedHeaders(List.of("*"));
// 응답 헤더 중 프론트엔드에서 Authorization 값을 읽어야 하는 경우를 위해 노출
configuration.setExposedHeaders(List.of("Authorization"));
// 쿠키 등 인증 정보가 포함된 요청을 허용
// JWT를 Authorization 헤더로만 사용하고 쿠키를 사용하지 않는다면 false로 설정해도 됨
configuration.setAllowCredentials(true);
// Preflight 요청 결과를 3600초 동안 캐싱
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 모든 API 경로에 위 CORS 정책 적용
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
위 설정을 통해 Spring Security에서 CORS 정책을 직접 적용하도록 구성했습니다.
도메인 연결 이후 프론트엔드 접속 주소가 변경되었기 때문에 백엔드에서도 해당 도메인을 허용 출처로 등록했습니다. 또한 'www' 여부와 이후 HTTPS 적용까지 고려해 총 네 가지 주소를 허용했습니다.
결과적으로 새 도메인에서 접속하더라도 브라우저의 CORS 정책에 의해 API 요청이 차단되지 않도록 설정했습니다.
애매하게 알고 있던 개념을 프로젝트에 적용해보는 것과 학습한 내용을 실제 프로젝트의 에러로 마주하는 것은 확실히 느낌이 다르네요.
이번에는 도메인 연겨 이후 발생한 CORS 오류를 직접 확인하고, 프론트엔드 요청 주소와 백엔드 CORS 설정을 수정하면서 문제를 해결했습니다.
작은 설정이었지만 실제 배포 환경에서 하나씩 문제를 해결하는 과정이 한 발자국씩 성장하고 있다는 느낌이 들었습니다. 덕분에 개발도 다시 조금씩 재밌어지고 있습니다.
다음 시간에는 HTTPS 설정 과정으로 돌아오겠습니다. 수고하셨습니다.
다음편 :
IP 접속에서 도메인 접속으로(2) - HTTPS 설정하기
안녕하세요. 다들 저녁은 드셨나요? 저는 오늘 동태탕에 솥밥을 먹었는데 너무 맛있어서 기분 좋게 하루를 마무리하고 있습니다.저번 시간에는 도메인을 연결하고 그 과정에서 발생한 CORS 문제
0110020321.tistory.com
'개발일지' 카테고리의 다른 글
| 만보기 API 연동하기(1) (0) | 2026.05.26 |
|---|---|
| IP 접속에서 도메인 접속으로(2) - HTTPS 설정하기 (0) | 2026.05.13 |
| 구글 OAuth2.0 - Flutter와 연동하기(1) (0) | 2026.04.24 |