웹 서비스를 개발하다 보면, 새로운 기능을 배포하기 전에 실제 서버와 동일한 환경에서 미리 테스트해 볼 공간이 필요합니다. 이때 기존 도메인을 활용하여 dev나 test 같은 머리말을 붙인 서브도메인을 생성하면 비용 추가 없이 독립적인 환경을 구축할 수 있습니다.

오늘은 Route 53과 Nginx를 활용하여 하나의 도메인으로 여러 개의 서비스를 스마트하게 관리하는 방법을 알아보겠습니다.


1. 서브도메인이란 무엇인가?

서브도메인은 루트 도메인(Root Domain, 예: example.com)의 왼쪽에 마침표로 구분하여 추가하는 이름입니다.

  • 운영 서버 (Production): www.example.com 또는 example.com
  • 개발 서버 (Development): dev.example.com
  • API 서버 (API): api.example.com

이들은 각각 서로 다른 IP 주소(다른 EC2 인스턴스)를 가리키거나, 한 서버 내에서 서로 다른 포트로 연결될 수 있습니다.


2. AWS Route 53에서 서브도메인 레코드 추가하기

가장 먼저 해야 할 일은 DNS 설정에서 서브도메인이 어디로 가야 할지 이정표를 세워주는 것입니다.

  1. Route 53 호스팅 영역으로 이동합니다.
  2. [레코드 생성] 버튼을 클릭합니다.
  3. 레코드 이름: dev (원하는 서브도메인 이름)를 입력합니다.
  4. 레코드 유형: A - IPv4 주소를 선택합니다.
  5. 값: 개발용으로 사용할 서버의 IP 주소를 입력합니다.

이제 dev.your-domain.com을 입력하면 해당 IP의 서버로 접속 신호가 전달됩니다.


3. Nginx 서버 블록(Virtual Host) 설정

서버에 신호가 도착했다면, Nginx가 "이건 dev로 들어온 요청이니 이 폴더를 보여줘!"라고 판단할 수 있게 설정해야 합니다.

3.1 운영 서버와 개발 서버 설정 분리

/etc/nginx/sites-available/ 디렉토리에 각각의 설정 파일을 만듭니다.

운영 서버 설정 (my-app-prod):

Nginx
 
server {
    listen 80;
    server_name your-domain.com www.your-domain.com;

    location / {
        proxy_pass http://localhost:3000; # 운영 포트
    }
}

개발 서버 설정 (my-app-dev):

Nginx
 
server {
    listen 80;
    server_name dev.your-domain.com;

    location / {
        proxy_pass http://localhost:4000; # 개발용 포트 또는 다른 폴더
    }
}

이렇게 server_name을 기반으로 요청을 분기하면 하나의 서버(Nginx) 안에서도 여러 서비스를 완벽히 분리하여 운영할 수 있습니다.


4. 서브도메인 활용의 장점

  1. 비용 절감: 도메인을 추가로 구매할 필요가 없습니다.
  2. 독립적인 테스트: 운영 중인 서비스에 영향을 주지 않고 새로운 기능을 마음껏 테스트할 수 있습니다.
  3. 브랜드 통일성: 서비스의 성격에 따라 주소를 나누더라도 메인 도메인의 브랜드 가치를 유지할 수 있습니다.
  4. SSL 통합 관리: Wildcard SSL 인증서(*.example.com)를 사용하면 모든 서브도메인에 한 번에 HTTPS를 적용할 수 있어 관리가 편리합니다.

5. 실무 꿀팁: 개발 서버 보안 강화

개발 서버(dev.)는 외부인에게 노출되어서는 안 되는 공간입니다. 서브도메인을 만들었다면 반드시 아래 설정을 추가하세요.

  • IP 제한: 사내 IP나 본인의 IP에서만 접속할 수 있도록 Nginx 설정에서 allow 기능을 사용하세요.
  • 검색 엔진 차단: 구글 봇이 개발 서버의 내용을 수집하지 않도록 robots.txt에 Disallow: / 설정을 추가하세요.
  • 기본 인증: ID/PW를 입력해야 접속할 수 있는 HTTP Basic Auth를 걸어두는 것도 좋은 방법입니다.

6. 결론: 체계적인 배포 프로세스의 완성

서브도메인을 활용한 환경 분리는 단순한 기술을 넘어 배포의 안전성을 책임지는 중요한 전략입니다. 이제 dev 서버에서 충분히 테스트하고 확신이 섰을 때 www 서버로 코드를 옮기는 안전한 개발 문화를 시작해 보세요.

웹 서비스가 성장하여 방문자가 급증하면, 아무리 고성능인 단일 서버라도 물리적인 한계에 부딪히게 됩니다. 서버가 느려지거나 다운되는 것을 방지하기 위해 가장 먼저 고려해야 할 기술이 바로 **로드 밸런싱(Load Balancing)**입니다.

오늘은 오픈소스 웹 서버인 Nginx를 활용하여 여러 대의 서버로 부하를 분산하고, 서비스의 가용성을 극대화하는 방법을 상세히 알아보겠습니다.


1. 로드 밸런싱(Load Balancing)이란?

로드 밸런싱은 말 그대로 '부하(Load)'를 여러 대의 서버에 '균형 있게(Balancing)' 나누는 기술입니다. 사용자의 요청이 집중될 때, 앞단에 위치한 로드 밸런서가 뒤에 대기 중인 여러 대의 애플리케이션 서버로 요청을 배분합니다.

1.1 로드 밸런싱의 주요 목적

  • 고가용성(High Availability): 특정 서버에 장애가 발생해도 다른 서버가 요청을 처리하여 중단 없는 서비스를 제공합니다.
  • 확장성(Scalability): 트래픽 증가 시 서버 대수만 늘리면 되므로 유연한 대응이 가능합니다.
  • 성능 최적화: 서버 한 대에 가해지는 부담을 줄여 응답 속도를 향상시킵니다.

2. Nginx 로드 밸런싱 핵심 설정법

Nginx에서는 upstream 블록을 사용하여 로드 밸런싱 그룹을 정의합니다.

2.1 기본 설정 예시 (Round Robin)

가장 기본적인 방식으로, 서버들에 순차적으로 요청을 배분합니다.

Nginx
 
http {
    # 백엔드 서버 그룹 정의
    upstream my_backend_servers {
        server 10.0.0.1:3000;
        server 10.0.0.2:3000;
        server 10.0.0.3:3000;
    }

    server {
        listen 80;
        server_name your-domain.com;

        location / {
            # 위에서 정의한 upstream 그룹으로 요청 전달
            proxy_pass http://my_backend_servers;
            
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

2.2 주요 부하 분산 알고리즘

서비스의 성격에 따라 적절한 알고리즘을 선택할 수 있습니다.

  • Round Robin (기본값): 순서대로 균등 배분.
  • Least Connections (least_conn): 현재 연결 수가 가장 적은 서버로 요청을 보냅니다. 작업 시간이 긴 요청이 많을 때 유리합니다.
  • IP Hash (ip_hash): 사용자의 IP를 해싱하여 항상 동일한 서버로 연결합니다. 세션 유지가 필요한 서비스에 적합합니다.
  • Weight (가중치): 성능이 더 좋은 서버에 더 많은 요청을 보내도록 설정합니다. (server 10.0.0.1:3000 weight=3;)

3. 장애 감지와 복구 (Health Check)

Nginx 로드 밸런서의 강력한 기능 중 하나는 백엔드 서버의 상태를 체크하는 것입니다.

Nginx
 
upstream my_backend_servers {
    # 3번 실패하면 30초 동안 해당 서버를 제외함
    server 10.0.0.1:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:3000 max_fails=3 fail_timeout=30s;
}

이 설정을 통해 특정 서버가 다운되었을 때 사용자가 에러 페이지를 보는 대신, 정상 작동하는 다른 서버의 응답을 받을 수 있도록 자동 제어가 가능합니다.


4. 실무 도입 시 고려사항: 세션 동기화

로드 밸런싱을 도입할 때 가장 주의해야 할 점은 세션(Session) 관리입니다. 사용자가 A 서버에서 로그인했는데, 다음 클릭 시 B 서버로 연결되면 로그인이 풀리는 현상이 발생합니다.

이를 해결하기 위해 다음과 같은 방법을 사용합니다.

  1. Sticky Session: ip_hash를 사용하여 사용자를 특정 서버에 고정시킵니다.
  2. External Session Store: 세션 정보를 서버 메모리가 아닌 외부 저장소(예: Redis)에 저장하여 모든 서버가 공유하게 합니다. (권장 방식)

5. 결론: 더 큰 서비스를 향한 도약

Nginx 로드 밸런싱 설정은 단순한 서버 운영을 넘어 '시스템 아키텍처'를 설계하는 첫걸음입니다. 초기 비용 없이 소프트웨어 설정만으로 대규모 트래픽에 대응할 수 있다는 점은 큰 매력입니다.

웹사이트를 운영하면서 주소창 옆에 있는 '자물쇠 아이콘'은 이제 선택이 아닌 필수입니다. HTTPS가 적용되지 않은 사이트는 구글 검색 순위에서 밀려날 뿐만 아니라, 사용자들에게 '안전하지 않음' 경고를 표시하여 신뢰도를 떨어뜨리기 때문입니다.

오늘은 Let's Encrypt를 사용하여 무료로 SSL 인증서를 발급받고, 90일마다 돌아오는 갱신 과정을 Certbot을 이용해 완전히 자동화하는 방법을 상세히 알아보겠습니다.


1. Let's Encrypt와 Certbot이란?

Let's Encrypt는 누구나 무료로 SSL/TLS 인증서를 발급받을 수 있도록 지원하는 비영리 인증 기관(CA)입니다. 그리고 Certbot은 이 Let's Encrypt 인증서를 자동으로 발급, 설치, 갱신해 주는 오픈소스 소프트웨어 도구입니다.

1.1 왜 자동 갱신이 필요한가?

Let's Encrypt 인증서의 유효 기간은 90일로 매우 짧습니다. 이는 보안성을 높이기 위함이지만, 관리자가 매번 수동으로 갱신하기에는 번거롭고 실수로 만료될 위험이 큽니다. 따라서 자동화 설정을 통해 신경 쓰지 않아도 인증서가 유지되도록 하는 것이 핵심입니다.


2. 사전 준비 사항

작업을 시작하기 전에 아래 두 가지 조건이 충족되어야 합니다.

  1. 도메인 보유: IP 주소가 아닌 실제 도메인(example.com)이 서버의 공인 IP와 연결되어 있어야 합니다.
  2. 웹 서버 설치: Nginx 또는 Apache가 서버에 설치되어 동작 중이어야 합니다.

3. Certbot 설치 및 인증서 발급 (Nginx 기준)

Ubuntu 서버 환경에서 Nginx를 위한 Certbot 설정을 진행해 보겠습니다.

3.1 Certbot 설치

Bash
 
sudo apt update
sudo apt install certbot python3-certbot-nginx -y

3.2 인증서 발급 및 자동 설정

아래 명령어를 입력하면 Certbot이 Nginx 설정 파일을 자동으로 분석하여 SSL 설정을 추가해 줍니다.

Bash
 
sudo certbot --nginx -d your-domain.com -d www.your-domain.com
  • 이메일 입력: 만료 알림을 받을 이메일 주소를 입력합니다.
  • 약관 동의: A를 눌러 동의합니다.
  • HTTPS 리다이렉트: 기존 HTTP 접속을 자동으로 HTTPS로 넘길지 묻는 질문에는 2 (Redirect)를 선택하는 것을 권장합니다.

4. SSL 자동 갱신 설정 및 검증

Certbot은 설치 시 자동으로 시스템 스케줄러(cron 또는 systemd timer)에 갱신 스크립트를 등록합니다. 하지만 실제로 잘 작동하는지 확인하는 과정이 필요합니다.

4.1 드라이 런(Dry Run) 테스트

실제로 갱신을 수행하지 않고, 절차상 문제가 없는지 가상으로 테스트합니다.

Bash
 
sudo certbot renew --dry-run

결과 메시지에 **"Congratulations, all simulated renewals succeeded"**라는 문구가 보인다면 자동 갱신 설정에 문제가 없는 것입니다.

4.2 스케줄러 확인

인증서 갱신 작업이 등록되어 있는지 확인하려면 아래 명령어를 입력하세요.

Bash
 
systemctl list-timers | grep certbot

5. SSL 보안 등급 확인하기 (전문성 강화)

인증서 설치가 완료되었다면, 내 사이트의 보안 설정이 얼마나 견고한지 테스트해 볼 수 있습니다. SSL Labs 사이트에 접속하여 본인의 도메인을 입력하면 보안 등급(A~F)을 확인할 수 있습니다.

Nginx에서 최신 암호화 프로토콜(TLS 1.2, 1.3)만 사용하도록 설정하면 손쉽게 A 등급을 획득할 수 있으며, 이는 구글 SEO 점수에도 긍정적인 영향을 미칩니다.


6. 결론: 안전한 웹 서비스의 완성

무료 인증서라고 해서 유료 인증서보다 보안성이 떨어지는 것은 아닙니다. Let's Encrypt와 Certbot을 조합하면 비용 부담 없이 완벽한 HTTPS 환경을 구축할 수 있습니다.

요약하자면:

  1. Certbot으로 간편하게 인증서를 발급받으세요.
  2. --dry-run 테스트를 통해 자동 갱신 설정을 꼭 검증하세요.
  3. 보안 등급을 체크하여 최적의 서버 설정을 유지하세요.

웹 서비스를 운영하다 보면 성능 최적화와 보안이라는 두 마리 토끼를 잡아야 하는 순간이 옵니다. 특히 Node.js, Python(Django/Flask), Go 등으로 만든 애플리케이션 서버를 외부 네트워크에 직접 노출하는 것은 보안상 위험할 뿐만 아니라 성능 면에서도 효율적이지 않습니다.

이때 가장 대중적으로 사용되는 해결책이 바로 Nginx를 활용한 리버스 프록시(Reverse Proxy) 구성입니다. 오늘은 리버스 프록시의 개념부터 실제 설정 방법, 그리고 이를 통해 얻을 수 있는 이점까지 상세히 정리해 보겠습니다.


1. 리버스 프록시(Reverse Proxy)란 무엇인가?

일반적인 프록시(Forward Proxy)가 클라이언트의 요청을 대신 전달한다면, 리버스 프록시는 서버의 앞단에 위치하여 클라이언트의 요청을 받아 내부 서버로 전달하는 역할을 합니다.

사용자는 실제 애플리케이션 서버(예: 3000번 포트)에 직접 접속하는 것이 아니라, 80(HTTP) 또는 443(HTTPS) 포트를 통해 Nginx에 먼저 도달하게 됩니다. Nginx는 이 요청을 적절한 내부 서버로 토스(Toss)해 주는 '중개인' 역할을 수행합니다.


2. 리버스 프록시 도입의 3가지 핵심 이점

2.1 보안 강화 (Security)

실제 서비스가 돌아가는 서버의 IP와 포트를 외부로부터 숨길 수 있습니다. 공격자는 Nginx의 IP만 볼 수 있으며, 내부 인프라 구조를 파악하기 어렵게 됩니다. 또한, Nginx 단에서 WAF(웹 방화벽) 설정을 추가하여 악의적인 요청을 1차적으로 걸러낼 수 있습니다.

2.2 부하 분산 (Load Balancing)

하나의 Nginx 뒷단에 여러 대의 애플리케이션 서버를 두고, 요청을 골고루 나누어 줄 수 있습니다. 특정 서버에 장애가 발생하더라도 다른 서버로 요청을 유도하여 서비스 가용성을 높일 수 있습니다.

2.3 정적 파일 캐싱 및 압축 (Performance)

이미지, CSS, JS와 같은 정적 자원을 Nginx가 직접 캐싱하거나 gzip 압축을 통해 전송 속도를 높일 수 있습니다. 이는 애플리케이션 서버가 비즈니스 로직에만 집중할 수 있도록 부담을 덜어줍니다.


3. Nginx 리버스 프록시 실전 설정법

이제 Ubuntu 환경에서 Nginx를 설치하고 리버스 프록시를 설정하는 과정을 살펴보겠습니다. (내부 서버는 localhost:3000에서 동작 중이라고 가정합니다.)

3.1 Nginx 설치

먼저 패키지 목록을 업데이트하고 Nginx를 설치합니다.

Bash
 
sudo apt update
sudo apt install nginx -y

3.2 설정 파일 생성 및 수정

기본 설정 파일을 수정하기보다는, 새로운 설정 파일을 만들어 관리하는 것이 좋습니다.

Bash
 
sudo nano /etc/nginx/sites-available/my-app

파일 내부에 아래 내용을 입력합니다. (도메인이 있다면 server_name에 작성하세요.)

Nginx
 
server {
    listen 80;
    server_name your-domain.com; # 도메인이 없다면 서버 IP 입력

    location / {
        # 요청을 내부 서버(3000번 포트)로 전달
        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;
        
        # 클라이언트의 실제 IP 주소 전달
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

3.3 설정 활성화 및 테스트

작성한 설정을 활성화하고 구문에 에러가 없는지 확인합니다.

Bash
 
# 설정 파일 심볼릭 링크 생성
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/

# Nginx 설정 테스트
sudo nginx -t

# Nginx 재시작
sudo systemctl restart nginx

4. 자주 발생하는 문제와 해결법 (Troubleshooting)

리버스 프록시 설정 후 흔히 겪는 에러 두 가지를 짚어보겠습니다.

  • 502 Bad Gateway: Nginx는 정상이나, proxy_pass로 연결된 내부 애플리케이션 서버가 죽어있을 때 발생합니다. pm2 status 등으로 서버 상태를 확인하세요.
  • 413 Request Entity Too Large: 클라이언트가 업로드하는 파일 용량이 Nginx 기본 제한을 초과할 때 발생합니다. http나 server 블록에 client_max_body_size 20M; 설정을 추가하여 해결할 수 있습니다.

5. 결론: 현대 웹 아키텍처의 필수 요소

리버스 프록시는 단순한 전달자를 넘어, 웹 서비스의 안정성과 확장성을 책임지는 핵심 인프라 기술입니다. 특히 최근처럼 마이크로서비스 아키텍처(MSA)가 각광받는 환경에서는 Nginx를 활용한 게이트웨이 구성이 더욱 중요해지고 있습니다.

오늘 안내해 드린 기본 설정을 바탕으로, 이후에는 HTTPS 보안 인증서(SSL) 적용과 로드 밸런싱 설정까지 확장해 보시길 권장합니다. 안정적인 서버 운영으로 사용자에게 더 나은 경험을 제공해 보세요!

+ Recent posts