nextjs 프로젝트를 ec2에 배포하였고 nginx를 웹 서버로 사용하였다.
여러 페이지를 구성하였고 이미지 파일들을 프로젝트 최상단 public 디렉터리에 생성하여 관리하였다.
로컬에서는 페이지들이 잘 나타났는데 배포 후 확인해보면 왠걸 메인페이지를 제외한 페이지는 다음과 같이 nginx에서 404 처리를 해버리고 메인에서 이미지 또한 나오지 않았다.
문제가 발생했던 이유는 Nginx 설정에서 try_files $uri $uri/ =404; 지시어가 모든 요청을 Nginx에서 처리하려고 했기 때문이다.
기존 nginx 설정을 확인해보면
ec2 인스턴스에서 vim을 통해 확인할 수 있다.
sudo vi /etc/nginx/sites-available/default
nginx 설정
...
location / {
proxy_pass http://localhost:3000;
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;
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
..
try_files $uri $uri/ =404;
위 명령어를 살펴보자.
try_files $uri $uri/ =404;는 Nginx에게 먼저 파일 시스템에서 요청된 파일이나 디렉터리를 찾도록 지시하고, 파일이나 디렉터리가 없으면 404 오류를 반환한다. 이 설정은 정적 웹사이트에서 유용할 수 있다. 하지만 Next.js는 서버사이드 렌더링(SSR)을 통해 동적으로 페이지를 생성하는 애플리케이션이므로, 실제 파일 시스템에서 파일을 찾는 방식은 적절하지 않다고 한다.
서버사이드 렌더링(SSR)을 사용하는 Next.js는 요청에 따라 서버에서 페이지를 동적으로 렌더링한다. 즉, URL에 해당하는 파일이나 디렉터리가 없더라도 Next.js 서버는 해당 URL에 대해 페이지를 생성해 응답할 수 있다. 하지만 try_files는 Nginx가 파일이나 디렉터리를 찾지 못할 경우 바로 404 오류를 반환했기 때문에 Next.js 서버가 요청을 처리할 기회를 얻지 못한다.
try_files $uri $uri/ =404;
nginx 설정에서 위 명령어를 제거하고 반영하니 올바르게 잘 처리되었다.
nginx 설정
...
location / {
proxy_pass http://localhost:3000;
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;
}
..
try_files를 제거한 후에는 Nginx가 요청된 파일을 찾지 않고, 모든 요청을 Next.js 서버로 전달하게 된다. 이렇게 되면 Next.js가 SSR을 통해 동적으로 페이지를 생성하고 사용자에게 응답할 수 있다. 즉, 이제 Nginx는 단순히 프록시 역할을 하며, 모든 라우팅 로직은 Next.js 서버가 처리하게 된다.
Next.js의 SSR에서는 모든 요청을 Node.js 서버로 넘겨 동적으로 페이지를 생성해야 하므로, try_files는 적합하지 않았던 것이다.
이제 메인 페이지에서 이미지도 잘 나오고 모든 페이지들이 잘 나오는 것을 확인할 수 있다.