Post

vercel, ngrok 을 사용하여 무료로 프로젝트 배포하기

일정기간 간단하게 배포 하는데 돈을 들이고 싶지 않다면 이글을 참고해보세요.

1. 동시동작 테스트를 하고싶은데… 🥹

제가 만든 서비스는 아래와 같이 여러명이 한 페이지에서 여행 계획을 같이 세우는 것이였습니다.

아래와 같이 동작 과정을 찍기 위해서는 프로젝트를 배포해야겠죠. 하지만 저는 돈을 쓰고 싶지 않았습니다. 결국 돈을 하나도 쓰지 않고 해결했죠! 😎



2. 프론트는 vercel 로, 백엔드는 ngrok 으로

Vercel을 통해 프론트 프로젝트를 배포한 후, 백엔드는 로컬에서 실행하고, ngrok 을 사용해 외부에서 로컬에 접근할 수 있도록 터널링합니다.

  1. vercel 홈페이지
  2. ngrok 홈페이지

2.1. backend key 생성

keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650

하지만 윈도우의 경우 인텔리제이에서 터미널에서, 인텔리제이에서 받은 sdk 를 사용한다면 위 명령어가 먹히지 않을 수 있습니다. 그럴 때에는 sdk 의 위치를 파악한 다음, 해당 위치를 환경변수에 등록해주세요. 그럼에도 아래와 같은 오류가 나타날 수 있습니다.

식 또는 문에서 예기치 않은 '-genkeypair' 토큰입니다.
식 또는 문에서 예기치 않은 '-alias' 토큰입니다.

그럴때에는 아래와 같이 명령어를 작성해주세요.

& "{ keytool.exe 의 위치 }" -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650

& 연산자를 사용하면 정상적으로 실행됩니다.

2.2. keyStore 등록

생성된 키는 프로젝트 최상위에 있어야 합니다. 그리고 깃허브에 올라가지 않도록 주의해주세요. 그리고 https 로 실행하기 위해서는 아래와 같이 application.yml 을 수정해주어야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
  port:
    8443
  ssl:
    enabled:
      true
    key-store:
      keystore.p12
    key-store-password:
      ${SPRING_DATASOURCE_PASSWORD}
    key-store-type:
      PKCS12
    key-alias:
      tomcat

그리고 실행하면 아래와 같이 톰캣이 https 로 시작되었다는 로그가 나올거에요.

2024-08-23T12:44:44.553+09:00  INFO 9136 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8443 (https) with context path ''

2.3. Security 설정 변경

  • http 로 요청이 들어와도 바로 https 로 리다이렉트 되도록 하는 코드를 추가해주세요.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      @Bean
          public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
              httpSecurity
                      .cors(cors -> {})
                      ...
                      .requiresChannel(channel ->
                              channel.anyRequest().requiresSecure()
                      );
        
              return httpSecurity.build();
          }
    
  • 시큐리티 CORS 설정에서 아래와 같이 ngrok 헤더를 노출해주세요.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
      @Bean
          public CorsFilter corsFilter() {
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
              CorsConfiguration config = new CorsConfiguration();
        
              config.setAllowCredentials(true);
              config.addAllowedOrigin("https://trip-now.vercel.app/");
              config.addExposedHeader("Authorization");
              config.addExposedHeader("ngrok-skip-browser-warning");
              config.addAllowedHeader("*");
              config.addAllowedMethod("*");
              source.registerCorsConfiguration("/**", config);
        
              return new CorsFilter(source);
          }
    

2.4. 만약 소셜 로그인을 사용한다면?

https 로 실행했기 때문에 콜백 주소를 알맞게 바꿔주어야 합니다.

2.5. 만약 웹소켓을 사용한다면?

ws 를 전부 wss 로 바꿔주세요.

2.6. ngrok 실행

터미널에서 실행시 일반적인 실행 커맨드인 ngrok http {port number} 를 사용하면 오류가 납니다.

아래와 같이 명확하게 지정해주세요.

1
ngrok http "https://localhost:{포트번호}"

2.7. axios proxy 수정하기

  • front 에서 기본적으로 localhost:8080 으로 보냈다면, 이제는 ngrok 이 주는 주소로 바꿔야 합니다.
  • 헤더에 ngrok-skip-browser-warning 을 키로, 69420 을 값으로 넣어주세요.
    • 이렇게 하지 않으면 get 요청을 받지 못해요.
    • 아래와 같은 오류의 원인입니다.

        content.js:1 Uncaught 
        ReferenceError: Search is not defined
        at window.onload (content.js:1:2818)
        login:1 Access to XMLHttpRequest at 'https://~p/api/v1/auth/user' from origin 'https://trip-now.vercel.app' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
        index-DRfKBROT.js:1532 
      

2.8. vercel 에 배포하기

  • 배포시 vite 가 아닌, frame work 를 선택해주셔야 합니다.
  • 최상위 디렉토리를 잘 지정해주세요.
  • public 안의 asset 을 가져올 경우 이는 상대경로로 지정하면 안됩니다.
    • 엑박으로 뜨는 이슈가 존재해요.
    • ‘../../public/icon.png’ → ‘/icon.png’ 로 수정해주세요.

2.9. 주의

ngrok 무료 플랜의 경우 껐다 키면 도메인 주소가 갱신 되므로 서버를 계속 가동해야 프론트팀이 귀찮아지지 않습니다,,, 😂



3. 코드를 보고 싶다면?

3.1. 프론트 코드

https://github.com/sieunnnn/TripNow

3.2. 백엔드 코드

https://github.com/planner-project/sieunLab

This post is licensed under CC BY 4.0 by the author.