본문 바로가기
Prop : 부동산/업데이트 일지

AWS EC2 Failsafe & Maintenance Page 종합 매뉴얼

by 프롭테크 2025. 9. 1.
반응형

AWS EC2 Failsafe & Maintenance Page 종합 매뉴얼

이 매뉴얼은 AWS Free Tier를 활용하여 Failsafe(안전장치) 및 유지보수 안내 페이지 역할을 하는 웹서버를 구축하는 전체 과정을 안내합니다.

주요 기능:

  • llun.com과 같은 특정 도메인으로의 접근을 처리합니다.
  • /lab/과 같이 미리 약속된 경로는 정상적으로 콘텐츠를 제공합니다.
  • 그 외의 모든 경로(/, /about, /anything 등)로 접근 시 "작업 중" 안내 페이지를 보여줍니다.
  • Google Analytics 4를 이용해 어떤 경로로 사용자가 접근하려 했는지 데이터를 수집하고 분석합니다.
  • 서버에 파일을 업로드하는 다양한 방법을 안내합니다.


목차

  1. EC2 인스턴스 생성 및 기본 설정
  2. 서버 초기 설정 (Nginx 및 방화벽)
  3. Nginx 및 유지보수 페이지 설정
  4. Failsafe 콘텐츠 생성 (/lab/ 경로)
  5. SSL 인증서 설정 (HTTPS)
  6. GA4를 통한 접근 경로 추적 설정
  7. 테스트 및 검증
  8. 부록 A: EC2에 파일 업로드하는 방법
  9. 부록 B: RStudio에서 배포 자동화하기

1. EC2 인스턴스 생성 및 기본 설정

1-1. EC2 인스턴스 시작

  1. AWS 콘솔 → EC2 → Launch Instance
  2. 설정:
    • Name: maintenance-server
    • AMI: Ubuntu Server 22.04 LTS
    • Instance type: t2.micro (Free tier eligible)
    • Key pair: 새로 생성하거나 기존 키를 선택합니다. (이 매뉴얼에서 your-key.pem으로 지칭)
    • Security Group: 새로 생성합니다.

1-2. Security Group 설정

Inbound Rules:

  • Type: HTTP, Protocol: TCP, Port: 80, Source: 0.0.0.0/0
  • Type: HTTPS, Protocol: TCP, Port: 443, Source: 0.0.0.0/0
  • Type: SSH, Protocol: TCP, Port: 22, Source: 0.0.0.0/0

1-3. Elastic IP 할당 (권장)

고정 IP를 사용하기 위해 Elastic IP를 생성하고 방금 만든 EC2 인스턴스에 연결합니다.


2. 서버 초기 설정 (Nginx 및 방화벽)

2-1. SSH 접속

로컬 터미널에서 아래 명령어로 서버에 접속합니다.

ssh -i /path/to/your-key.pem ubuntu@[EC2_ELASTIC_IP]

2-2. 패키지 설치 및 Nginx 실행

sudo apt update && sudo apt upgrade -y
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx

2-3. UFW 방화벽 설정

sudo ufw allow 'Nginx Full'
sudo ufw allow ssh
sudo ufw --force enable

3. Nginx 및 유지보수 페이지 설정

3-1. Nginx 설정 파일 수정

기본 설정을 비활성화하고 llun.com을 위한 새 설정을 만듭니다.

# 기본 설정 링크 제거
sudo rm /etc/nginx/sites-enabled/default

# 새 설정 파일 생성
sudo nano /etc/nginx/sites-available/llun_com

아래 내용을 llun_com 파일에 붙여넣습니다.

server {
    listen 80;
    server_name llun.com; # 실제 사용할 도메인으로 변경
    root /var/www/html;
    index index.html;

    # 1. 약속된 '/lab/' 경로는 정상적으로 서비스합니다.
    location /lab/ {
        try_files $uri $uri/ =404;
    }

    # 2. 그 외 모든 요청은 503 오류를 반환합니다.
    location / {
        return 503;
    }

    # 3. 503 오류 발생 시 보여줄 페이지를 지정합니다.
    #    이 설정 덕분에 브라우저의 URL은 바뀌지 않습니다.
    error_page 503 /maintenance.html;

    # 4. maintenance.html 파일에 직접 접근하는 것을 막습니다.
    location = /maintenance.html {
        internal;
    }
}

3-2. 설정 활성화

# 새 설정 파일 링크 생성
sudo ln -s /etc/nginx/sites-available/llun_com /etc/nginx/sites-enabled/

# Nginx 설정 문법 검사
sudo nginx -t

# Nginx 다시 로드
sudo systemctl reload nginx

3-3. 유지보수 페이지(maintenance.html) 생성

서버 터미널에서 아래 명령을 실행하여 추적 스크립트가 포함된 maintenance.html 파일을 생성합니다.

cat > /var/www/html/maintenance.html << 'EOF'
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>작업 중</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; margin-top: 100px; background: #f5f5f5; }
        .container { max-width: 600px; margin: 0 auto; padding: 40px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h1 { color: #333; } .emoji { font-size: 48px; }
    </style>

    <!-- Google Analytics 4 (GA4) 추적 스크립트 -->
    <!-- 'G-XXXXXXXXXX' 부분을 본인의 GA4 측정 ID로 변경하세요. -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'G-XXXXXXXXXX', {
        'send_page_view': false // 자동 페이지뷰 전송 비활성화
      });

      window.addEventListener('load', function() {
        gtag('event', 'maintenance_page_hit', {
          'original_path': window.location.pathname, // 사용자가 요청한 원래 경로
          'page_title': document.title
        });
      });
    </script>
    <!-- End Google Analytics -->

</head>
<body>
    <div class="container">
        <div class="emoji">🚧</div>
        <h1>현재 사이트 준비 중입니다</h1>
        <p>더 나은 서비스를 위해 열심히 준비하고 있습니다.<br>빠른 시일 내에 찾아뵙겠습니다.</p>
    </div>
</body>
</html>
EOF

4. Failsafe 콘텐츠 생성 (/lab/ 경로)

정상적으로 서비스할 경로의 디렉토리와 파일을 생성합니다.

# 디렉토리 생성 및 권한 설정
sudo mkdir -p /var/www/html/lab
sudo chown -R $USER:$USER /var/www/html

# /lab/index.html 파일 생성
cat > /var/www/html/lab/index.html << 'EOF'
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Lab - Failsafe</title>
</head>
<body>
    <h1>🧪 Lab 섹션</h1>
    <p>이 페이지는 정상적으로 서비스되고 있습니다.</p>
</body>
</html>
EOF

5. SSL 인증서 설정 (HTTPS)

Let's Encrypt를 통해 무료 SSL 인증서를 발급받아 HTTPS를 활성화합니다.

# Certbot 설치
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

# SSL 인증서 발급 및 Nginx 자동 설정
# llun.com 부분을 실제 도메인으로 변경하세요.
sudo certbot --nginx -d llun.com

Certbot이 HTTPS 리다이렉션 설정을 자동으로 추가해줍니다.


6. GA4를 통한 접근 경로 추적 설정

수집된 데이터를 GA4에서 의미 있게 분석하기 위해 맞춤 측정기준을 설정해야 합니다.

  1. GA4 대시보드 접속: Google Analytics
  2. 경로: 관리데이터 표시맞춤 정의
  3. 맞춤 측정기준 만들기 클릭
  4. 아래와 같이 설정:
    • 측정기준 이름: Original Path (또는 '최초 접근 경로')
    • 범위: 이벤트
    • 설명: 유지보수 페이지에 도달한 사용자의 원래 요청 경로
    • 이벤트 매개변수: original_path (3-3단계의 스크립트와 동일해야 함)
  5. 저장합니다. (리포트에 반영되기까지 최대 48시간이 소요될 수 있습니다.)

데이터 분석 방법

탐색자유 형식 보고서에서 아래와 같이 설정하여 분석합니다.

  • : Original Path (방금 만든 맞춤 측정기준)
  • : 이벤트 수
  • 필터: 이벤트 이름maintenance_page_hit인 경우

7. 테스트 및 검증

  • http://llun.com/lab/ 접속 → "Lab 섹션" 페이지가 정상적으로 표시되어야 합니다.
  • http://llun.com/ 또는 http://llun.com/any/other/path 접속 → "현재 사이트 준비 중입니다" 페이지가 표시되어야 합니다. (브라우저 주소창의 URL은 그대로 유지되어야 함)
  • GA4 실시간 보고서에서 maintenance_page_hit 이벤트가 수집되는지 확인합니다.

부록 A: EC2에 파일 업로드하는 방법

방법 1: SCP (터미널 - 가장 표준적)

  1. 로컬 → EC2 홈 디렉토리로 파일 전송:

    scp -i /path/to/your-key.pem local_file.html ubuntu@[EC2_IP]:~
  2. EC2 접속 후 웹 디렉토리로 이동:

    ssh -i /path/to/your-key.pem ubuntu@[EC2_IP]
    sudo mv ~/local_file.html /var/www/html/

방법 2: VS Code (Remote-SSH 확장 프로그램)

  1. VS Code에 Remote - SSH 확장 프로그램 설치.
  2. SSH 호스트 추가 (ssh -i /path/to/key.pem ubuntu@[EC2_IP]).
  3. 연결 후, VS Code 탐색기 패널로 로컬 파일을 드래그 앤 드롭하여 업로드.
  4. VS Code 내장 터미널에서 sudo mv 명령으로 파일 이동.

방법 3: FileZilla (GUI SFTP 클라이언트)

  1. 사이트 관리자에서 새 사이트 추가 (SFTP, 키 파일 방식).
  2. 호스트, 사용자, 키 파일 경로 등 정보 입력 후 연결.
  3. 왼쪽(로컬) 패널에서 오른쪽(서버) 패널로 파일을 드래그 앤 드롭.
  4. 별도 터미널로 접속하여 sudo mv 명령으로 파일 이동.

부록 B: RStudio에서 배포 자동화하기

R의 system() 함수를 사용하여 파일/폴더 배포를 자동화할 수 있습니다.

사용자 함수 코드

deploy_to_ec2 <- function(local_path, key_path, ec2_user, ec2_ip, remote_dest_path = "/var/www/html") {
  # 입력값 유효성 검사
  if (!file.exists(local_path)) stop("Error: 로컬 경로를 찾을 수 없습니다.")
  if (!file.exists(key_path)) stop("Error: 키 파일을 찾을 수 없습니다.")

  # 업로드 준비
  is_directory <- dir.exists(local_path)
  recursive_flag <- if (is_directory) "-r" else ""
  item_name <- basename(local_path)

  message(sprintf("▶ 배포 시작: '%s'", item_name))

  # 1. SCP 업로드
  message("[1/2] SCP 업로드 중...")
  scp_command <- sprintf(
    'scp %s -i "%s" "%s" %s@%s:~',
    recursive_flag, key_path, local_path, ec2_user, ec2_ip
  )
  if (system(scp_command) != 0) {
    message("  └─> [실패] SCP 업로드 오류."); return(FALSE)
  }
  message("  └─> [성공] 업로드 완료.")

  # 2. SSH 원격 이동
  message(sprintf("[2/2] 원격 서버에서 '%s' 이동/교체 중...", remote_dest_path))
  ssh_command <- sprintf(
    'ssh -i "%s" %s@%s "sudo rm -rf %s/%s && sudo mv ~/%s %s"',
    key_path, ec2_user, ec2_ip,
    remote_dest_path, item_name,
    item_name, remote_dest_path
  )
  if (system(ssh_command) != 0) {
    message("  └─> [실패] 원격 이동 오류."); return(FALSE)
  }
  message("  └─> [성공] 이동 완료.")

  message("✔ 배포가 성공적으로 완료되었습니다!")
  return(TRUE)
}

함수 사용 예시

# 정보 설정
my_key <- "path/to/your-key.pem"
my_ip <- "YOUR_EC2_IP"

# 단일 파일 배포
deploy_to_ec2(
  local_path = "./maintenance.html",
  key_path = my_key,
  ec2_user = "ubuntu",
  ec2_ip = my_ip
)

# 폴더 전체 배포
deploy_to_ec2(
  local_path = "./assets", # assets 폴더 전체
  key_path = my_key,
  ec2_user = "ubuntu",
  ec2_ip = my_ip
)
반응형

댓글