리액트 도커로 말아서 배포하기

tein·2022년 8월 26일

jamtomer

목록 보기
2/5

열심히 만든 백엔드 코드와 프론트 분들이 만들어주신 코드를
같은 도커 네트워크에 올려보고 싶어서 시도해봄


AWS EC2

웹서버 설치
: nginx 이미지를 사용해 웹서버 도커를 만든다.
$] docker pull nginx

리액트를 빌드하기 위해 노드를 설치한다.
(빌드 해서 배포해야 도커파일에서 배포할 수 있다)
$] curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

nvm 활성화 한다
$] . ~/.nvm/nvm.sh

노드 최신 버전 설치 한다
$] nvm install --lts

노드 설치되고 실행되는지 테스트
$] node -e "console.log('Running Node.js ' + process.version)"

플젝 코드가 있는 폴더로 이동해서 리액트 빌드 한다.
$] npm run build

내가 가진 aws서버는 ec2 프리티어라 사양이 낮아 리액트를 빌드하지 못한다.
그래서 로컬에서 빌드하고, 빌드된 파일을 aws로 옮겨 사용하기로 했다.


local

로컬에서 노드 설치한다.

$] npm update
$] npm install -g react-scripts
$] npm install -g typescript
$] npm link typescript
# 안되면 
$] npm install --legacy-peer-deps
# 하고
$] npm run build

이제 빌드된 파일들을 aws로 옮긴다.
프로젝트가 있는 폴더를 보면 build라는 폴더가 만들어져 있는데, 이 build를 통째로 옮기면 된다.


AWS EC2

/apps/ 에 도커 파일을 만들고 아래와 같이 작성한다.

$] vi Dockerfile
FROM nginx
COPY 프로젝트이름/build /usr/share/nginx/html

이제 저 도커 파일을 이미지로 빌드 한다.

# 나는 이미지 이름을 `mtmfe`로 설정했다.
$] docker build -t mtmfe .

이미지를 실행시키기 전에, 도커 네트워크를 만들어 준다.

$] docker network create mtmnet

백엔드 코드와 디비를 모두 같은 네트워크에 둘 것이므로,
이 둘도 같은 네트워크에 올린다.

# -p 출력코드:입력코드
# 백엔드 도커의 출력 포트는 80이고, 프론트의 env에 설정된 포트는 80이다.

# mariadb
$] docker run --name mariadb --network mtmnet -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=패스워드입력 mariadb

# backend
$] sudo docker run -it --rm --network mtmnet -d -p 80:8000 --name mtm mtm

# frontend
$] sudo docker run -it --rm --network mtmnet -d -p 8080:80 --name mtmfe mtmfe

포트 번호는 aws 보안설정에서 열어둔 포트대로 이용했다.
백엔드는 yml 설정에서 port를 8000을 사용하도록 했고
프론트는 .env에서 기본 포트를 80으로 맞춰줬다.

백엔드에서 설정한 db접속 정보대로 db에 접속하기 위해 db user정보도 세팅해뒀다.

# yml 파일 일부
# 들여쓰기에 주의한다.

# 공백 없음
spring:
  # 공백 2칸
  datasource:
    # 공백 4칸
    # jdbc:mariadb <- 여기서 mariadb는 db를 실행시키고 있는 도커 컨테이너 이름이다.
    url: jdbc:mariadb://localhost:3306/DATABASENAME
    driver-class-name: org.mariadb.jdbc.Driver
    username: USERNAME
    password: USERPASSWORD

DB 도커에 접속한다.

$] docker exec -it mariadb /bin/bash

이후는 mariadb 사용 방법과 같다.

-- maria db 설정
-- DATABASENAME : 데이터베이스 이름
-- USERNAME : yml 파일에서 접속할 user
-- USERPASSWORD : yml 파일에 적힌 password
create database DATABASENAME;
create user 'USERNAME'@'%' identified by 'USERPASSWORD';

grant all privileges on DATABASENAME.* to 'USERNAME'@'%';
flush privileges;

로컬에서 ec2서버의 public IP로 접속해보니 잘 되는 것을 확인할 수 있었다.

백엔드 로그를 확인하려면

$] docker logs mtm -f

를 입력한다.


여기까지 꽤 삽질을 많이 했는데, 어떤 부분이 문제였는지도 적어둔다.

  1. 리액트를 빌드할 때 .env 파일을 빼먹고 빌드함 -> 404 error
  2. .env 파일을 추가 후 재시도하였지만 .env파일에서 http가 아닌 https를 쓰고 있었음 -> 404 error
  3. 스프링 부트에서 cors 설정이 다른 url만 허용하고 있었음 -> cors error
    1) 이 부분은 아직 명쾌하게 해결하지 못하였고, 로그인 유지가 안되고 있다.
    2) 임시로 각 컨트롤러마다 @CrossOrigin("*") 을 붙여줘서 페이지는 띄우게 해주었다.
    3) 궁극적인 해결은 config.WebConfig에서 allowedOrigins()를 제대로 설정해야한다.
    4) 이 부분에서 allowedOrigins() 에 들어갈 url은 어떤 url이 되어야 하는가?

아직 3.4)를 해결하지 못했다.
이 부분은 보안쪽을 더 깊게 파보면서 해결해야겠다.

추가로, 로컬에서 리액트를 실행시켜 백엔드로 데이터를 요청할 때는 로그인 유지도 잘 되고 모든게 잘 굴러간다.
이걸 보면 3.1)의 문제는 스프링부트 쪽 문제가 아니라 리액트쪽이 잘못된 것 같다는 생각이 얼핏 든다.
다음번엔 3.2)에서 해뒀던 임시방편을 싹 지우고 로컬에서 실행한 리액트로 시도해보고 어느쪽 문제인지 자세히 살펴봐야겠다.

profile
내 시행착오 모음집

0개의 댓글