WEEK 18 나만무 폴리싱 TIL(7월10일 목요일)

Devkty·2025년 7월 13일
post-thumbnail

[목표]
AWS 오토스케일링 적용하기(CORS 해결하기)
멘토님께 메일 보내기
피드백 정리해서 뭘해야할 지 정하기
정체성과 시나리오 정하기
폴리싱할 내용 정하기

11:00 ~ 12:00

AWS 아마존 Q로 수정을 했다. (RSC 데이터 문제)
시나리오 짯다.

[초안]
Jira를 지금까지의 대학교나 정글에서의 4개월간의 개발을 하면서 트러블슈팅이라는 것을 잘 모르지만 기록은 체계적으로 하고 싶어하는 사람들을 위해 만들게되었다.

Jira를 최대한 이해하여 이슈트래킹을 어떻게 하는지에 대해 초급/대학생 개발자의 시선으로 재해석 했다. 소규모 프로젝트를 진행하는데, 과도하다고 생각하는 기능은 과감히 빼고 편리한 기능은 추가했다.

어쨋든 Jira를 벤치마킹했기 때문에, 미리 이슈트레킹에 대해서 쉽게 학습하고 이슈 자동화로 프로젝트 이슈를 체계적으로 관리할 수 있다.

우리의 대상은 소규모 프로젝트를 진행하는 개발자 대상이다. 즉, 현업의 관점보다는 대학교에서나 개인이나 가볍게 프로젝트를 진행할 때, 이슈 트래킹하기 용이하도록 만들었다.

근데, 내 생각에는 하나의 이슈카드에서 관리자 승인이 나오기 전까지는 Done으로 바꾸지 못하니까 지금의 틀도 그대로 쓸 수 있을것 같다. 근데, 이슈 카드안에서 거부됨을 알 수 있는 기능을 강화해야 될 필요성이 있다.

12:00 ~ 13:00

식사를 하고 왔다.

13:00 ~ 14:30

어제 발생한 RSC 데이터 반환문제를 해결하고 있다. 밑에 냐용으로 해결완료 했다.

  • 오토스케일링 후 아마존 Q의 RSC 데이터 반환 문제 해결

    CloudFront에서 Next.js RSC 데이터 반환 문제 해결 과정

    어제에 이어서 배포된 사이트에 자꾸 RSC 데이터가 보이는 문제를 해결해보았다. 중요한 내용은 CloudFront의 헤더를 모두 허용에서 수동으로 따로 허용해줘서 해결했다. 만약에 반영이 안되면 무효화로 해결했다.

    1. 문제 개요

    증상

    • CloudFront 도메인을 통해 접근 시 간헐적으로 HTML이 아닌 RSC 원시 데이터(text/x-component)가 반환됨

    • 오토스케일링으로 생성된 EC2 인스턴스에서 주로 발생

      예시 응답

      "$Sreact.fragment"
      I[87555,[],""]
      I[65150,["4277","static/chunks/4277-..."]]

      2. 분석 및 원인

      2-1. 상태 점검

      타겟 그룹 및 ALB 상태

      # ALB 연결 테스트
      curl -I http://<기존 인스턴스 IP>/auth/login
      # → Content-Type: text/html
      
      curl -I http://<신규 인스턴스 IP>/auth/login
      # → Content-Type: text/x-component (문제 발생)

      CloudFront 경유 테스트

      curl -I https://d1yf3se408yzed.cloudfront.net/auth/login
      # → 간헐적으로 RSC 데이터 노출

      2-2. 원인 요약

    • Nginx 프록시 대상이 하드코딩된 내부 IP (172.31.x.x)

    • 환경 변수(.env) 및 DB 설정 누락

    • CloudFront의 Origin Request Policy에서 RSC 관련 헤더 전달


      3. 해결 절차

      3-1. Nginx 설정 수정

      기존 설정 (문제 발생)

      # /etc/nginx/sites-available/default
      
      upstream frontend {
          server 172.31.38.111:3000;
      }
      
      server {
          listen 80 default_server;
      
          location / {
              proxy_pass http://frontend;
              ...
          }
      }
      

      수정된 설정 (정상 작동)

      upstream frontend {
          server localhost:3000;
      }
      
      server {
          listen 80 default_server;
      
          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_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_cache_bypass $http_upgrade;
          }
      }
      

      적용 명령

      sudo nginx -t
      sudo systemctl reload nginx

      3-2. CloudFront 캐시 정책 및 무효화

      기존 정책: CachingOptimized (정적 리소스에 적합)

      변경: CachingDisabled (SSR에 적합)

      무효화 명령

      aws cloudfront create-invalidation \
        --distribution-id E1RP0D9PX2A2GW \
        --invalidation-batch "Paths={Quantity=1,Items=['/*']},CallerReference=cache-invalidation-$(date +%s)"

      3-3. AMI 생성 및 Launch Template 교체

      정상 인스턴스로부터 AMI 생성

      aws ec2 create-image \
        --instance-id i-0f3960fab43d2e227 \
        --name "codeplanner-working-ami-20250709" \
        --description "Working CodePlanner instance AMI with proper configuration"

      Launch Template 새 버전 생성

      aws ec2 create-launch-template-version \
        --launch-template-id lt-0a7432bfc3898514c \
        --version-description "Fixed version with working AMI" \
        --launch-template-data '{
          "ImageId": "ami-0b60678d2e83db79e",
          "InstanceType": "t2.small",
          "UserData": ""
      }'

      오토스케일링 그룹에 적용

      aws autoscaling update-auto-scaling-group \
        --auto-scaling-group-name codeplanner-asg \
        --launch-template '{
          "LaunchTemplateId": "lt-0a7432bfc3898514c",
          "Version": "10"
      }'

      인스턴스 새로고침 수행

      aws autoscaling start-instance-refresh \
        --auto-scaling-group-name codeplanner-asg

      3-4. CloudFront Origin Request Policy 수정

      정상 작동하는 헤더 화이트리스트 정책

      [추가할 헤더들]

      밑에 사진과 같이 똑같이 설정해야한다. 잘못하면 로그인 정보가 안바뀐다.

      전달하지 않아야 할 헤더 목록 (캐시 분할 유발)

    • RSC

    • Next-Router-State-Tree

    • Next-Router-Prefetch

    • Next-Router-Segment-Prefetch

      3-5. 애플리케이션 재시작

      EC2 내 명령어

      # 앱 빌드 및 실행
      sudo -u ubuntu npm run build
      sudo -u ubuntu pm2 restart all

      4. 최종 결과

      항목해결 여부
      RSC 데이터 노출 문제해결
      오토스케일링 인스턴스 설정정상화
      Authorization 헤더 인증 문제해결
      CloudFront 캐시 일관성 문제해결

      5. 교훈 및 권장 사항

      인프라 구성

    • UserData 스크립트는 완전한 상태로 작성

    • IP 하드코딩 금지 → localhost 또는 서비스 디스커버리 사용

    • 환경 변수는 AMI에 포함하거나 외부 설정으로 주입

      CloudFront 설정

    • SSR 프레임워크에서는 헤더 기반 캐시 주의

    • 동적 콘텐츠는 캐시 비활성화하거나 분리된 정책 적용

    • Origin Request Policy에서 불필요한 헤더 전달 금지

      운영/모니터링

    • Content-Type 헤더 모니터링으로 응답 이상 조기 발견

    • 오토스케일링 신규 인스턴스 초기 상태 점검 필수

    • CloudFront와 ALB 응답 비교를 통한 문제 원인 분리 가능




  • 새로운 오토스케일링 도입법

    새로운 오토스케일링 서버 구축 가이드

    1. Launch Template 설계

    1-1. UserData 스크립트 요약

    주요 기능
    • Node.js 22.16.0 수동 설치

    • PM2, Nginx 설치 및 설정

    • 백/프론트엔드 자동 배포

    • .env 환경 변수 자동 작성

    • 방화벽 및 로그 설정 포함

      핵심 스크립트 (요약)

      #!/bin/bash
      
      # 로그 설정 - 디버깅을 위한 상세 로깅
      exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
      echo "Starting UserData script execution at $(date)"
      
      # 에러 발생 시 스크립트 중단
      set -e
      
      # 1. 기본 패키지 설치
      echo "Installing basic packages..."
      apt-get update -y
      apt-get install -y curl git build-essential wget gnupg2 ca-certificates lsb-release ufw awscli
      
      # 2. Node.js 22.16.0 설치
      echo "Installing Node.js..."
      NODE_VERSION=22.16.0
      ARCH=$(uname -m)
      if [ "$ARCH" == "x86_64" ]; then
        ARCH="x64"
      elif [ "$ARCH" == "aarch64" ]; then
        ARCH="arm64"
      else
        echo "Unsupported architecture: $ARCH"
        exit 1
      fi
      
      curl -O https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH.tar.xz
      tar -C /usr/local --strip-components=1 -xJf node-v$NODE_VERSION-linux-$ARCH.tar.xz
      rm node-v$NODE_VERSION-linux-$ARCH.tar.xz
      
      # Node.js 확인
      echo "Node.js version: $(node -v)"
      echo "npm version: $(npm -v)"
      
      # PM2 설치 및 환경 설정
      echo "Installing PM2..."
      npm install -g pm2
      export HOME=/home/ubuntu
      export PM2_HOME=/home/ubuntu/.pm2
      
      # 3. PostgreSQL 17.5 설치
      echo "Installing PostgreSQL..."
      sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
      wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor > /usr/share/keyrings/postgresql.gpg
      echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
      apt-get update -y
      apt-get install -y postgresql-17
      
      # PostgreSQL 버전 확인
      echo "PostgreSQL version:"
      sudo -u postgres psql -c "SELECT version();"
      
      # 4. Nginx 설치 및 설정
      echo "Installing and configuring Nginx..."
      apt-get install -y nginx
      
      # 5. 방화벽 설정 - 보안 강화
      echo "Configuring firewall..."
      ufw allow OpenSSH
      ufw allow 'Nginx Full'
      # 내부 포트는 localhost에서만 접근 가능하도록 설정
      ufw --force enable
      
      # 6. 인스턴스 메타데이터 가져오기
      echo "Getting instance metadata..."
      INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
      PRIVATE_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4)
      REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)
      
      echo "Instance ID: $INSTANCE_ID"
      echo "Private IP: $PRIVATE_IP"
      echo "Region: $REGION"
      
      # 7. 환경 변수 설정 - AWS Parameter Store에서 가져오기 (옵션)
      echo "Setting up environment variables..."
      mkdir -p /home/ubuntu/codeplanner
      cat > /home/ubuntu/codeplanner/.env << EOF
      NODE_ENV=production
      INSTANCE_ID=$INSTANCE_ID
      PRIVATE_IP=$PRIVATE_IP
      BACKEND_URL=http://localhost:5000
      FRONTEND_URL=http://localhost:3000
      DATABASE_URL=postgresql://username:password@your-db-host:5432/codeplanner
      EOF
      chown ubuntu:ubuntu /home/ubuntu/codeplanner/.env
      
      # 8. 프로젝트 클론 및 설정
      echo "Cloning projects..."
      cd /home/ubuntu/codeplanner
      chown -R ubuntu:ubuntu /home/ubuntu/codeplanner
      
      # Backend 클론 및 설정
      echo "Setting up backend..."
      if [ ! -d "Codeplanner_Backend" ]; then
        sudo -u ubuntu git clone https://github.com/Krafton-Jungle-Weight/Codeplanner_Backend.git
      else
        cd Codeplanner_Backend
        sudo -u ubuntu git pull origin main
        cd ..
      fi
      
      # Frontend 클론 및 설정
      echo "Setting up frontend..."
      if [ ! -d "Codeplanner_Frontend" ]; then
        sudo -u ubuntu git clone https://github.com/Krafton-Jungle-Weight/Codeplanner_Frontend.git
      else
        cd Codeplanner_Frontend
        sudo -u ubuntu git pull origin main
        cd ..
      fi
      
      # 9. 백엔드 설치 및 실행
      echo "Installing and starting backend..."
      cd /home/ubuntu/codeplanner/Codeplanner_Backend
      chown -R ubuntu:ubuntu .
      
      # 의존성 설치
      sudo -u ubuntu npm install
      if [ $? -ne 0 ]; then
          echo "Backend npm install failed"
          exit 1
      fi
      
      # 빌드
      sudo -u ubuntu npm run build
      if [ $? -ne 0 ]; then
          echo "Backend build failed"
          exit 1
      fi
      
      # PM2로 백엔드 시작
      sudo -u ubuntu pm2 start ecosystem.config.js --env production
      if [ $? -ne 0 ]; then
          echo "Backend PM2 start failed"
          exit 1
      fi
      
      # 10. 프론트엔드 설치 및 실행
      echo "Installing and starting frontend..."
      cd /home/ubuntu/codeplanner/Codeplanner_Frontend
      chown -R ubuntu:ubuntu .
      
      # 의존성 설치
      sudo -u ubuntu npm install
      if [ $? -ne 0 ]; then
          echo "Frontend npm install failed"
          exit 1
      fi
      
      # 빌드
      sudo -u ubuntu npm run build
      if [ $? -ne 0 ]; then
          echo "Frontend build failed"
          exit 1
      fi
      
      # PM2로 프론트엔드 시작
      sudo -u ubuntu pm2 start ecosystem.config.js --env production
      if [ $? -ne 0 ]; then
          echo "Frontend PM2 start failed"
          exit 1
      fi
      
      # 11. 서비스 시작 및 활성화
      echo "Starting services..."
      systemctl enable nginx
      systemctl start nginx
      systemctl status nginx
      
      # PM2 설정 저장 및 부팅 시 자동 시작 설정
      sudo -u ubuntu pm2 save
      sudo -u ubuntu pm2 startup systemd -u ubuntu --hp /home/ubuntu
      
      # 12. 헬스 체크 및 검증
      echo "Performing health checks..."
      sleep 30
      
      # Nginx 상태 확인
      if ! systemctl is-active --quiet nginx; then
          echo "Nginx is not running"
          exit 1
      fi
      
      # PM2 프로세스 확인
      PM2_STATUS=$(sudo -u ubuntu pm2 list | grep -c "online")
      if [ "$PM2_STATUS" -lt 2 ]; then
          echo "Not all PM2 processes are online"
          sudo -u ubuntu pm2 list
          exit 1
      fi
      
      # 로컬 헬스 체크
      if ! curl -f http://localhost/health; then
          echo "Health check failed"
          exit 1
      fi
      
      # 13. CloudWatch 로그 설정 (옵션)
      echo "Setting up CloudWatch logs..."
      cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << 'EOF'
      {
          "logs": {
              "logs_collected": {
                  "files": {
                      "collect_list": [
                          {
                              "file_path": "/var/log/nginx/access.log",
                              "log_group_name": "/aws/ec2/codeplanner/nginx",
                              "log_stream_name": "{instance_id}/access.log"
                          },
                          {
                              "file_path": "/var/log/nginx/error.log",
                              "log_group_name": "/aws/ec2/codeplanner/nginx",
                              "log_stream_name": "{instance_id}/error.log"
                          },
                          {
                              "file_path": "/home/ubuntu/.pm2/logs/*.log",
                              "log_group_name": "/aws/ec2/codeplanner/app",
                              "log_stream_name": "{instance_id}/app.log"
                          }
                      ]
                  }
              }
          }
      }
      EOF
      
      # 14. 최종 상태 확인 및 로깅
      echo "Final status check..."
      echo "Nginx status: $(systemctl is-active nginx)"
      echo "PM2 processes:"
      sudo -u ubuntu pm2 list
      
      # 성공 메시지
      echo "UserData script completed successfully at $(date)"
      echo "Instance is ready for service"
      
      # ALB 헬스 체크를 위한 추가 대기
      echo "Waiting for services to be fully ready..."
      sleep 60
      
      exit 0

      주요 개선사항

      1. 오토스케일링 최적화

    • 에러 처리: set -e로 에러 발생 시 스크립트 중단

    • 상세 로깅: 모든 단계별 로그 기록

    • 헬스 체크: 서비스 시작 후 상태 검증

      2. Nginx 설정 개선

    • localhost 사용: 하드코딩된 IP 문제 해결

    • API 프록시: 백엔드 API 경로 분리

    • 헬스 체크 엔드포인트: ALB 헬스 체크용

      3. 보안 강화

    • 방화벽 최적화: 필요한 포트만 개방

    • 환경 변수 분리: 설정 정보 외부화

    1. 모니터링 준비
    • CloudWatch 로그: 애플리케이션 로그 수집 준비

      인스턴스 메타데이터: 디버깅용 정보 수집

    1. 안정성 향상
    • 의존성 검증: 각 단계별 성공/실패 확인

    • 서비스 자동 시작: 부팅 시 자동 실행 설정

    • 대기 시간: ALB 헬스 체크 안정화


      2. Launch Template 생성

      CLI 예시

      aws ec2 create-launch-template \
        --launch-template-name "codeplanner-optimized-template" \
        --launch-template-data '{
          "ImageId": "ami-0c02fb55956c7d316",
          "InstanceType": "t3.small",
          "KeyName": "your-key-pair",
          "SecurityGroupIds": ["sg-xxxxxxxxx"],
          "UserData": "'$(base64 -w 0 userdata.sh)'",
          "IamInstanceProfile": {
            "Name": "EC2-CodePlanner-Role"
          },
          ...
        }'

      3. Auto Scaling Group 설정

      aws autoscaling create-auto-scaling-group \
        --auto-scaling-group-name "codeplanner-asg-v2" \
        --launch-template '{"LaunchTemplateName":"codeplanner-optimized-template","Version":"$Latest"}' \
        --min-size 1 \
        --max-size 5 \
        --desired-capacity 2 \
        --target-group-arns "arn:aws:elasticloadbalancing:..." \
        --vpc-zone-identifier "subnet-xxxxx,subnet-yyyyy"

      4. 핵심 설정 포인트

      4-1. Nginx 프록시 구성 (프론트엔드 nginx.conf)

      server {
          listen 80;
          server_name code-planner.com;
          server_name _;
          
          # 프론트엔드 정적 파일 서빙
          location / {
              # rewrite ^/(.*)$ /maintenance break;  # 서버 점검시 주석 해제, 점검완료시 주석
              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_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_cache_bypass $http_upgrade;
          }
          
          # API 요청을 백엔드로 프록시 + CORS 헤더 및 OPTIONS 처리
          location /api/ {
              # rewrite ^/(.*)$ /maintenance break;  # 서버 점검시 주석 해제, 점검완료시 주석
              proxy_pass http://localhost:5000/api/;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
              proxy_set_header x-github-event $http_x_github_event;
              proxy_cache_bypass $http_upgrade;
      
              # CORS 헤더 추가
              add_header 'Access-Control-Allow-Origin' '*' always;
              add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
              add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
              add_header 'Access-Control-Allow-Credentials' 'true' always;
      
              # OPTIONS preflight 요청 처리
              if ($request_method = 'OPTIONS') {
                  add_header 'Access-Control-Allow-Origin' '*';
                  add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
                  add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
                  add_header 'Access-Control-Allow-Credentials' 'true';
                  add_header 'Content-Length' 0;
                  add_header 'Content-Type' 'text/plain charset=UTF-8';
                  return 204;
              }
          }
      }
      

      4.2 환경 변수 관리 (SSM Parameter Store 사용)

      aws ssm put-parameter \
        --name "/codeplanner/database-url" \
        --value "your-database-connection-string" \
        --type "SecureString"
      
      DB_URL=$(aws ssm get-parameter --name "/codeplanner/database-url" --with-decryption --query 'Parameter.Value' --output text)
      echo "DATABASE_URL=$DB_URL" >> /home/ubuntu/codeplanner/.env
      

      4.3 Health Check

      aws elbv2 modify-target-group \
        --target-group-arn "arn:..." \
        --health-check-path "/" \
        --health-check-protocol "HTTP" \
        --health-check-port "80" \
        --healthy-threshold-count 2 \
        --unhealthy-threshold-count 3

      5. CloudFront 구성

      5-1. Origin Request Policy

      {
        "Name": "CodePlanner-Production-Policy",
        "HeadersConfig": {
          "HeaderBehavior": "whitelist",
          "Headers": {
            "Items": [
              "Authorization", "Accept", "Accept-Language",
              "User-Agent", "Referer", "Host",
              "Access-Control-Request-Method", "Access-Control-Request-Headers"
            ]
          }
        },
        "CookiesConfig": { "CookieBehavior": "all" },
        "QueryStringsConfig": { "QueryStringBehavior": "all" }
      }

      5-2. Cache Policy (동적 콘텐츠용)

      {
        "Name": "CodePlanner-Dynamic-Cache",
        "DefaultTTL": 0,
        "MaxTTL": 31536000,
        "MinTTL": 0,
        "ParametersInCacheKeyAndForwardedToOrigin": {
          "EnableAcceptEncodingGzip": true,
          "EnableAcceptEncodingBrotli": true,
          "QueryStringsConfig": { "QueryStringBehavior": "all" },
          "HeadersConfig": { "HeaderBehavior": "none" },
          "CookiesConfig": { "CookieBehavior": "all" }
        }
      }

      6. CloudWatch 및 로그 수집

      6-1. CloudWatch Agent 설치

      wget https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
      rpm -U ./amazon-cloudwatch-agent.rpm

      6.2 로그 수집 설정

      {
        "logs": {
          "logs_collected": {
            "files": {
              "collect_list": [
                {
                  "file_path": "/var/log/nginx/access.log",
                  "log_group_name": "/aws/ec2/codeplanner/nginx",
                  "log_stream_name": "{instance_id}/access.log"
                },
                {
                  "file_path": "/home/ubuntu/.pm2/logs/*.log",
                  "log_group_name": "/aws/ec2/codeplanner/app",
                  "log_stream_name": "{instance_id}/app.log"
                }
              ]
            }
          }
        }
      }

      7. 배포 자동화 (CodeDeploy 기반)

      7-1. AppSpec

      version: 0.0
      os: linux
      files:
        - source: /
          destination: /home/ubuntu/codeplanner
      hooks:
        BeforeInstall:
          - location: scripts/stop_application.sh
        ApplicationStart:
          - location: scripts/start_application.sh
        ApplicationStop:
          - location: scripts/stop_application.sh

      7-2. 애플리케이션 재시작 스크립트

      #!/bin/bash
      
      cd /home/ubuntu/codeplanner/frontend
      npm install
      npm run build
      pm2 restart frontend
      
      cd ../backend
      npm install
      npm run build
      pm2 restart backend
      
      systemctl reload nginx

      8. 보안 강화

      8-1. IAM Role 권한 최소화

      {
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "ssm:GetParameter",
              "ssm:GetParameters",
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents"
            ],
            "Resource": "*"
          }
        ]
      }

      8.2 Security Group 제한

      aws ec2 authorize-security-group-ingress \
        --group-id sg-xxxxxxxxx \
        --protocol tcp --port 80 --source-group sg-alb-xxxxxxxxx
      
      aws ec2 authorize-security-group-ingress \
        --group-id sg-xxxxxxxxx \
        --protocol tcp --port 443 --source-group sg-alb-xxxxxxxxx

      요약

      항목내용
      IP 하드코딩 방지localhost 기반 Nginx 설정
      SSR 대응 캐시 정책CloudFront Origin/Cache Policy 최적화
      환경 변수 보안 관리AWS SSM Parameter Store 사용
      인스턴스 재현성 확보Launch Template + UserData로 통일
      로깅 및 모니터링CloudWatch Agent 통한 접근/앱 로그 수집
      보안 구성IAM 최소 권한, SG 최소 개방
      배포 자동화CodeDeploy + AppSpec + Hook 기반

      이 구성을 기준으로 하면, 이전에 겪었던 RSC 데이터 노출, 설정 누락, 인증 실패, 캐시 문제, 신규 인스턴스 불안정 등의 문제를 자동화된 방식으로 완전히 방지할 수 있습니다.

시나리오 정하기 (14:30 ~ 18:00)

팀원분들과 어제 미리 생각해오기로 했던, 우리의 서비스 정체성과 시나리오를 이야기 했다.
전체 종합한 내용은 다음과 같다.

Codeplanner 목적/시나리오

목적

Jira와 같은 이슈트레킹을 학습하고 각 기업들에 이슈처리 프로세스를 벤치마킹하여 소규모, 대학생 등의 소단위 프로젝트에 도입할만한 이슈트레킹 서비스이다. 추가 기능으로 Ai를 통한 이슈 자동 생성, 코드 품질 검사를 통해 편리함을 제공하기도 한다. (+ 자신의 프로젝트에 대한 정리도 제공)

흐름

  1. 회의록을 통해서 PM이나 조장이 AI 자동화로 이슈 생성
  2. 백로그에는 이슈 담당자가 배정이 안되있는 것들에 대해 모음이다. (칸반엔 없음)
  3. 해당 이슈는 Todo에 등록되고 담당된 팀원에 알람이 간다. 프로젝트의 흐름을 파악할 필요가 있기 때문. (다른부서 협업)
  4. 담당자를 배정하면 해당 담당자와 관리자에게 알람이 간다.
  5. 담당자가 개발자라면 커밋을 하므로써 In Progress 단계로 전환된다.
  6. 커밋을 통해 코드 품질 검사가 완료되면 In Review 상태로 넘어간다. 관리자에게 알림이 전송되고 리뷰를 한다. 이때, 리뷰어는 다른 팀(디자인, 개발, PM 등)일 수 있다. (백로그 삭제)
  7. 리뷰를 하는 단계에서 멘션을 통해 해당 부서나 조직에 알림을 보낼 수 있다. (커뮤니티) 문제사항들에 대해 해결을 한다.
  8. 거부시, In Progress 상태로 롤백되고 작업이 완료되면 다시 리뷰를 받을 수 있다. (해당과정 루프 가능)
  9. 허용시, PR까지 해서 완벽하게 이슈가 완료되었다면 Done으로 이동된다. 삭제?

+Story같은 경우 딸린 테스크가 완료되면 Story도 Done된다.
이거는 태스크랑 서브테스크로만 관리

+버그도 비슷하게 처리할 것인가?
포함하자. 하나의 이슈로 추가할 수 있다.

상황

PM과 개발자가 하나의 소프트웨어 개발 프로젝트를 진행하는 상황이다. 상황극은 X.

  1. PM이 회의를 통해서 작성한 회의록으로 이슈 자동화를 통해 이슈를 생성한다.
  2. 해당 이슈들에 대해 백로그로 간다. 그러면 이슈들에 대해 담당자를 알맞게 배정한다.
  3. 담당자와 관리자가 배정되면 Todo로 이동되며 해당 인원에게 알람이 간다.
  4. 담당 개발자는 커밋을 하므로써 In Progress 단계에 접어들게 된다. (여기서 커밋시 자동으로 넘어가는것에 대해 말씀드리기, 수동도 가능)
  5. 여러 커밋을 통해서 코드 품질 검사까지 완료된다면(코드품질검사를 꼭 통과 안되도 가능하다), In review 상태로 변환이 되서 관리자에게 알람이 가서 컨펌을 받는다. 해당 단계에서 PR도 포함한다.
  6. 컨펌 결과 거부가된다면, In progress 상태로 롤백되고 담당개발자는 재작업을 한다. 재작업이 완료되면 In review 상태로 옮겨서 다시 컨펌 받을 수 있다. (여부에 따라 해당 과정이 루프를 돌 수 있다.)
  7. 컨펌 결과가 통과된다면, 담당 개발자가 병합 충돌까지 해결해서 올린다. 모두 완료된 이슈라면 Done으로 이동한다.

[유윤선 코치님 피드백]

인원구성 셋트가 유동적으로 정할 수 있으면 좋겠다. 역할군이 다르니까

현업에서 그대로 가져와도된다. AI도 가능

TF 팀 정도의 규모라고 생각하고 설명.

18:00 ~ 19:00

식사와 휴식을 가졌다. 좀잇다 야식을 먹어서 간단히 먹었다.

19:00 ~ 21:30

어제와 오늘까지 오토스케일링을 정상 가동하기 위해 아마존 Q와 함께 해결한 내용을 정리 했다. 원래 이렇게 오래 걸리는게 아닌데, Nginx로 꼬여서 오래 걸렸다. 이것 저것도 할 것도 많고… 그래도 나중에는 트러블 슈팅 내용대로 문제를 해결하면 되니 다행이다. 미리 오토스케일링 EC2 올리는 방법도 정리해둬서 든든하다. 실제로 되는지 테스트 해보진 않았지만, 그땐 아마존 Q의 도움을 받으면 되니 상관없을 것 같다.

21:30 ~ 22:00

멘토님께 피드백 내용 정리해서 이메일 작성하고 다음주 피드백 일정 잡았다.
내용으로 전송을 완료했다.

22:00 ~ 23:00

운동하기

23:00 ~ 01:00

기윤 형님의 생일이었기 때문에 식사를 하고 씻고 왔다.

01:00 ~ 03:30

권호: 이슈별 부서 표시, 부서별 요약 제공
윤호: C언어 코드 품질 검사 구현, 결과창 구현(시간되면 목록 리스트 리팩토링)
명석: PR에서 PR 파일 변동 내역, Merge까지 완료될 수 있도록 제공
진혁: 권한별 페이지 분리 구현
나: 오토스케일링 관련 내용 정리, 폴리싱할 내용들 확인(동적 테스트), 서버 안정화 테스트, 상황이 된다면 오토스케일링 자동 업데이트 고려,
프로젝트에서 종료시 내용 요약 여부 확인(핵심)

먼저, 팀 노션의 CI/CD, Devops, 전체적인 흐름, 시나리오 등을 모두 정리했다.

지금 작업 중인것 외의 부족한 점 찾기 (프로젝트 QA 동적검사)

갑자기 생각난건데, 프로젝트에서 버그 같은 유형은 High, mid, low 등으로 중요도를 확인할 수 있어야할 것 같음.

  1. Welcome 페이지 맨 밑의 Code Planner 핵심 기능 내용 수정 (구현내용 기반)
  2. 로그인: 화면 내용 수정 및 위치 통일화
  3. 회원가입: 내용 수정 및 위치 통일화, 마케팅 정보 관련 내용 삭제
  4. 비밀번호 찾기 후 화면 개선
  5. 헤더: 알림에 알림 삭제 기능 추가, 모든 알림보기 구현
    로그인 중인 프로필 제대로 출력, 프로필 사진은 마이페이지에 있는 프로필로
  6. 마이페이지: 닉네임 중복검사?, 회원 탈퇴 기능 추가, 비밀번호 변경 추가
  7. 프로젝트 리스트: 새 프로젝트 생성에서 모달 길이가 너무 길어서 버튼이 안눌리는 문제 해결
  8. 내이슈: 전체적인 폼 리팩토링 필요, 클릭했을때 나온 모달창 또한 리팩토링 필요.
    단번에 찾을 수 있게 정렬기능 추가.
  9. 요약 페이지: 상단에 전체 요약 4개 색상 카드 추가, 최근 활동 6개까지 제한
    오른쪽 아래에 각 부서별 현황 요약 막대 도표 추가(추가된다면 최근 활동하고 자리 바꿔야할듯)
  10. 타임 라인: 진행률이 소수점으로 보이는 문제 있음.
    이슈카드 색상 추가.
    가능하다면 간트차트 한글화.
    프로젝트 개요 존재 이유?
  11. 보드: 담당자 표시는 가독성 높은걸로 바껴야할 것 같다.
    이슈카드 클릭했을 때 모달창을 리팩토링할 필요성이 있음.
    이슈카드 프리뷰에 설명에 대한 요약이 있을게 아니면 카드 크기를 줄일 필요가 있고, 카드를 포함하는 박스도 어느정도 제한이 있어야할 것 같다.
  12. 목록: 디자인 폼 자체를 리팩토링해야한다. 또는 겹친다고 판단되면 삭제도 고려 쓸거면 제대로 구현
    담당자와 보고자 번호가 이상한 문제를 해결해야한다.
    이슈 추가 버튼 삭제
  13. 코드: 어느정도 브랜치, 커밋 , PR 슬롯에 대한 클릭 폼이 바껴야할 것 같다.
    저장소 정보도 가독성과 여백 조절이 필요할 것 같다.
  14. AI 이슈 생성: 폼 리펙토링 필요성 있음. (중요성 낮음)
    모달 창에서 특정 버튼 안눌리는 오류 수정.
    역대 AI 이슈 생성 기록 조회(종복성에 대한 의도성이 있음.)
  15. 설정: 팀관리 같은경우 권한 설정이 되야한다.
    팀원 관리는 전체 유저 목록이 아닌 초대쪽으로 바꿔야할 것 같다. (URL 초대?)
    X 표시 오른쪽으로 이동
    프로젝트 삭제는 한번정도 확인
  16. +프로젝트에 대한 전체 요약들을 제공해야한다.

앞으로 폴리싱하다가 충돌나는 경우가 매우 많을 것 같으니, 내일 정확하게 작업 공간을 정해야함.

03:30 ~ 04:30

벨로그를 정리해보았다.
우리의 폴더 구조도를 만들어봤다.

📦Codeplanner_Frontend
 ┣ 📂app                        # Next.js App Router의 메인 폴더
 ┃ ┣ 📂api                       # (비어있음/미정의) API 관련 폴더
 ┃ ┣ 📂auth                      # 인증 관련 페이지 및 컴포넌트
 ┃ ┃ ┣ 📂emailVerified             # 이메일 인증 관련
 ┃ ┃ ┣ 📂forgot-password           # 비밀번호 찾기
 ┃ ┃ ┣ 📂github-oauth              # 깃허브 OAuth 로그인
 ┃ ┃ ┣ 📂login                     # 로그인
 ┃ ┃ ┣ 📂needEmail                 # 이메일 필요 안내
 ┃ ┃ ┗ 📂reset-password            # 비밀번호 재설정
 ┃ ┣ 📂error                      # 에러 페이지
 ┃ ┣ 📂maintenance                # 점검 안내 페이지
 ┃ ┣ 📂not-found.tsx              # 404 Not Found 페이지
 ┃ ┣ 📂projectList                # 프로젝트 리스트 및 깃허브 연동
 ┃ ┣ 📂projects                   # 개별 프로젝트 관련 라우팅
 ┃ ┃ ┣ 📂[projectId]                # 동적 라우팅: 프로젝트별
 ┃ ┃ ┃ ┣ 📂board                      # 칸반보드
 ┃ ┃ ┃ ┣ 📂code                       # 코드/Pull Request
 ┃ ┃ ┃ ┣ 📂issue                      # 이슈 상세
 ┃ ┃ ┃ ┣ 📂issue-generater-ai         # AI 이슈 생성
 ┃ ┃ ┃ ┣ 📂list                       # 이슈 리스트
 ┃ ┃ ┃ ┣ 📂my-issues                  # 내 이슈
 ┃ ┃ ┃ ┣ 📂settings                   # 프로젝트 설정
 ┃ ┃ ┃ ┣ 📂summary                    # 프로젝트 요약
 ┃ ┃ ┃ ┗ 📂timeline                   # 간트차트 등 타임라인
 ┃ ┣ 📂user                       # 유저 관련 페이지
 ┃ ┃ ┣ 📂create                      # 회원가입
 ┃ ┃ ┗ 📂mypage                      # 마이페이지
 ┃ ┣ 📂welcome                    # 웰컴 페이지
 ┃ ┣ layout.tsx                   # 전체 레이아웃
 ┃ ┣ globals.css                  # 전역 스타일
 ┃ ┗ page.tsx                     # 루트 페이지
 ┣ 📂components                  # 전역 컴포넌트
 ┃ ┣ 📂auth-layout                 # 인증 레이아웃
 ┃ ┣ 📂header                      # 헤더
 ┃ ┣ 📂icons                       # 아이콘 컴포넌트
 ┃ ┣ 📂theme-provider              # 테마 관련
 ┃ ┗ 📂ui                          # 버튼, 모달 등 UI 요소
 ┣ 📂lib                         # API, 유틸 함수 등
 ┣ 📂public                      # 정적 파일 (이미지, 파비콘 등)
 ┣ 📂scripts                     # 배포/운영 스크립트
 ┣ components.json
 ┣ DEPLOYMENT.md
 ┣ ENVIRONMENT_SETUP.md
 ┣ GITHUB_SECRETS_SETUP.md
 ┣ jsconfig.json
 ┣ next-env.d.ts
 ┣ next.config.mjs
 ┣ nginx.conf
 ┣ package.json
 ┣ postcss.config.mjs
 ┣ README.md
 ┣ tailwind.config.ts
 ┣ tsconfig.json
profile
모든걸 기록하며 성장하고 싶은 개발자입니다. 현재 크래프톤 정글 8기를 수료하고 구직활동 중입니다.

0개의 댓글