영업 뛰다가 온, 남들과 조금 다른 주니어 개발자

영업하면서 배운 고객 중심적 사고, 비즈니스 통찰력 등을 총동원해서 서비스를 개발하고 있습니다. 영업 경험이 개발하는 과정에서 큰 역할을 하더라구요, 즐겁게 개발하고 있습니다!

Computer Science/Web 프로젝트

오라클 서버에 Spring Boot, React 프로젝트 배포하기 (Nginx 사용)

브윗 2025. 1. 27. 22:02

만들어둔 오라클 서버에 Spring Boot 와 React 프로젝트를 배포하겠습니다!

Nginx가 정적 파일(리액트 앱)을 제공하고, API 요청을 스프링부트 애플리케이션으로 전달하는 방식입니다!

 

 

오라클 서버에 잘 접속할 수 있다는 전제 하에 시작!

오라클 서버 만드는 방법은 아래 글을 참고해서 만들었답니다!


* 참고 글 : https://mycodings.fly.dev/blog/2022-08-07-complete-introduction-of-oracle-cloud-free-tier#구획-내-가상-클라우드-컴퓨터-설정vcn

 


배포 전에 프로젝트의 특정 부분을 조금 바꿔줘야 할 수도 있다. (바로 내 얘기)
왜냐면 개발할 때랑 배포할 때에는 조금씩 도메인이나 ip 주소가 다르기 때문!

배포 생각 안하고 개발용으로 열심히 만들었다가, 이제 배포하려고 하니, 바꿔야하는 곳이 여러 곳이었다.

localhost:3000 이나 localhost:8080 으로 하드코딩 해뒀던 곳들은 모두 실제 내가 사용할 서버의 공인 ip 주소에 맞게 바꿈.

나는 WebConfig 나 SecurityConfig 파일에 작성해뒀던 것을 서버 공인 ip 로 바꿨다. 아래처럼!
(참고로 ip 주소 뿐만 아니라 사용할 도메인 주소도 추가해줘야함)


(예시)
@Configuration
public class WebConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        //.allowedOrigins("http://localhost:3000") // React 앱의 주소
                        .allowedOrigins("https://140.???.??.???") //Oracle Main server public ip
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}​


기존에는 http 로 작성했지만, 이제 배포할 때는 https 로 할 거기 때문에, 이 부분도 신경써줘야함 ㅠ
http 말고 https 로 작성해주자..! (이거 안해서 엄청 시간 많이 씀 ㅠ)

 

 

[배포 방법]

 

1. 필요한 것들 설치 및 추가하기

 

- 리눅스 업데이트 : sudo apt update && sudo apt upgrade -y

- DB 설치 (e.g. MariaDB) : sudo apt install mariadb-server -y

- DB 접속 후 데이터베이스 생성 (아래는 예시)

CREATE DATABASE DB이름 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER '유저명'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON DB이름.* TO '유저명'@'%';
FLUSH PRIVILEGES;

- DB 생성 후 스프링부트 프로젝트에 알맞게 업데이트 (application.properties 에 잘 변경해서 업데이트하기)

- JDK 설치 (나는 스프링부트라 17버전 설치) : sudo apt install openjdk-17-jdk -y

 

등등등...

 

 

2. 리액트 프로젝트 배포

 

1) 리액트 build 후 (yarn run build 혹은 npm run build 명령어 사용),

2) 생성된 build 폴더의 모든 내용물을 서버의 /var/www/html 디렉토리에 업로드.

 

나는 내 로컬 컴퓨터 (맥)에서 빌드하고 그걸 터미널에서 scp 명령어 사용해서 리눅스 서버로 보냈다!

내가 사용한 명령어는 아래와 같음

scp -i ~/Documents/Oracle_cloud_sshkey/main/ssh-key-2024-12-30-main.key -r ~/Documents/Git/smr/build/* ubuntu@140.???.??.???:/var/www/html/

 

 

 

3. Nginx 설정

Nginx를 사용하여 리액트 앱을 서비스하고, 스프링부트 API로 요청을 프록시하겠습니다!

 

1) 우선 Nginx 설치

sudo apt update
sudo apt install nginx

 

2) Nginx 설정하기 (아래 명령어로 파일 들어가서 편집)

sudo vi /etc/nginx/sites-available/원하는 파일명 (자신의 프로젝트 명과 동일하게 하면 알아보기 좋음)

 

3) 다음과 같이 설정 추가!

(자신의 도메인은 각자 준비해서 저기에 넣으면 됨! 나는 도메인은 아래 링크에서 무료로 만들었다!)

https://내도메인.한국/page/member_login_step1.php

 

원하는 도메인 선택해서 고급설정 부분의 IP연결 쪽에 맨 오른쪽에 서버의 public IP 주소를 작성해주면 됨!

 

참고로 도메인 뒷쪽 부분은 .p-e.kr / .o-r.kr / .n-e.kr / .r-e.kr / .kro.kr 중에서택할 수 있는데,

아무래도 가장 깔끔한 .kro.kr 로 다들 선택하는 것 같음..

그래서 ssl 설정할 때 너무 많이 이걸로 요청한다고 자꾸 안되길래, 나도 도메인을 n-e.kr 로 다시 새로 생성했다. 이 점 참고하세요!

참고로 이 도메인이 내 서버 ip 와 잘 연결됐는지 확인하는 법은?!

아래 명령어를 터미널에 쳐보자!

ping 자신의 도메인.kr

 

서버 ip 가 잘 나오고 있으면 잘 연결된 것!


 

어쨌든 이렇게 자신의 도메인 주소를 만들고, 아래처럼 작성해줍시다!

# HTTP 요청을 HTTPS로 리디렉션
server {
    listen 80;
    server_name 자신의도메인.co.kr;

    # HTTP -> HTTPS 리디렉션
    return 301 https://$host$request_uri;
}

# HTTPS 서버 설정
server {
    listen 443 ssl;
    server_name 자신의도메인.co.kr;

    ssl_certificate /etc/letsencrypt/live/자신의도메인.co.kr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/자신의도메인.co.kr/privkey.pem;

    # React 앱 서비스
    location / {
        alias /var/www/html/;
        index index.html;
        try_files $uri /index.html;  # 모든 요청을 index.html로 처리
    }

    # Spring Boot API 경로 처리
    location /api/ {
        proxy_pass http://127.0.0.1:8080/;  # Spring Boot 백엔드 API 주소
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

    # 기타 정적 파일 예외 처리 (favicon.ico, logo 등)
    location ~ ^/(favicon.ico|logo192.png|manifest.json|asset-manifest.json) {
        root /var/www/html;
    }
}

 

 

추가로 포트도 열어줍시다!

Nginx 가 사용하는 포트와 8080, 443 등 필요한 포트를 열어줄게요!

 

방화벽 규칙 확인 및 열기

sudo ufw status

 

  • HTTP: 80
  • HTTPS: 443
  • 스프링부트 API: 8080 (Nginx를 통해 프록시 설정된 경우 필요 없음)
sudo ufw allow 'Nginx Full'
sudo ufw allow 8080
sudo ufw allow 3000 (리액트)
sudo ufw reload

 

 

참고로, 해당 포트들이 오라클 서버에서도 열려있어야 합니다!

오라클 서버 인스턴스 - 서브넷 - 보안목록 - 수신규칙 확인해보시고, 해당 포트가 추가안되어 있다면 추가해주세요!

저는 일단 이정도 열어뒀습니다! (필요없는 것도 있을 수 있음)

 

 

Nginx 상태 확인

sudo nginx -t

 

(결과가 아래처럼 2줄이 나오면 잘된거임)

 

 

Nginx 재시작

sudo systemctl restart nginx

 


참고로 잘 안되면 오라클 인스턴스 재부팅해보세요!

전 재부팅하니까 잘 됐습니다!

 

 

 

5. HTTPS 설정

Let's Encrypt에서 무료 SSL 인증서 발급받기! 이렇게 발급받은 인증서를 Nginx 설정에 자동으로 적용합니다!

 

1) Certbot 설치

sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx

 

2) SSL 인증서 발급

sudo certbot --nginx -d 여러분의 도메인.kr

 

3) PEM 파일을 JKS 형식으로 변환하기

 

Let's Encrypt에서 발급된 인증서는 PEM 형식의 파일들이다! Spring Boot에서는 JKS(Java KeyStore) 또는 PKCS12 형식으로 변환하여 사용해야 한다고 함. 다음 명령어로 PEM 파일을 Java KeyStore(JKS) 형식으로 변환하자

이 명령어는 fullchain.pem(인증서)과 privkey.pem(개인키)을 사용해 keystore.p12라는 키 저장소 파일을 생성한다

sudo openssl pkcs12 -export -in /etc/letsencrypt/live/여러분의도메인.kr/fullchain.pem -inkey /etc/letsencrypt/live/여러분의도메인.kr/privkey.pem -out /etc/letsencrypt/live/여러분의도메인.kr/keystore.p12 -name 원하는닉네임

 

4) 인증서 파일과 폴더 권한 주기

(참고로 난 아무리 해도 잘 안돼서 그냥 온갖 권한을 아래 명령어를 통해 다 풀어줌 저렇게 하니까 됐다)

sudo chmod 644 /etc/letsencrypt/live/여러분의도메인.kr/keystore.p12
sudo chmod 755 /etc/letsencrypt/live/여러분의도메인.kr
sudo chmod +rx /etc/letsencrypt/live/s여러분의도메인.kr/

sudo chown ubuntu:ubuntu /etc/letsencrypt/live/여러분의도메인.kr/keystore.p12
(난 위에 명령어로 아예 해당 사용자(ubuntu라는 이름의 사용자)가 소유자로 권한을 바꿔버림)

 

5) 그 다음 스프링부트 프로젝트 application.properties 파일을 수정하여 HTTPS 연결을 설정해주기!

# HTTPS 설정
server.port=8443
server.ssl.key-store=file:/etc/letsencrypt/live/여러분의도메인.kr/keystore.p12
server.ssl.key-store-password=your0password #여러분의 패스워드
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=설정한닉네임
server.ssl.enabled=true

 


6. 스프링부트 프로젝트 배포

 

스프링부트 프로젝트를 JAR 파일로 build 후, 서버에 업로드하여 실행

 

프로젝트 폴더에서 ./gradlew build 하면 build/libs 폴더 안에 jar 파일이 생깁니다! 

(plain 파일이랑 일반 jar 파일 생기는데 plain 말고 일반 jar 파일 사용하면 됨)

그 파일을 로컬에서 리눅스로 보내면 됨.

(나는 맥 사용 중이라 터미널에서 아래의 scp 명령어로 리눅스로 보냈다!)

scp -i ~/Documents/Oracle_cloud_sshkey/main/ssh-key-2024-12-30-main.key ~/Documents/Git/stockManagement/build/libs/stockManagement-0.0.1-SNAPSHOT.jar ubuntu@140.???.??.???:/home/ubuntu/springboot

 

jar 파일은 아래 명령으로 실행 가능!

java -jar your-springboot-app.jar

 

그러나, SSL 인증서를 저렇게 그냥 java -jar 로 하면 못읽어들이는 것 같아서, 나는 sudo 를 붙여서 jar 파일을 실행했다!

그러니 됐음!

여러분도 sudo 를 붙여서 java -jar 로 실행해보세요!

sudo java -jar your-springboot-app.jar

 

 


 

이렇게 하니 잘 배포됐습니다!

정말 난생 처음 해보는거라 진짜 진땀 흘리면서 힘들게 몇시간동안 해냈네요ㅠ

하다보니 추가로 저의 이 사이트 더 업데이트하고 싶은 서비스들이 많습니다.. ㅎ (로그인 페이지 추가, 회원 관리 페이지 등등)

 

 

어쨌든 일단은 서버에 올린 것 성공한 걸로 행복 ㅎㅎ