Nginx 간단 설명
- 수문장과 같은 역할로 OS의 방화벽이 1차 보호를 한다면, 그 다음으로 요청을 먼저 받아볼 수 있는 역할을 하는 웹 서버이다.
- 제일 먼저 요청을 받아 보기 때문에 해당 요청으로 여러가지 설정이 가능한데 proxy_pass의 경우 이 요청을 보고 분석하여 내가 원하는 곳으로 보내주는 것이다. 그리고 보안 설정, 요청 분산 등의 처리도 가능하다 이를 각각 Blacklist IP, Load Balancing이라고 한다.
- Blacklist IP
Blacklist IP의 경우 외부 IP를 블랙리스트로 등록하여 접근을 막는 것으로 예를 들면 중국이나 러시아에서 들어오는 위험한 IP나 해외 IP등의 접근을 막는 것이다. - Load Balancing
Load Balancing의 경우 요청을 여러 대의 서버로 나누어 처리하는 것을 의미하며 단일 CPU라면 프로세스를 쪼개서 각 요청을 처리할 수 있고 CPU가 여러개라면 해당 요청을 분기시켜 n*100% 이상의 성능 향상도 기대할 수 있다고 한다.
Nginx Docker 배포 시 문제점

이 그림은 Django로 플젝할 때 이해하려고 그렸던 건데 크게 아래와 같은 흐름이다.
- 1차로 방화벽이 요청을 거른다.
- Nginx가 요청을 거른다. → 특정 도메인의 경우 모두 Nginx가 먼저 받아볼 수 있게 한다.
- Nginx에서 해당 요청에 대한 필요한 처리를 한다.
- 위에서 언급한 Blacklist, Load Balancing 등
- 헤더 세팅 및 ssl 인증서 적용
- proxy_pass → 현재 Nginx는 서버 자체에 설치되어 전역적으로 영향을 미치고 도커 서버에 대해 접근할 때 localhost로 접근할 수 있다.
- 각 도커 서버에 필요한 처리를 모두 한 후 응답한다.
하지만 내가 처음에 Docker는 각자의 공간인 컨테이너에서 실행되고 버전 관리나 다른 프로그램들에 영향도 미치지 않고 그런 장점들만 보여서 Nginx도 Docker로 실행했다. 이게 문제의 시작이었다.
Nginx를 도커로 실행해도 Nginx가 특정 도메인에 대한 처리는 똑같이 할 수 있다.
나는 https 설정을 하고 각각의 도커 서버에 proxy_pass를 설정했다.
우선 이렇게 하니 proxy_pass 설정에서 localhost로 접근이 불가능 했다. 이유는 각 도커 이미지마다 다르게 IP가 배정이 되고, Nginx도 도커로 실행했기 때문에 다른 도커 서버에 localhost로 접근하지 못했다.
이를 해결하기 위해 각 도커의 IP로 proxy_pass를 설정했지만 이는 IP가 노출되니 좋은 방법이 아니라고 했다.
그래서 proxy_pass로 해당 도메인 주소를 사용했는데 나는 localhost가 안되니 그럼 도메인으로 요청 보내면 잘 찾아가겠다고 생각을 하여 http://domain:port/api/v1 과 같은 형태로 proxy_pass를 설정했다.
이 과정에서 mixed contents에러가 발생했고, 이 에러는 React에서 받은 page가 https환경이고, 이 환경에서 http에 요청을 보내서 발생한 것이다.
당시 나는 이 에러를 보고 proxy_pass 설정을 했는데 왜 이런 에러가 나는지 이해하지 못했고 오랜 시간 이 문제를 해결하기 위해 애쓴 결과 아래의 그림과 같이 요청이 흘러감을 알게 되었다.

처음 페이지를 받았을 때, https의 환경일 것이고 서비스 사용을 하면서 Django서버에 요청을 보낸다.
그럼 https환경에서 보낸 요청이 도커 환경의 Nginx가 proxy_pass로 요청을 보내는데, 이때 Nginx가 도커 환경에서 실행되고 있기 때문에 해당 요청이 도커 외부로 나갔다가 외부에서 다시 요청이 들어오는 형식이라 https에서 요청을 보냈는데 http로 요청이 들어가서 mixed contents에러가 발생한 것이었다.
이를 해결하는 방법은 Nginx를 서버에 직접 설치하는 것으로 매우 간단했다.
직접 설치하면 proxy_pass에서 localhost로 도커에 접근이 가능하기 때문에 외부로 요청이 나가지 않고 내부에서 요청을 받아서 건내는 형태로 mixed contents 에러가 발생하지 않는다.
이 과정을 통해 알게된 점은
Nginx와 같이 서버 전체에 영향을 미칠 수 있는 프로그램은 서버에 직접 설치하는 것이 좋으며, 위와 같이 도커 컨테이너로 사용하면 컨테이너 밖에 영향을 미칠 수 없다. 그리고 앞서 언급한 Nginx의 기능은 proxy_pass 뿐만 아니라 Blacklist, Load Balancing 등의 여러 기능을 사용할 수 있는데 이를 도커 컨테이너 안에서 실행한다면 활용성이 매우 떨어진다.
특히 도커로 배포하여 사용시에 도커 간 통신이 매우 힘든 것을 알 수 있었다.
Nginx 설치 및 사용
- 설치 전 서버의 패키지 목록 업데이트
- sudo apt update
- 설치
- sudo apt install nginx
- nginx 실행
- sudo systemctl start nginx
- sudo systemctl restart nginx
- sudo systemctl stop nginx
- sudo systemctl enable nginx → 부팅 또는 재부팅시 Nginx를 자동으로 시작하게 해 줌
- 실행 확인
- sudo systemctl status nginx
- 버전 확인
- sudo dpkg -l nginx
- nginx -v
- UFW 방화벽관련 Nginx 프로필
- Nginx Full → 80 & 443 port
- Nginx HTTP 80 port
- Nginx HTTPS 443 port
- 방화벽 열기
- sudo ufw enable
- sudo ufw allow ‘Nginx HTTPS’ → HTTP는 필요 없어서? 이렇게 함 → 근데 직접 sudo ufw 80/tcp 와 같이 포트 직접 열어도 똑같은 것 같음
- 변경사항 유지되도록 방화벽 다시 로드
- sudo ufw reload
- 방화벽 잘 올라갔는지 확인
- sudo ufw status
- 혹시 IP를 확인해서 접속하고 싶다면 클라우드의 경우
- curl ifconfig.me 를 하면 나옴. 근데 이걸로 proxy_pass 설정하지 말것
- 도메인으로 접속하거나 IP로 접속하면 아래와 같은 화면이 나오면 정상적으로 실행 된 것

12. 중요한 nginx 구성 파일
- /etc/nginx/nginx.conf → nginx 기본 설정 파일
- /var/log/nginx/access.log → nginx 로그
- /var/log/nginx/error.log → nginx error 로그
13. 내 설정 파일 생성하여 nginx 세팅하기
- nginx.conf 파일을 보면 http 블록 가장 아래에 다음과 같은 명령어가 있음 → includ /etc/nginx/conf.d/*.conf;
- 해당 명령어는 경로에 대한 확장자를 가진 파일을 포함하는 것으로 우리가 설정하길 원하는 파일을 해당 경로에 .conf 확장자로 만들면 원하는 nginx 설정을 할 수 있음
- /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name {domain}; # {domain}을 도메인으로 변경
location / {
return 308 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name {domain}; # {domain}을 도메인으로 변경
ssl_certificate /etc/letsencrypt/live/{domain}/fullchain.pem; # {domain}을 도메인으로 변경
ssl_certificate_key /etc/letsencrypt/live/{domain}/privkey.pem; # {domain}을 도메인으로 변경
location / {
proxy_pass http://localhost:8002;
}
location /api/v1/{
proxy_pass http://127.0.0.1:8001/api/v1/;
}
}
-
- listen은 포트, server_name은 도메인. 해당 포트의 도메인으로 오는 요청을 이제 nginx가 가장 먼저 받아본다
- return 308 으로 80포트로 들어오는 요청은 전부 리다이렉트 하여 https 요청으로 바꿔준다
→ 아래의 443 포트로 요청이 리다이렉트 됨 - ssl_certificate, ssl_certificate_key로 ssl 설정을 하여 https를 사용할 수 있게 한다.
→ 경로는 각자 설치한 경로로 fullchain.pem, privkey.pem 을 연결시켜 준다(이 설정은 certbot에서 키를 설치하고 연결해야한다. https 사용을 위한 설정임) - 이번엔 루트 경로로 접근했을 때 proxy_pass 로 react 서버로 연결해 준다.
→ localhost로 내부에서 접근이 가능함. 도커로 띄운 것들도 도메인으로 접근하기 떄문 - /api/v1/ 경로로 들어오는 것은 모두 Backend 서버로 보낸다.
- location의 경우 위처럼 쓰면 정확히 일치하는 경로인 경우만 각자 proxy_pass로 보내준다. → 정규식 등으로 location 도 다양하게 접근하도록 바꿀 수 있다
14. nginx를 재실행 하여 적용시킨다 → sudo systemctl restart nginx