안녕하세요, 오늘부턴 본격적으로 웹 서버이자 reverse 프록시 서버로 배치할 nginx을 설치하고 사용법을 익혀보겠습니다.
저는 맥북 유저이며, homebrew를 사용하기에 터미널에 아래와 같이 입력하여 nginx를 설치하겠습니다. homebrew를 사용하지 않으시거나, 윈도우 유저시라면 nginx 웹페이지에 직접 접속하시어 다운받으실 수도 있습니다.
https://nginx.org/en/download.html
어쨌든, 저는 아래와 같이 homebrew를 사용하겠습니다.
brew install nginx
놀랍게도, 이 한 줄이면 설치는 끝났습니다.
이제, 터미널에 아래와 같이 입력해 nginx가 설치된 경로를 확인해주겠습니다.
which nginx
which 뒤에 프로그램 이름을 입력하면, 해당 프로그램의 위치를 확인할 수 있습니다.
아래와 같이 /opt/homebrew/bin/ 경로로 저장이 되어있는 것을 잘 확인할 수 있습니다.
이제, 에디터에서 해당 폴더를 열어보겠습니다.
폴더를 열 때엔, bin이 아닌 etc 경로로 접근해주세요.
bin은 엔진엑스의 실행파일 자체가 설치된 곳이고,
저희는 설정파일을 수정해야 하기에, etc경로로 접근해야 합니다.
엔진엑스를 설치하면 실행파일은 bin, 설정파일은 etc경로로 설치됩니다.
vs code를 사용하신다면, 아래의 extension을 설치해 코드 하이라이팅 기능을 사용하실 수 있습니다.
이제 저희는 nginx.conf 파일을 열어 많은 작업을 이곳에서 하게됩니다.
nginx.conf파일을 열어봅시다.
이렇게 생긴 파일이 잘 나타났다면, 성공입니다.
이제, 이 파일의 내용을 전부 지워주세요.
이제부터 conf파일에 직접 저희만의 웹서버를 구축해보겠습니다.
nginx의 conf파일은 엔진엑스 웹서버의 동작 전반을 관리하는 파일입니다.
크게, 아래와 같이 http와 events블록으로 구성됩니다.
http{}
events{}
nginx에서는 중괄호 블럭 단위를 "context" 라고 부르고,
라인 한 줄을 "directive" 라고 부릅니다.
nginx 웹 서버가 정상적으로 동작하기 위해선,
conf 파일 안에 http context와 events context가 존재해야 합니다.
http context는 서버의 동작 전반(몇 번 포트를 사용할지 등)을 작성하는 공간이고,
events context는 서버의 네트워크 설정을 작성하는 공간입니다.
우선 이번 포스팅에선 http context에 대해 살펴보겠습니다.
http{
server {
listen 8080;
}
}
events{}
먼저, 위와 같이 http 컨텍스트 내부에 서버 컨텍스트를 생성해주었습니다.
앞으로, server context내부에 어떤 url주소에서 어떤 페이지를 띄워줄지 지정해줄 것입니다.
listen은 사용할 포트 번호입니다. 저는 8080번으로 지정해주었으니,
localhost:8080으로 엔진엑스 웹서버에 접속할 수 있습니다.
이제, 8080번 포트에서 실제 웹서버에 접속해봅시다.
이를 위해, 터미널에 다음과 같이 입력하여 nginx서버를 활성화 시켜줍니다.
nginx
이후 8080포트로 접속해보면..
웰컴 사인이 등장합니다.
이 화면이 보인다면, 우리의 엔진엑스는 정상적으로 돌아가고 있다는 의미입니다.
이제, 처음 서버에 접속하면(홈 디렉토리) welcome페이지가 아닌 저희가 만든 html페이지를 렌더링하도록 conf파일을 수정하겠습니다.
연습을 위해 이렇게 html과 css로 구성된 간단한 폴더를 생성해주겠습니다.
지금은 웹 개발 자체를 공부하는 시간이 아니라, nginx를 공부하는 시간이니, html 페이지는 정말 대충 글자만 아무거나 넣어주시면 됩니다.
맨 처음 엔진엑스에 접속하면, 최상단의 index.html파일을 보여주도록 하겠습니다.
해당 index.html파일을 우클릭하여 경로를 복사해줍니다.
이후 conf파일을 아래와 같이 수정합니다.
http{
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx/index.html;
}
}
events{}
root는, 특정 주소로 접근했을 때 렌더링해줄 페이지를 지정해줄 수 있습니다.
nginx.conf파일은, 내용을 수정하면 터미널에 아래와 같은 명령어를 입력하여 변경사항을 적용해주어야 합니다.
nginx -s reload
변경 사항을 저장하여 서버를 새로고침 하라는 명령어입니다.
자, 이제 다시 localhost:8080으로 접속해보면..
의도와 다르게 저희가 만든 index.html이 아닌, 404에러가 발생했습니다.
nginx에서 root나 alias로 경로에 접근하면, 경로에 파일명은 제외하고 폴더까지만 작성해주어야 합니다. root와 alias는 내부적으로 스스로 전달된 경로에서 index.html파일을 찾습니다.
위의 코드에서 root에 전달된 경로에서 index.html을 지워주어야 합니다.
http{
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
}
}
events{}
이렇게 conf파일의 root에서 index.html은 지워줍니다.
항상, conf 파일을 수정하면
nginx -s reload
해주는 것도 잊지 않아야 합니다.
이후 접속하니..
정상적으로 index.html이 8080번 포트의 홈 디렉토리에 렌더링 되는 것을 확인할 수 있습니다.
프로젝트 폴더 구조가 아래와 같다고 가정해봅시다.
/members 경로로 접속하면 members/index.html을, /items 경로로 접속하면 items/index.html파일을 렌더링 하도록 해봅시다.
url의 특정 경로에 따른 웹서버의 동작은, location 키워드를 통해 제어할 수 있습니다.
server context내부에 loaction context를 만들어줍니다.
아래는 결론적으로 잘못된 코드지만, 우선 살펴보겠습니다.
http{
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
location /members {
root /Users/leejinwoo/Desktop/nginx/members/members.html;
}
}
}
events{}
이렇게, location 뒤에 원하는 경로를 적어줍니다.
저는 /members로 하였으니, 해당 블록은 사용자가 localhost:8080/members 라는 url로 접속했을 때 보여줄 파일을 지정해줍니다.
이 코드는 동작하지 않습니다.
이유는, root의 동작원리 때문입니다.
root 키워드는 기본적으로 location에서 쓰일 때 root뒤에 명시된 path의 맨 뒤에 location을 첨가합니다.
제가 적고도 어려우니, 코드로 설명드리겠습니다.
location /members {
root /Users/leejinwoo/Desktop/nginx/members/members.html;
}
위의 경우, /members 페이지에 접속하면 nginx가 전달할 파일의 실제 경로는
/Users/leejinwoo/Desktop/nginx/members/members.html
이 아닌,
/Users/leejinwoo/Desktop/nginx/members/members.html/members
가 됩니다.
차근차근 살펴보면, 우선 members가 두 번 중복됩니다.
root는 기본적으로 지정된 location을 root에 전달된 경로의 맨 마지막에 추가하기에,
/Users/leejinwoo/Desktop/nginx/members/members.html;
을 전달하면,
/Users/leejinwoo/Desktop/nginx/members/members.html/members
의 경로에서 index.html파일을 찾으려 하는 것이죠.
엔진엑스는 기본적으로 전달받은 디렉토리 내에서 index.html파일을 스스로 찾기 때문에, index.html은 경로에서 제외시켜야 했었죠.
그런데, 지금의 경우는 members폴더 내에 index.html파일이 없습니다.
우선, members.html이 index.html이었다 가정하고 경로의 문제를 먼저 해결해보면
http{
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
location /members {
root /Users/leejinwoo/Desktop/nginx;
}
}
}
events{}
이렇게 프로젝트 폴더명까지만 전달해야겠네요.
그럼, 엔진엑스는 아래의 파일을 찾고자 할 것입니다.
/Users/leejinwoo/Desktop/nginx/members/index.html
이제 root가 location을 전달받은 경로 끝에 자동으로 추가한다는 것은 알았는데,
엔진엑스 자체가 index.html파일만을 바라보기에,
index.html이 없는 members 폴더는 별도의 조치가 필요해 보입니다.
별도의 조치가 없다면, index.html이 없는 경로에 대해서는 에러를 내뿜고 끝날테니까요.
아니나 다를까 실제로 members 경로로 이동해보니, members.html파일이 화면에 나오지 못하고 있습니다.
이런 경우, try_files 키워드를 사용해 문제를 해결할 수 있습니다.
아래와 같이 /members 로케이션의 root directive밑에, try_files directive를 추가해주겠습니다.
http{
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
location /members {
root /Users/leejinwoo/Desktop/nginx;
try_files members/members.html /index.html = 404;
}
}
}
events{}
/members/index.html파일을 엔진엑스 컴파일러가 찾지 못하면,
컴파일러는 try_files에 띄워쓰기로 구분된 파일들을 차례로 확인합니다.
파일의 이름이 index.html이 아닌 경우에 사용해줍니다.
저의 경우엔 members/members.html
/index.html
=404
이렇게 세 개의 부분으로 나누어 적어주었는데요.
컴파일러는 가장 먼저 members/members.html
파일을 확인합니다.
해당 파일이 존재하면 해당 파일을 렌더링하고,
존재하지 않는다면 다음 파일인 /index.html
을 찾습니다. 이는 루트 디렉토리의 index.html파일의 경로네요.
마지막은 두 파일 모두 컴파일러가 발견하지 못한 경우 404에러를 리턴하도록 하였습니다.
엔진엑스 프로젝트를 위해 해주어야 할 중요한 한 가지 설정이 더 있습니다.
바로,
include mime.types;
명령어를 conf파일의 http 컨텍스트에 추가해주는 것인데요.
우선 수정된 코드는 아래와 같습니다.
http{
include mime.types;
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
location /members {
root /Users/leejinwoo/Desktop/nginx;
try_files members/members.html /index.html = 404;
}
}
}
events{}
mime.types란 무엇이고, 이 명령어는 왜 해주어야 하는 것일까요?
우선, mime.types는 nginx에서 기본으로 제공되는 파일로서, 아래와 같이 생겼는데요,
이는 엔진엑스가 여러 형태의 파일을 파일 고유의 형태로 잘 이해할 수 있도록 정리해둔 파일입니다.
이를 conf파일에 include시켜줌으로써 엔진엑스는 다양한 확장자의 파일을 정확하게 해석하고 사용할 수 있게 됩니다.
조금 더 원리를 파고 들어보면,
엔진엑스는 기본적으로 데이터를 MIME타입으로 주고받습니다.
마임은 Multipurpose Internet Mail Extensions의 줄임말로, http통신 상에서 서버가 각종 컨텐츠의 확장자를 지정하는 고유의 방식입니다.
예를 들어, .html은 text/html 형태로 기억합니다.
앞서 root는 전달받은 경로의 끝에 location을 자체적으로 append한다는 것을 확인하였습니다.
만일 이것이 불편하다면, root와 달리 location을 첨부하지 않는 alias를 root대신 사용할 수 있습니다.
http{
include mime.types;
server {
listen 8080;
root /Users/leejinwoo/Desktop/nginx;
location /members {
root /Users/leejinwoo/Desktop/nginx;
try_files /members.html /index.html = 404;
}
}
}
events{}
위와 같이 root로 작성된 /members 컨텍스트의 내부를 alias로 바꿔보겠습니다.
주석 처리된 기존의 부분은 아래와 같이 바뀔 수 있습니다.
차이점에 주목해보면, 마지막에 members폴더명까지를 작성해주었네요.
이는 alias는 root와 달리 location을 경로 맨 뒤에 자체적으로 추가하지 않기 때문입니다.
이상으로 오늘은 nginx를 설치하고, context와 directive의 개념 및 conf파일에 여러 코드들을 작성해보았습니다.
다음 포스팅에서도 계속하여 conf파일에 우리의 웹 서버 구축을 위한 작업을 이어 나가겠습니다.
감사합니다.