본문 바로가기

Web Development/Back-end

[WEB] MERN STACK APP 배포

1. Client 배포

 

A. EC2를 가동한다.

 

B. 보안규칙을 다음과 같이 설정한다.

80= Internet

22= SSH Key

3000= React

443= HTTPS

React Client 보안규칙

 

C. EC2 기본 셋팅 및 Nginx 설치

#APT-GET UPDATE
sudo apt-get update

#Install Nginx
sudo apt-get install nginx

#Install Nginx in Amazon Linux
sudo amazon-linux-extras install -y nginx1

#NGINX 명령어
sudo service nginx start
sudo service nginx stop
sudo service nginx reload
sudo service nginx status

 

D. nginx 설정

nginx.conf (/etc/nginx/nginx.conf)

user ubuntu;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    client_body_buffer_size 100k;
    client_header_buffer_size 1k;
    client_max_body_size 100k;
    large_client_header_buffers 2 1k;
    client_body_timeout 10;
    client_header_timeout 10;
    keepalive_timeout 5 5;
    send_timeout 10;
    server_tokens off;
    #gzip  on; on;

    include /etc/nginx/conf.d/*.conf;
}

default.conf(/etc/nginx/conf.d/default.conf)

server {
    #listen       80;
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name  yourdomain.com;

    access_log /home/ubuntu/client/server_logs/host.access.log main;

    location / {
        root   /home/ubuntu/client/deploy;
        index  index.html index.htm;
        try_files $uri /index.html;
        add_header X-Frame-Options SAMEORIGIN;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1; mode=block";
        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    server_tokens off;

    location ~ /\.ht {
        deny  all;
    }

}

 


가비아에서 구매한 도메인을 Route53에 적용하는 방법

 

HTTPS로 확장시 (도메인이 필수로 필요하다), 아래는 가비아에서 구매한 도메인을 적용한다. (Route53에서 바로 구매도 가능)

 

 

A. Route53에서 새로운 "호스팅영역"만들기

B. NameServer 목록을 가비아 설정에 등록하기

AWS Route53화면 빨간 표 쳐진 곳 내용을 가비아에 입력해야함

C. Route53에서 새로운 RecordSet 만들기

 

 

 

HTTPS 적용방법 (letsEncrypt)

# Certbot 설치
sudo snap install certbot --classic

# Certbot nginx에 적용 (다음 설정을 마치면, 기본적인 nginx 설정이 자동 변환된다)
sudo certbot --nginx

# nignx reload 할 것.
sudo service nginx reload

 

 

기타 참고 명령어

#점유 포트 확인
losf -i :80

#피드 죽이기
kill -9 (PID NUMBER)

 


2. Server 배포

 

A. 아래 디펜던시 설치

# APT-GET UPDATE
sudo apt-get update

# Install Nginx
sudo apt-get install nginx

# Install Nodejs
sudo apt-get install nodejs

# Install NPM
sudo apt-get install npm

# Install PM2
sudo npm install pm2@latest -g

 

B. 폴더 삽입

EC2 폴더구조

C. .env처리

# 아래 코드 삽입으로 절대경로로 변경
const path = require('path'); 
require('dotenv').config({ path: path.join(__dirname, '.env') });

 

D. con.d -> default.conf 생성 후, 아래 내용 복붙 (server : 5000번포트 사용시)

server {
        server_name (도메인);
        charset utf-8;

        location / {
                proxy_pass http://127.0.0.1:5000;
        }
        client_max_body_size 0;
}

 

E. Certbot 적용

# Certbot 설치
sudo snap install certbot --classic

# Certbot nginx에 적용 (다음 설정을 마치면, 기본적인 nginx 설정이 자동 변환된다)
sudo certbot --nginx

# Certbot nginx에 적용 다중 도메인
sudo certbot --nginx -d example.co.kr -d www.example.co.kr

 

F. 서브도메인 추가하기

       

    - Route53 추가하기 (레코드 유형 = CNAME , 값 = 원 Domain주소)

 

 

 

    - sudo certbot --nginx 명령어로 서브 도메인도 적용해준다.

 

 

 


배포 후, 접했던 문제들에 대하여..

 

1.  환경변수 문제

    -> .env파일을 package.json과 같은 최상위 경로에 생성해서 내용을 삽입해준 뒤, 실행 시, package.json과 같은 경로에서 실행하는 것으로 해결 가능하다.

 

 

 

 

2. 쿠키 전송문제

    -> https환경에서 쿠키전송은 기본적으로 잘 안된다. 쿠키를 전송하려고 하면, https환경에서는 쿠키의 신용을 허가해줘야 가능하다.

 

 

 

ServerSide (Express)

 

Server의 nginx의 conf.d/default.conf에 "proxy_set_header X-Forwarded-Proto $scheme;" 추가 작성 후, nginx reload.

location / {
	proxy_pass http://127.0.0.1:5000;
	proxy_set_header X-Forwarded-Proto $scheme;
}

 

Express Code 기준 다음과 같은 설정이 추가되었다.

 

 

 

 

ClientSide (React)

 

Client Side에서는, "add_header 'Access-Control-Allow-Credentials' 'true';" 를 추가해준 뒤,

location / {
	root   /home/ubuntu/client/deploy;
	index  index.html index.htm;
	try_files $uri /index.html;
	add_header 'Access-Control-Allow-Credentials' 'true';
	add_header X-Frame-Options SAMEORIGIN;
	add_header X-Content-Type-Options nosniff;
	add_header X-XSS-Protection "1; mode=block";
	add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
    }

 

모든 Cookie 송수신 관련 API에는 axios 또는 fetch에 {withcredentials : true} 옵션을 삽입해준 뒤, 쿠키를 전송하면 정상적으로 전송된다. (미들웨어에서 cookie를 가져와서 하는 최종 컨트롤러에도 모두 밖아야 정상 동작한다.)

 

**단, "Access-Control-Allow-Origin'에 특정 Origin 주소가 포함되어있어야 한다. 만약, "*"를 사용해 모든 오리진을 허용했다면, "Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 라는 에러를 만날 것이다 🤡

 

withcredential 옵션 삽입화면

 

 

이후, 재시도 해보면 cookie가 정상적으로 전송되고, 수신되어짐을 확인할 수 있다.