프로젝트 배경 및 개발 동기
Autowini에서는 React로 분리 및 개선한 프론트엔드 프로젝트들이 여러 개 존재합니다.
대표적으로 web-www-front (오토위니 웹), web-mobile-front (모바일 웹), web-admin-front (관리자 페이지) 등이 있습니다.
기존 JSP 기반 페이지들 중 방문자 수가 많고 이슈가 잦은 페이지부터 차례로 React로 분리 및 개선 작업을 진행하고 있었습니다.
이 분리된 React 페이지들은 IDC 서버에 업로드된 빌드 결과물을 서비스하는 구조로, 기존에는 개발이 완료된 후 develop 브랜치에 머지하고, CLI를 통해 직접 IDC에 빌드 파일을 업로드하는 방식으로 운영하고 있었습니다.
하지만 혼자 개발하는 환경이라면 문제가 없겠지만, 휴가 시 사수가 대신하거나 신규 프론트엔드 개발자가 투입될 경우, 직접 CLI로 IDC에 파일을 업로드하는 방식은 여러 혼란과 문제를 야기할 수 있다고 생각했습니다.
예를 들어, develop 브랜치에 머지하지 않은 상태에서 개발 브랜치에서 빌드 파일을 IDC에 올리면, 개발 서버에 표시되는 화면과 실제 develop 브랜치의 코드가 불일치하는 상황이 발생할 수 있습니다.
이러한 문제를 근본적으로 해결하기 위해, 안정적이고 일관된 CI/CD 파이프라인을 구축하기로 결정했습니다.
초기 시도와 문제점
GitHub Copilot의 도움으로 bitbucket-pipelines.yml 파일을 생성하여 아래와 같이 파이프라인을 작성했습니다.(보안을 위해 IP 주소, 사용자명, 패스워드 변수명 등 민감한 정보는 가려서 표시하였습니다. 실제 파이프라인 설정 시에는 별도의 환경변수로 관리하시기 바랍니다.)
# Autowini Frontend Pipeline Configuration
# Node.js 20 이미지 사용 (프로젝트 요구사항에 맞춤)
image: node:20
definitions:
caches:
pnpm: ~/.pnpm-store
pipelines:
branches:
develop:
- step:
name: 'Build and Deploy to Dev Server'
caches:
- pnpm
script:
# pnpm 설치
- npm install -g pnpm@10.6.3
# 의존성 설치
- pnpm install
# 개발 서버용 빌드
- pnpm build:dev
# sshpass 설치 (비밀번호 인증용)
- apt-get update && apt-get install -y sshpass
# SSH known_hosts에 서버 추가
- mkdir -p ~/.ssh
- ssh-keyscan -H $DEPLOY_SERVER_IP >> ~/.ssh/known_hosts 2>/dev/null
# SCP를 통한 파일 업로드 (비밀번호 인증)
# Repository Settings > Pipelines > Repository variables에서 SSH_PASSWORD 설정 필요
- sshpass -p "$SSH_PASSWORD" scp -r dist/* $DEPLOY_USER@$DEPLOY_SERVER_IP:$DEPLOY_TARGET_PATH
artifacts:
- dist/**
- develop 브랜치에서 빌드 후 IDC 서버로 scp를 이용해 빌드 결과물을 전송하는 스크립트를 작성했습니다.
- Repository 변수에 SSH 비밀번호(SSH_PASSWORD)를 설정해 비밀번호 인증으로 연결했습니다.
하지만 문제는 Bitbucket Pipelines의 IP가 IDC 방화벽에 허용되지 않아 접속이 계속 타임아웃된다는 점이었습니다.
문제 분석 및 해결 과정
bitbucket공식 문서(https://support.atlassian.com/bitbucket-cloud/docs/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall/)를 참고하여 bitbucket.org, api.bitbucket.org, altssh.bitbucket.org의 IPv4 inbound IP 리스트를 확인 후 팀장님께 전달해 협력사인 메가존 IDC에 방화벽 허용 요청을 했습니다.
하지만 파이프라인 재실행 시 동일한 오류가 계속 발생했습니다.
파이프라인 내부에서 디버깅을 위해 실제로 파이프라인 실행 환경에서 사용 중인 외부 접속 IP를 출력해 보니 아래와 같았습니다.
52.90.48.7
52.0.3.221
44.208.32.148
...
출력된 IP들은 허용 목록에 포함되지 않았고, 조회 결과 AWS EC2 대역이라는 사실을 확인했습니다. Bitbucket Pipelines는 내부적으로 Atlassian이 관리하는 AWS 인프라 위에서 실행되기 때문에, 파이프라인이 수행되는 런타임 환경도 AWS EC2 IP를 사용합니다. 이 때문에 고정된 특정 IP가 아닌, AWS가 할당하는 다양한 퍼블릭 IP가 표시되며, IDC 방화벽에서 특정 IP만 허용하는 형태의 접근 통제가 어려운 구조라는 점도 함께 파악할 수 있었습니다.
(참고 EC2 IP: https://ip-ranges.amazonaws.com/ip-ranges.json)
내부 논의 및 Bitbucket 지원팀 문의
사내 인프라를 담당하는 백엔드 개발자분과 논의한 결과, AWS 전체 IP 대역을 방화벽에 허용하는 방식은 보안상 적절하지 않을 뿐만 아니라 관리 측면에서도 비효율적이라는 결론에 도달했습니다. 이에 따라 CI는 Bitbucket Pipelines에서 수행하고, CD는 젠킨스와 같은 내부 시스템에서 처리하는 대안도 함께 검토하게 되었습니다.
그러던 중 다른 백엔드 개발자 분의 추천으로 Bitbucket에 공식 문의를 넣어 보게 되었고, Bitbucket AI로부터 아래와 같은 중요한 답변을 받았습니다.
Bitbucket Pipelines에서 SSH 연결을 위한 핵심 가이드
- SSH 접근이 필요한 파이프라인 스텝은 최소 size: 4x 이상으로 설정해야 한다.
- runtime.cloud.atlassian-ip-ranges: true 옵션을 활성화해야 한다.
pipelines:
default:
- step:
size: 4x4x # step size 4x 적용
runtime:
cloud:
atlassian-ip-ranges: true # Atlassian 고정 IP 사용 설정
script:
- <이하 동일>
- 이렇게 하면 Bitbucket Pipelines가 Atlassian이 관리하는 고정 IP 풀을 사용하여 IDC 방화벽에서도 안정적으로 접속할 수 있습니다.
결론 및 느낀 점
Bitbucket Pipelines에서 안정적으로 SSH 접속을 하기 위해서는 bitbucket-pipelines.yml 파일에 size: 4x 이상을 설정하고 atlassian-ip-ranges 옵션을 활성화하는 것이 필수적이었습니다. 이 설정을 적용한 뒤 IDC 방화벽에 Atlassian 고정 IP를 허용하자, 이전에 발생하던 SSH 타임아웃 문제가 완전히 해결되었고, 안정적인 CI/CD 파이프라인 운영이 가능해졌습니다.
이 문제를 해결하기 위해 이전에도 하루, 어제도 거의 하루를 소모하며 원인을 찾았지만 쉽게 해결되지 않았습니다. 마지막 시도로 Bitbucket 팀에 문의를 넣어보려던 순간, Bitbucket AI가 해결의 핵심을 알려주었고 덕분에 빠르게 문제를 해결할 수 있었습니다. 이번 파이프라인 구축을 통해 버전 관리와 배포 프로세스가 한층 체계화되어, 앞으로 팀 전체에도 큰 도움이 될 것 같습니다.
'지식 정리 📝' 카테고리의 다른 글
| React SPA에서 메타 태그 중복 문제, 라이브러리 제작으로 해결하기 (feat. react-head-safe) (0) | 2026.01.09 |
|---|---|
| React i18n 다국어 처리 빌드 크기 최적화 2 (0) | 2025.12.30 |
| GitHub Copilot을 활용한 사용하지 않는 번역 키 제거 (0) | 2025.11.13 |
| Autowini WEB 통합 프로젝트 Vitest 테스트 시스템 도입 (1) | 2025.10.17 |
| 확장자는 JPG인데 Windows에서 열리지 않는 이미지 문제 해결한 방법 (0) | 2025.09.02 |