궁금한 점
- Next.js로 웹 개발을 하고있는데 나는 NGINX를 사용하고 있는걸까...구성을 내가하지않아서 쓰고있는건지 아닌지도 모르겠다.
- NGINX는 웹 서버라고 알고있지.. 언제 쓰는걸까... 도커로 Next.js를 서버를 실행할 때 꼭 써야하는건가?..
1. NGINX란
Nginx는 오픈 소스 웹 서버 소프트웨어로, 주로 HTTP 및 리버스 프록시 서버로 사용됩니다. 또한, 이메일 프록시(IMAP, POP3, SMTP)와 로드 밸런서로도 동작할 수 있습니다.
Next.js와 Nginx는 함께 사용하기에 좋은 조합입니다. Nginx는 Next.js 애플리케이션의 프론트엔드 및 백엔드 요청을 효율적으로 처리하고, 성능과 보안을 향상시키는데 도움을 줍니다. Next.js와 Nginx를 통합하는 일반적인 방법과 이유는 다음과 같습니다.
Next.js와 Nginx를 통합하는 일반적인 방법과 이유는 다음과 같습니다.
1. 리버스 프록시로 Nginx 사용
Nginx를 리버스 프록시로 설정하여 클라이언트 요청을 Next.js 애플리케이션(주로 Node.js 서버)으로 전달할 수 있습니다. 이렇게 하면 Next.js 서버가 외부와 직접 통신하지 않고 Nginx가 중간에서 요청을 관리합니다.
2. 정적 파일 캐싱
Nginx는 정적 파일(이미지, CSS, JS 등)을 효율적으로 제공할 수 있지만, Nginx의 캐싱 기능을 활용하면 더 빠르게 제공할 수 있습니다. 특히 next export로 생성된 정적 사이트를 배포할 때 유용합니다.
3. 로드 밸런싱
대규모 트래픽을 처리하려면 Nginx를 사용해 여러 Next.js 서버에 로드를 분산할 수 있습니다.
4. SSL/TSL
Nginx에서 HTTPS를 설정해 Next.js 앱을 더 안전하게 배포할 수 있습니다.
2. Next.js 프로젝트와 Nginx를 연동하는 방법
1. Next.js 프로젝트 빌드
먼저 Next.js 애플리케이션을 프로덕션 모드로 빌드합니다.
Next.js 애플리케이션이 Node.js 기반으로 동작하기 때문에, 내부적으로 Node.js 서버가 실행되는 것입니다.
npm run build # Next.js를 프로덕션 빌드로 준비
npm start # 프로덕션 서버 실행(기본적으로 포트 3000)
2. Nginx 설치
Windows용 Nginx를 설치합니다.
Nginx 다운로드 및 설치:
- Nginx 공식 사이트에서 Windows용 Nginx를 다운로드합니다.
- 다운로드한 ZIP 파일을 원하는 디렉토리에 압축 해제합니다. 예를 들어, C:\nginx.
Nginx 실행:
1. nginx.exe를 실행하여 Nginx 서버를 시작합니다.
cd C:\nginx
nginx.exe
2. Nginx가 실행 중인지 확인하려면 브라우저에서 http://localhost에 접속합니다. 기본 페이지가 표시되면 정상 실행 중입니다.
3. Nginx 설정
Nginx를 Next.js와 연동하려면 설정 파일을 수정해야 합니다.
설정 파일 위치:
- 기본 설정 파일은 C:\nginx\conf\nginx.conf에 있습니다.
- 이 파일을 텍스트 편집기(예: 메모장 또는 VS Code)로 엽니다.
설정 파일 수정:
Next.js 서버와 Nginx를 연동하는 리버스 프록시 설정을 추가합니다. 다음은 기본 설정 예시입니다:
리버스 프록시는 클라이언트의 요청을 받아 백엔드 서버로 전달하고, 백엔드 서버의 응답을 다시 클라이언트에 반환하는 중간 서버를 의미합니다.
주요 역할
- 클라이언트가 백엔드에 직접 연결하지 않도록 보호(보안 강화)
- 여러 서버에 요청을 분산 처리 (로드 밸런싱)
- 정적 파일 제공 및 캐싱으로 응답 속도 향상
- SSL/TLS 암호화 처리 등
http { # HTTP 관련 설정을 정의하는 블록
include mime.types; # MIME 타입(파일 형식)
default_type application/octet-stream; # MIME 타입을 알 수 없는 파일의 기본 타입을 설정
sendfile on; # 파일 전송 최적화
keepalive_timeout 65; # 클라이언트와 서버 간의 유효 연결을 유지하는 시간(초)
server { # 클라이언트 요청을 처리하기 위한 개별 서버 설정을 정의
listen 80; # 서버가 포트 80(HTTP)에서 요청을 수신하도록 설정
server_name localhost; # 이 서버가 처리할 요청의 도메인 이름
# 리버스 프록시 설정
location / { # 모든 요청(루트 경로 포함)을 처리하도록 설정
proxy_pass http://localhost:3000; # Nginx가 받은 요청을 http://localhost:3000로 전달
proxy_http_version 1.1; # 프록시 서버가 클라이언트와 백엔드 서버 간에 사용할 HTTP 버전을 지정
proxy_set_header Upgrade $http_upgrade; # 클라이언트 요청에서 Upgrade 헤더를 벡엔드 서버로 전달
proxy_set_header Connection 'upgrade'; # Connection 헤더를 upgrade로 설정하여 업그레이드된 연결을 지원
proxy_set_header Host $host; # 요청의 Host 헤더를 원본 요청에서 사용한 호스트 이름으로 설정
proxy_cache_bypass $http_upgrade;
}
# 정적 파일 캐싱 (선택 사항)
location /_next/static/ { # Next.js의 정적 파일 요청을 처리합니다.
root C:/path/to/your/nextjs-project/.next/; # 정적 파일이 저장된 디렉토리의 경로를 지정합니다.
expires 1y; # 캐싱 만료 기간을 1년으로 설정합니다.
add_header Cache-Control "public, immutable";
}
}
}
설정 파일 저장 후 Nginx 재시작:
- 설정 파일을 저장합니다.
- Nginx를 재시작합니다:
nginx.exe -s reload
4. Next.js와 Nginx 연동 확인
- 브라우저에서 http://localhost로 접속합니다.
- Next.js 애플리케이션이 표시되면 Nginx와 Next.js가 정상적으로 연동된 것입니다.
5. SSL/TLS 설정 (선택 사항)
로컬 개발 환경에서는 HTTPS가 필요하지 않을 수 있지만, 프로덕션 환경에서는 HTTPS 설정이 필수입니다.
로컬 환경에서 HTTPS 설정 (Self-Signed Certificate):
1. OpenSSL로 SSL 인증서를 생성합니다.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout selfsigned.key -out selfsigned.crt
2. Nginx 설정 파일에 SSL 설정을 추가합니다:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate C:/nginx/conf/selfsigned.crt;
ssl_certificate_key C:/nginx/conf/selfsigned.key;
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;
}
}
3. Nginx를 재시작하고, 브라우저에서 https://localhost로 접속합니다.
6. 전체적인 동작
- 브라우저가 Nginx로 요청을 보냅니다.
- Nginx는 요청에 따라:
- /로 시작하면 Next.js 서버로 요청을 전달합니다.
- /_next/static/로 시작하면 정적 파일 디렉토리에서 직접 파일을 제공합니다.
- Nginx는 성능 최적화를 위해 캐싱 및 헤더 설정을 적용합니다.
Next.js 프로젝트를 Docker를 통해 실행하려면 Docker 이미지를 빌드하고 컨테이너를 실행하는 과정을 거쳐야 합니다. 아래는 Next.js를 Docker로 실행하기 위한 단계별 가이드입니다.
3. Next.js 프로젝트를 Docker환경에서 실행시키는 방법
1. Dockerfile 작성
Next.js 애플리케이션을 실행하기 위한 Dockerfile을 프로젝트 루트 디렉토리에 작성합니다.
# Node.js 베이스 이미지 사용
FROM node:18-alpine
# 작업 디렉토리 생성
WORKDIR /app
# package.json과 package-lock.json 복사
COPY package*.json ./
# 종속성 설치
RUN npm install
# Next.js 애플리케이션 코드를 복사
COPY . .
# Next.js 빌드
RUN npm run build
# 애플리케이션 실행 Next.js 기본 포트: 3000
EXPOSE 3000
CMP ["npm", "start"]
2. Docker 이미지 빌드
Dockerfile이 작성되었으면 Docker 이미지를 빌드합니다.
docker build -t nextjs-app .
- -t nextjs-app: 이미지를 next-app이라는 이름으로 태그합니다.
- .: 현재 디렉토리를 빌드 컨텍스트로 사용합니다.
3. Docker 컨테이너 실행
빌드된 이미지를 사용해 컨테이너를 실행합니다.
docker run -p 3000:3000 nextjs-app
- -p 3000:3000: 로컬 머신의 포트 3000과 컨테이너의 포트 3000을 매핑합니다.
- nextjs-app: 실행할 Docker 이미지 파일
4. Docker Compose를 사용하여 실행 (선택 사항)
더 복잡한 설정(예: 데이터베이스 등)이나 편리한 실행 관리를 위해 Docker Compose를 사용할 수 있습니다.
1) docker-compose.yml 파일 작성
version: "3.8"
services:
nextjs-app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
command: npm start
2) Docker Compose 실행
docker-compose up
5. Next.js 실행 확인
브라우저에서 http://localhost:3000으로 접속하여 Next.js 애플리케이션이 실행되고 있는지 확인합니다.
4. Next.js와 함께 사용되는 애플리케이션과 기술 스택
1. 웹 서버 및 리버스 프록시
- Nginx
- 리버스 프록시 역할(요청을 Next.js 서버로 전달)
- 정적 파일 캐싱, HTTPS 처리, 로드 밸런싱
- Apache
- Nginx와 유사하게 정적 파일 제공 및 리버스 프록시로 활용 가능
- Caddy
- HTTPS 설정이 간편한 대안 웹 서버
2. 컨테이너화 및 오케스트레이션
Next.js 애플리케이션을 컨테이너로 패키징하거나 여러 서버를 관리할 때 사용됩니다.
- Docker
- Next.js 애플리케이션을 컨테이너로 실행
- 환경 독립성과 배포 용이성을 제공
- Kubernetes(K8s):
- 대규모 배포 및 컨테이너 오케스트레이션
- 로드 밸런싱, 스케일링 자동화
3. 클라우드 배포 플랫폼
Next.js 애플리케이션을 클라우드에 배포하는데 사용됩니다.
- Vercel
- Next.js의 공식 배포 플랫폼으로, 가장 간편한 배포 방법
- 서버리스 기능과 정적 사이트 배포 지원
- Netlify
- Jamstack 아키텍처를 지원하는 플랫폼
- 정적 파일 및 서버리스 API 배포 가능
- AWS(Amazon Web Services)
- EC2 인스턴스, S3(정적 파일), Lambda(서버리스)와 연계
- Google Cloud
- Compute Engine(가상 머신), Cloud Run(컨테이너), Firebase(호스팅)
- Azure
- Azure App Service를 통해 Next.js 배포 가능
4. 데이터 베이스
Next.js API 라우트에서 데이터를 처리할 때 사용됩니다.
- PostgreSQL
- 관계형 데이터베이스로, 복잡한 쿼리에 적합
- MySQL
- PostgreSQL과 유사하며, 대중적인 관계형 데이터베이스
- MongoDB
- NoSQL 데이터베이스로, 비정형 데이터에 적합
- Redis
- 캐싱 및 세션 관리에 주로 사용
- Firebase Realtime Database 또는 Firestrore
- 실시간 데이터 동기화가 필요한 경우 사용
5. CI/CD 도구
- GitHub Actions
- Next.js 애프릴케이션 빌드 및 테스트 자동화
- GitLab CI/CD
- 코드 변경 시 Next.js 빌드 및 배포 실행
- Jenkins
- 복잡한 CI/CD 워크플로를 구성할 때 유용
- CircleCI
- GitHub 및 Bitbucket과 쉽게 통합 가능
결론
1) 나는 그동안 npx create-next-app@latest를 실행하면 구성되는 Next.js 프로젝트를
npm run dev또는 npm run start를 해서 서버를 실행시키면 http://localhost:3000으로 접속할 수 있는데 이게 nginx를 통해서 이루어지는거라고 막연하게 생각했다. 프론트엔드 개발을 할때마다 nginx를 너무 많이 들어서와서 내가 모르는 내부 구성에서 nginx를 사용할거라고 생각했다.
→ 틀렸다. next.js 서버 실행과 nginx는 상관없다.
2) Docker 컨테이너 환경에서 Next.js 서버를 실행시키기 위해서는 Nginx를 사용해야하는 줄 알았다
→ 틀렸다. Nginx 없이도 Docker 컨테이너에서 Next.js를 실행시킬 수 있다. Nginx는 단지 선택사항일 뿐이었다...
Nginx가 없다면 Next.js는 Node.js 기반의 내장 서버를 이용해 클라이언트 요청을 직접 처리할 수 있다.