NGINX

bunny.log·2023년 3월 22일
2

Nginx 두가지 기능

현재 Nginx가 쓰이는 곳은 두 군데이며 서로 다른 이유로 쓰이고 있다. 하나는 Proxy를 이유로 다른 하나는 Static 파일을 제공해주는 역할을 하고 있다. 우선 어떤식으로 Nginx가 프록시 기능을 해주는지 알아보자.

클라이언트에 요청을 보낼때 정적 파일을 원할때는 Nginx의 설정에 따라 자동적으로 React JS로 보내주며 API 요청일 경우에는 Node Js로 보내준다.

Nginx가 요청을 나눠서 보내주는 기준은
location/로 시작하는지 /api 로 시작하는지에 따라서 나눠준다.
/로 시작하면 ReactJS/api로 시작하면 NodeJS로 보내준다.

요청 URL에 / 이 있느냐 api 가 붙느냐에 따라 React JS 프론트서버로 Node JS 요청이 나뉘도록 되어있다.

Nginx dockerfile

📄 ./default.conf (프론트엔드 로컬에 위치 nginx 설정파일)

upstream frontend {
	#3000번 포트에서 frontend가 돌아가고 있다는 것을 명시해줌.
	server frontend:3000;
}

#5000번 포트에서 frontend가 돌아가고 있다는 것을 명시해줌.
upstream backend {
	server frontend:5000;
}


server{
	#Nginx 서버 포트 80으로 열어 줍니다.
	listen 80;


	#location에는 우선 순위가 있는데 / 그냥 이렇게만 되는 것은 우선 순위가 가장 낮습니다. 그래서 여기서는 /api로 시작하는 것을 먼저 찾고 그게 없다면 / 이렇게 시작되는 것이니 그 요청을 http://frontend로 보내면 된다.
	location / {
		proxy_pass http://frontend
	}

	location /api {
		#/api로 들어오는 요청을 http://backend로 보내줍니다.
		proxy_pass http://backend
	}

	location / socks-node {
		proxy_pass http://frontend;
		proxy_http_version 1.1;

	}
}

//upstream의 frontend, backend는 docker-compose.yml 파일에서

아래와 같이 연관되어 표시된다.

Nginx dockerfile

#Nginx 베이스 이미지 가져오기

FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf

docker-compose.yml

version:3
Frontend:
	build:
		#개발 환경을 위한 Dockerfile이 어디있는지 알려줍니다.
		docker file: Dockerfile.dev
		context: ./frontend
	volumes:
		#코드를 수정 후 다시 이미지를 build하지 않고 수정된 코드가 반영될 수 있게 volume을 이용해 줍니다.
		#노드모듈스는 복사하여 주지 않습니다. 
		#현재 ./frontend 파일을 WORKDIR /app 을 복사하여 줍니다.   
		- /app/node_modules
		- ./frontend:/app
	stdin_open: true
	#리액트 앱을 종료할때 나오는 버그를 잡아줌
   
   nginx:
   
nginx:
	#재시작정책 
	#no : 어떠한 상황에서도 재시작을 하지 않습니다.
	#always : 항상 재시작을 합니다.
	#on-failure 에러코드와 함께 컨테이너가 멈추었을때만 재시작을 합니다.
	#unless-stopped : 개발자가 임의로 멈추려고 할때 빼고는 항상 재시작을 합니다.
	restart: always
	build:
		docker file: Dockerfile.dev
		context: ./nginx
	ports:
    #로컬 3000번에서 컨테이너 80번
		- “3000:80”
    restart: always
    
	build:
		docker file: Dockerfile.dev
		context: ./nginx
	ports:
		- “3000:80”
   backend:
   		build:
		dockerfile: Dockerfile.dev
		context: ./backend
		container_name: app_backend
	volumes:
		- /app/node_modules
	-	./backend:app

   mysql:
   	build: ./mysql
		restart: unless-stopped
		container_name: app_mysql
	ports :
		- “3306:3306”
	volumes:
		- ./mysql/mysql_data:/var/lib/mysql
		- ./mysql/sqls/:/docker-entrypoint-initdb..d/
	environment:
    	#환경변수 Mysql의 Root계정 비밀번호와 Database의 이름을 지정해줍니다. 
		MYSQL_ROOT_PASSWORD: johnahn
		MYSQL_DATABASE: myapp

reverse proxy

Nginx는 오픈 소스 웹 서버 및 리버스 프록시 서버로 널리 사용되는 소프트웨어입니다. 웹 서버로서의 역할뿐만 아니라 리버스 프록시 서버로서도 사용될 수 있습니다.

Next.js 프로덕션 환경에서는 Nginx와 같은 웹 서버를 사용하여 Next.js 애플리케이션을 배포하고 리버스 프록시 서버로 사용하는 것이 일반적입니다.

Nginx를 사용하여 Next.js 애플리케이션을 배포하고 리버스 프록시 서버로 설정하기 위해서는 다음과 같은 단계를 수행해야 합니다.

  1. Next.js 애플리케이션을 빌드합니다. npm run build 명령어를 사용하여 Next.js 애플리케이션을 빌드합니다.

  2. Nginx를 설치하고 설정합니다. Nginx를 설치한 후, Nginx 설정 파일(nginx.conf)을 편집하여 리버스 프록시 설정을 추가합니다.

  3. Nginx의 리버스 프록시 설정에서 Next.js 애플리케이션을 프록시합니다. Nginx 설정 파일의 server 블록 안에 다음과 유사한 내용을 추가합니다.

예를 들어 요청 포트가 443으로 들어주면 https 인증서 요청으로 nginx거쳐서 next서버로 보내주고 80으로 요청이 오면 nginx가 내부적으로 443으로 리다이렉트 해서 보내주는 것이 reverse proxy 이다.

Nginx는 캐싱, 리다이렉트, 정적 파일 제공, HTTPS 등과 관련하여 다양한 기능을 제공합니다. 각각의 기능을 설명해보겠습니다.

  1. 캐싱:
    Nginx는 캐싱 기능을 사용하여 동일한 요청에 대한 응답을 캐시하여 이후 동일한 요청에 대해 원격 서버로부터 데이터를 다시 가져오지 않고 캐시된 응답을 제공합니다. 이는 서버의 성능을 향상시키고 응답 시간을 단축시킵니다. Nginx는 프록시 캐싱을 통해 원격 서버로부터 응답을 가져와 클라이언트에게 전달할 수 있습니다.

  2. 리다이렉트:
    Nginx는 리다이렉트 기능을 사용하여 클라이언트의 요청을 다른 위치로 리다이렉트할 수 있습니다. 예를 들어, http://example.com으로의 요청을 https://example.com으로 리다이렉트할 수 있습니다. 이를 통해 보안 요구사항이나 URL 구조 변경 등을 처리할 수 있습니다.

  3. 정적 파일 제공:
    Nginx는 정적 파일 제공에 특화되어 있습니다. 웹 서버로서 동작하여 클라이언트에게 정적 파일(HTML, CSS, JavaScript, 이미지 등)을 직접 제공할 수 있습니다. 이를 통해 정적 파일의 제공 속도를 향상시킬 수 있고, 웹 애플리케이션 서버에 부하를 줄일 수 있습니다.

  4. HTTPS:
    Nginx는 SSL/TLS 암호화를 지원하여 안전한 통신을 제공합니다. HTTPS 설정을 통해 인증서를 사용하여 클라이언트와 서버 간의 통신을 암호화할 수 있습니다. 이를 통해 보안 요구사항을 충족시키고 사용자의 개인 정보를 보호할 수 있습니다.

이러한 기능들은 Nginx의 설정 파일인 nginx.conf에서 구성됩니다. nginx.conf 파일을 편집하여 원하는 기능을 설정하고, Nginx를 재시작하여 변경사항을 적용할 수 있습니다. Nginx의 설정은 다양한 옵션과 지시어를 사용하여 유연하게 구성할 수 있으며, 이를 통해 다양한 요구사항을 처리할 수 있습니다.

해결

  1. ec2 서버에 nginx를 설치한다
[ubuntu@~:] sudo apt-get install nginx
[ubuntu@~:] vim /etc/nginx/nginx.confg

2.confg 파일중 http에서 리다이렉트 부분을 추가한다.

server {
	server_name nodebird.com;
	listen 80;
	location / {
		proxy_set_header HOST $host;
		proxy_pass http://127.0.0.1:3060;
		proxy_redirect off;
	}
}

위 코드는 nodebird.com에서 80으로 요청이 들어오면 3060으로 보내주는 리다이렉트 코드이다.

80번 포트로 들어오면 hppts로 리다이렉트 되는 구문 예

Certbot 을 설치하면 설트봇에서 아래 구문을 nginx.config에 적어준다.
301은 리다이렉트와 관련이 있다.

server {
	if($host = nodebird.com){
		return 301 https://$host$request_url;
	} # managed by Certbot
	server_name nodebird.com;
	listen 80;
	return 404; # managed by Certbot
}

왜 개발환경 서버와 운영환경 서버가 다른걸까요?

개발 환경에서 localhost:3000으로 정적 파일들에 대한 요청을 보내면 개발서버에서 해당 내용에 대한 정적파일을 응답하며

운영서버에서는 개발서버대신에 NGINX가 정적파일들을 제공해줍니다.

개발에서 사용하는 서버는 소스를 변경하면 자동으로 전체 앱을 다시 빌드해서 변경 소스를 반영해 주는 것 같은 개발 환경에 특화된 기능들이 있고

운영환경에서는 소스를 변경할때 다시 반영해줄 필요가 없어 더 깔끔하고 빠른 Nginx를 웹 서버로 사용합니다.

server{

	listen 3000

	location / {
		#① HTML파일이 위치할 루트설정 
        root /usr/share/nginx/html;

		#② 사이트의 index 페이지로 할 파일명 설정
        index index.html index.htm;
		
        #③ React Router을 사용해서 페이지간 이동을 할때 이 부분이 필요하다.
        try_files $uri $uri/ /index.html;
	}
}

① 3000번 포트로 요청이 "/" 로 들어오면
/usr/share/nginx/html에 빌드된 파일을 올려주면 접속시 빌드된 파일을 확인 할수 있으며 root 파일을 바꿔 줄수도 있다.

② 리액트 public 폴더의 index.html 파일을 index.htm로

React는 Single Page Application 입니다. 그러기에 index.html 하나의 정적 파일만 가지고 있어서 만약 {URL}/home 이렇게 접속을 하려고 할때도 index.html 파일에 접근을 해서 라우팅을 시켜야 하는데 nginx에서는 자동으로 이걸 알수가 없을때에 대안책으로 index.html을 제공하여서 /home으로 라우팅을 시킬수 있게 임의로 설정해주는 것입니다.

참고
https://zionh.tistory.com/182

참고하면 좋은
https://seungdols.tistory.com/862

강의
https://www.inflearn.com/course/lecture?courseSlug=%EB%85%B8%EB%93%9C%EB%B2%84%EB%93%9C-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EB%A6%AC%EB%89%B4%EC%96%BC&unitId=49436&tab=curriculum

챗지피티
https://chat.openai.com/

그외 추천 NGINX redirect
https://velog.io/@gbskang/nginx%EB%A1%9C-https-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%ED%8A%B8%ED%95%98%EA%B8%B0

profile
나를 위한 경험기록

0개의 댓글