블로그로 돌아가기

CI/CD 파이프라인을 위한 프록시: GitHub Actions, GitLab CI 및 Jenkins를 통한 비공식 리소스 접근 설정

CI/CD 파이프라인에서 프록시 설정에 대한 완벽한 가이드: GitHub Actions, GitLab CI 및 Jenkins. 지리적 차단을 우회하고, 비공식 API에 접근하며, 프록시를 통해 빌드를 가속화하는 방법.

📅2026년 5월 16일
```html

외부 API에 접근하거나 종속성을 다운로드하려고 할 때 403 Forbidden 또는 Connection refused 오류가 발생하나요? 아마도 CI/CD 서버의 IP 주소가 리소스 측에서 차단되었기 때문입니다. 프록시는 이 문제를 해결합니다: 필요한 IP를 통해 트래픽을 라우팅하면 파이프라인이 중단 없이 작동합니다. 이 기사에서는 GitHub Actions, GitLab CI 및 Jenkins에 대한 단계별 지침을 제공합니다.

CI/CD에서 프록시가 필요한 이유: 실제 시나리오

CI/CD 파이프라인은 고정 IP 주소를 가진 서버에서 작동합니다 — GitHub, GitLab의 클라우드 러너 또는 자체 Jenkins 에이전트에서. 이러한 IP는 잘 알려져 있으며, 많은 외부 서비스가 이를 차단하거나 요청 수를 제한합니다. 다음은 프록시 없이는 해결할 수 없는 구체적인 상황입니다:

지리적 제한 리소스 접근하기

많은 기업 npm 레지스트리, Maven 리포지토리 및 내부 API는 특정 국가 또는 IP 범위에서만 접근할 수 있습니다. GitHub Actions 러너가 대상 서비스의 방화벽 수준에서 차단된 지역에 있는 경우, 파이프라인은 종속성을 다운로드하거나 데이터를 전송할 수 없습니다. 필요한 지리적 위치의 프록시는 인프라를 변경하지 않고 이 문제를 해결합니다.

속도 제한 및 IP 차단

GitHub Actions의 클라우드 러너는 Microsoft Azure의 IP 범위를 사용합니다. 많은 공개 API는 이러한 범위를 알고 있으며, 엄격한 제한을 적용하거나 완전히 차단합니다. 예를 들어, 공개 데이터 파싱, 테스트 중 외부 API 요청, 제한된 CDN에서 배포판 다운로드 등은 클라우드 러너의 IP 때문에 자주 실패합니다. 프록시를 통한 회전은 속도 제한을 우회할 수 있습니다.

실제 웹사이트와의 통합 테스트

통합 테스트가 실제 웹사이트나 마켓플레이스(Wildberries, Ozon, Avito, Amazon)에 접근하는 경우, 이러한 사이트는 매번 실행 시 러너에서 동일한 IP를 감지하고 빠르게 차단합니다. IP 회전이 가능한 프록시는 테스트가 CAPTCHA나 차단 없이 안정적으로 진행되도록 합니다.

내부 기업 리소스 접근하기

기업 네트워크는 종종 외부 세계로부터 차단되어 있습니다. 파이프라인이 내부 서버에 배포하거나 비공식 API에 접근해야 하는 경우, 기업 네트워크 내 프록시(또는 SOCKS5 터널)는 클라우드 러너와 폐쇄된 인프라 간의 다리가 됩니다.

광고 및 마케팅 통합 테스트

Facebook Ads API, TikTok Ads API 또는 Google Ads API와 작업하는 팀은 종종 CI/CD를 통해 캠페인 생성을 자동화합니다. 이러한 플랫폼은 IP에 대해 엄격한 규칙을 가지고 있습니다: 데이터 센터의 IP에서 오는 요청은 차단되거나 추가 인증을 요구할 수 있습니다. 파이프라인 내의 레지던스 프록시는 요청을 일반 사용자 트래픽처럼 보이게 합니다.

파이프라인에 적합한 프록시 유형 선택하기

프록시 유형 선택은 작업에 따라 다릅니다. CI/CD 파이프라인에 적합한 세 가지 옵션이 있으며, 각각의 장점과 제한 사항이 있습니다:

프록시 유형 속도 사이트 신뢰도 가장 적합한 용도
데이터 센터 프록시 매우 높음 중간 종속성 다운로드, 내부 리포지토리, 엄격한 검사가 없는 빠른 API
레지던스 프록시 중간 높음 실제 웹사이트와의 통합 테스트, 광고 API(Facebook, TikTok), 마켓플레이스
모바일 프록시 중간 최고 모바일 API 테스트, 최대의 안티봇 보호가 있는 플랫폼 작업

실용적인 규칙:

작업이 패키지를 다운로드하거나 내부 서비스에 접근하는 것이라면 데이터 센터 프록시를 선택하세요 — 빠르고 저렴합니다. 실제 웹사이트에서 테스트하거나 광고 플랫폼과 작업하는 경우 레지던스 프록시가 필요합니다. SOCKS5 프로토콜이 HTTP/HTTPS보다 선호되며, 비표준 포트 및 프로토콜과 더 투명하게 작동합니다.

GitHub Actions에서 프록시 설정하기

GitHub Actions는 현재 가장 인기 있는 CI/CD 도구입니다. 여기서 프록시 설정은 환경 변수 및 리포지토리 비밀을 통해 이루어집니다. 단계별로 살펴보겠습니다.

1단계: 리포지토리 비밀에 프록시 데이터 추가하기

프록시 로그인 및 비밀번호를 YAML 워크플로 파일에 직접 입력하지 마세요. GitHub Secrets를 사용하세요:

  1. 리포지토리 열기 → SettingsSecrets and variablesActions
  2. New repository secret 클릭
  3. 형식이 PROXY_URL인 비밀을 생성하고 값은 http://user:[email protected]:port 형태로 입력하세요.

2단계: 워크플로에서 환경 변수 사용하기

대부분의 도구(curl, wget, npm, pip, Maven)는 표준 환경 변수 HTTP_PROXY, HTTPS_PROXYNO_PROXY를 자동으로 인식합니다. 워크플로 예시는 다음과 같습니다:

name: Build with Proxy

on: [push]

env:
  HTTP_PROXY: ${{ secrets.PROXY_URL }}
  HTTPS_PROXY: ${{ secrets.PROXY_URL }}
  NO_PROXY: localhost,127.0.0.1,internal.company.com

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        run: npm ci

      - name: Run integration tests
        run: npm test

      - name: Call external API
        run: |
          curl -v https://api.example.com/data

3단계: GitHub Actions에서 SOCKS5 프록시 사용하기

SOCKS5를 사용하는 경우(대부분의 작업에 권장됨) 표준 환경 변수로는 부족합니다 — 로컬 터널이 필요합니다. proxychains 유틸리티를 사용하거나 microsocks를 설정하세요:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Setup SOCKS5 proxy tunnel
        run: |
          sudo apt-get install -y proxychains4
          echo "socks5 proxy.host 1080 user password" >> /etc/proxychains4.conf

      - name: Run command through SOCKS5
        run: proxychains4 curl https://restricted-resource.com/api

특정 도구에 대한 프록시 설정하기

일부 도구는 시스템 변수를 무시하고 별도의 설정이 필요합니다:

도구 프록시 설정 방법
npm / yarn npm config set proxy http://user:pass@host:port
pip (Python) pip install --proxy http://user:pass@host:port package
Maven settings.xml<proxies> 섹션을 통해 설정
Gradle systemProp.https.proxyHost=hostgradle.properties에 추가
Git git config --global http.proxy http://user:pass@host:port
Docker build --build-arg HTTP_PROXY=http://user:pass@host:port

GitLab CI에서 프록시 설정하기

GitLab CI는 프로젝트, 그룹 또는 인스턴스 수준에서 환경 변수를 설정할 수 있는 여러 수준을 제공합니다. 이는 GitHub Actions에 비해 프록시 관리를 더 유연하게 만듭니다.

1단계: GitLab CI/CD Variables에 변수 추가하기

  1. 프로젝트 열기 → SettingsCI/CDVariables 섹션
  2. Add variable 클릭
  3. 형식이 PROXY_URL인 변수를 추가하고, 유형은 Masked (로그에서 값 숨김)으로 설정
  4. 값: http://user:[email protected]:port

2단계: .gitlab-ci.yml에서 변수 사용하기

variables:
  HTTP_PROXY: $PROXY_URL
  HTTPS_PROXY: $PROXY_URL
  NO_PROXY: "localhost,127.0.0.1,.internal.company.com"

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image: node:20-alpine
  script:
    - npm ci
    - npm run build

integration_tests:
  stage: test
  image: python:3.11
  script:
    - pip install -r requirements.txt
    - pytest tests/integration/

deploy:
  stage: deploy
  script:
    - curl -X POST https://api.external-service.com/deploy
      -H "Authorization: Bearer $DEPLOY_TOKEN"
      -d '{"version": "$CI_COMMIT_SHA"}'

특정 작업에만 프록시 사용하기

프록시가 항상 필요한 것은 아닙니다 (예: 통합 테스트에만 필요하고 빌드에는 필요하지 않은 경우), 특정 작업 수준에서 변수를 설정하고 전역적으로 설정하지 마세요:

integration_tests:
  stage: test
  variables:
    HTTP_PROXY: $PROXY_URL
    HTTPS_PROXY: $PROXY_URL
  script:
    - pytest tests/integration/

build:
  stage: build
  # 여기서는 프록시가 설정되지 않음 — 직접 연결
  script:
    - npm ci && npm run build

자체 호스팅 GitLab 러너: 러너 수준에서 프록시 설정하기

자체 GitLab 러너를 사용하는 경우, 러너 구성에서 전역적으로 프록시를 설정할 수 있습니다. /etc/gitlab-runner/config.toml 파일을 열고 [runners.env] 섹션에 추가하세요:

[[runners]]
  name = "my-runner"
  url = "https://gitlab.com/"
  token = "TOKEN"
  executor = "docker"
  environment = [
    "HTTP_PROXY=http://user:[email protected]:port",
    "HTTPS_PROXY=http://user:[email protected]:port",
    "NO_PROXY=localhost,127.0.0.1"
  ]

이는 해당 러너에서 모든 파이프라인이 프록시를 사용해야 할 때 편리합니다 — 각 .gitlab-ci.yml에 프록시를 입력할 필요가 없습니다.

Jenkins에서 프록시 설정하기

Jenkins는 세 가지 도구 중 가장 유연하지만 설정이 가장 복잡합니다. 여기서 프록시는 여러 수준에서 설정할 수 있습니다: Jenkins 전체에 대해 전역적으로, 특정 파이프라인에 대해 또는 개별 단계에 대해 설정할 수 있습니다.

방법 1: Jenkins의 전역 프록시 설정

  1. Manage JenkinsSystem 열기
  2. HTTP Proxy Configuration 섹션 찾기
  3. 서버, 포트, 사용자 이름, 비밀번호 필드 입력
  4. No Proxy Host 필드에 내부 주소를 쉼표로 구분하여 입력
  5. Test URL 클릭하여 확인하고 저장

이 설정은 플러그인 및 Jenkins 업데이트 다운로드에 영향을 미치지만 파이프라인 실행 환경에 자동으로 전달되지 않습니다. 파이프라인에는 별도의 구성이 필요합니다.

방법 2: Declarative Pipeline에서 environment를 통한 프록시 설정

pipeline {
    agent any

    environment {
        HTTP_PROXY  = credentials('proxy-url-credential')
        HTTPS_PROXY = credentials('proxy-url-credential')
        NO_PROXY    = 'localhost,127.0.0.1,internal.company.com'
    }

    stages {
        stage('Build') {
            steps {
                sh 'npm ci'
                sh 'npm run build'
            }
        }

        stage('Integration Tests') {
            steps {
                sh 'pytest tests/integration/'
            }
        }

        stage('Deploy') {
            steps {
                sh '''
                    curl -X POST https://api.external-service.com/deploy \
                    -H "Authorization: Bearer ${DEPLOY_TOKEN}" \
                    -d "version=${GIT_COMMIT}"
                '''
            }
        }
    }
}

3단계: Jenkins Credentials에 프록시 자격 증명 추가하기

  1. Manage JenkinsCredentialsSystemGlobal credentials 열기
  2. Add Credentials 클릭
  3. 유형: Secret text
  4. ID: proxy-url-credential
  5. 비밀: http://user:[email protected]:port

방법 3: Java 프로젝트의 JVM 매개변수를 통한 프록시 설정

파이프라인이 Java 프로젝트(Maven, Gradle)를 빌드하는 경우, 시스템 환경 변수가 작동하지 않을 수 있습니다 — JVM은 자체 시스템 속성을 사용합니다. JAVA_OPTS에 추가하세요:

environment {
    JAVA_OPTS = '-Dhttps.proxyHost=proxy.host -Dhttps.proxyPort=8080 -Dhttps.proxyUser=user -Dhttps.proxyPassword=password -Dhttp.nonProxyHosts=localhost|127.0.0.1|*.internal.com'
}

파이프라인 내 Docker 컨테이너에서 프록시 사용하기

대부분의 현대 CI/CD 파이프라인은 Docker 컨테이너 내에서 단계를 실행합니다. 컨테이너에 프록시를 전달하는 것은 별도의 작업이며 여러 방법으로 해결할 수 있습니다.

이미지 빌드 시 --build-arg를 통한 프록시 전달하기

Docker 이미지 빌드 중에만 프록시가 필요한 경우(예: Dockerfile 내 패키지 설치를 위해) 빌드 인수를 사용하세요:

# .github/workflows/build.yml 또는 .gitlab-ci.yml에서
docker build \
  --build-arg HTTP_PROXY=$HTTP_PROXY \
  --build-arg HTTPS_PROXY=$HTTPS_PROXY \
  --build-arg NO_PROXY=$NO_PROXY \
  -t myapp:latest .

# Dockerfile에서
ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
ENV NO_PROXY=$NO_PROXY

RUN apt-get update && apt-get install -y curl
RUN npm ci

⚠️ 중요: 이미지 빌드 시 보안

ARGENV를 통해 Dockerfile에서 설정된 변수는 이미지 메타데이터에 저장되며 docker inspect를 통해 볼 수 있습니다. 프록시가 인증을 요구하는 경우, 완성된 이미지를 공개 레지스트리에 게시하지 않도록 하세요 — 그렇지 않으면 자격 증명이 공개됩니다.

Docker 데몬의 전역 프록시 설정

자체 호스팅 러너에서는 Docker 데몬 전체에 대한 프록시를 설정할 수 있습니다 — 그러면 모든 컨테이너가 Dockerfile을 변경하지 않고도 자동으로 프록시를 받습니다:

# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://user:[email protected]:port"
Environment="HTTPS_PROXY=http://user:[email protected]:port"
Environment="NO_PROXY=localhost,127.0.0.1,registry.internal.com"

# 변경 사항 적용:
# systemctl daemon-reload
# systemctl restart docker

보안: 프록시 자격 증명 저장하기

프록시 자격 증명은 API 키나 데이터베이스 비밀번호와 같은 비밀입니다. 이들의 유출은 누구나 귀하의 프록시를 귀하의 비용으로 사용할 수 있음을 의미합니다. 안전한 저장을 위한 규칙은 다음과 같습니다:

보안 체크리스트

  • 절대 프록시 로그인/비밀번호를 파이프라인 YAML 파일에 직접 입력하지 마세요
  • ✅ GitLab에서는 Masked variables를 사용하고 GitHub에서는 Encrypted secrets를 사용하세요 — 로그에서 숨겨집니다
  • ✅ Jenkins에서는 Secret text 또는 Username with password 유형을 Credentials Store에서 사용하세요
  • ✅ 내부 주소에 대해 NO_PROXY를 추가하세요 — 귀하의 인프라로의 트래픽은 프록스를 통해 가지 않아야 합니다
  • ✅ 프록시 비밀번호를 정기적으로 회전하세요 — 비밀 저장소에서만 업데이트하고 파이프라인 코드는 변경하지 마세요
  • ✅ 지원되는 경우 프록시의 IP 인증(러너의 IP 화이트리스트)을 사용하세요 — 이는 비밀번호보다 안전합니다
  • ✅ 비정상적인 활동에 대해 프록시 로그를 확인하세요

프록시 URL 형식: 무엇을 어디에 넣을지

프로토콜 URL 형식 언제 사용해야 하는지
HTTP http://user:pass@host:port 대부분의 도구, npm, pip, curl
HTTPS https://user:pass@host:port 프록시 서버와의 암호화된 연결
SOCKS5 socks5://user:pass@host:port 비표준 포트, UDP 트래픽, 최대 호환성

자주 발생하는 오류 및 해결 방법

올바르게 설정했더라도 문제가 발생할 수 있습니다. 다음은 가장 일반적인 오류와 그 해결 방법입니다:

오류: Proxy Authentication Required (407)

원인: 잘못된 로그인 또는 비밀번호이거나, 도구에서 전달되지 않음.

해결 방법: URL 형식을 확인하세요 — 비밀번호의 특수 문자는 URL 인코딩해야 합니다. 예를 들어, p@ss#wordp%40ss%23word. 또한 환경 변수가 실제로 단계에 전달되는지 확인하세요 — echo $HTTP_PROXY를 통해 확인하세요 (첫 몇 문자).

오류: SSL Certificate Verification Failed

원인: 프록시가 SSL 검사(MITM)를 수행하고 인증서를 변경합니다. 클라이언트가 프록시 인증서를 신뢰하지 않습니다.

해결 방법: 프록시의 루트 인증서를 신뢰할 수 있는 목록에 추가하세요. curl의 경우: --cacert /path/to/proxy-ca.crt. npm의 경우: npm config set cafile /path/to/proxy-ca.crt. 또는 SSL 검사 없이 프록시를 사용하세요 — CI/CD에서는 이것이 더 바람직합니다.

오류: 프록시를 통한 Connection Timeout

원인: 프록시 서버에 러너의 IP에서 접근할 수 없거나, 포트가 방화벽에 의해 차단되었습니다.

해결 방법: 파이프라인 단계에서 nc -zv proxy.host port 명령어로 프록시의 접근 가능성을 확인하세요. 러너의 IP가 프록시 제공자의 화이트리스트에 추가되었는지 확인하세요 (IP 인증을 사용하는 경우). GitHub Actions의 클라우드 러너의 경우 IP 범위는 meta.github.com에 게시됩니다.

오류: 도구가 HTTP_PROXY 변수를 무시함

원인: 일부 도구(특히 Java 기반)는 시스템 환경 변수를 읽지 않습니다.

해결 방법: 특정 도구에 대한 기본 프록시 설정을 사용하세요 (위의 표 참조). Java의 경우 JAVA_OPTS를 통해 JVM 속성을 추가하세요. curl의 경우 -x http://proxy:port 플래그를 명시적으로 사용하세요.

오류: 내부 서비스도 프록스를 통해 감

원인: NO_PROXY 변수가 설정되지 않았거나 잘못 설정되었습니다.

해결 방법: 모든 내부 도메인과 IP를 NO_PROXY에 지정하세요. 도메인에 대해 와일드카드를 사용하세요: NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,.internal.company.com. 주의: 일부 도구는 CIDR 표기법을 지원하고, 다른 도구는 정확한 도메인만 지원합니다.

결론

CI/CD 파이프라인에서 프록시 설정은 일회성이 아니라 자동화 아키텍처의 일부분입니다. 우리는 세 가지 주요 도구를 살펴보았습니다: GitHub Actions(Secrets 및 환경 변수를 통해), GitLab CI(변수를 통해 마스킹) 및 Jenkins(Credentials Store 및 Declarative Pipeline을 통해). 모든 도구에 대해 핵심 원칙은 동일합니다: 절대 자격 증명을 코드에 저장하지 말고, 내부 주소에 대해 NO_PROXY를 사용하고, 특정 작업에 맞는 프록시 유형을 선택하세요.

올바른 프록시 유형 선택은 파이프라인의 안정성에 매우 중요합니다. 종속성을 다운로드하고 표준 API에 접근하는 데는 빠른 데이터 센터 프록시로 충분합니다. 그러나 파이프라인이 실제 웹사이트에서 통합 테스트를 수행하거나 광고 플랫폼(Facebook Ads API, TikTok Ads API)과 작업하거나 마켓플레이스에 접근하는 경우에는 레지던스 프록시를 사용하세요: 이들의 IP는 일반 사용자 트래픽으로 인식되며 차단이나 속도 제한에 걸릴 가능성이 매우 낮습니다.

주요 규칙: 파이프라인 시작 부분에 프록시를 테스트하는 단계를 추가하세요 — 이는 문제를 신속하게 진단하고 긴 빌드의 끝에서 오류를 찾는 데 시간을 낭비하지 않도록 도와줍니다. 프록시 설정 직후에 curl -v https://api.ipify.org 단계를 추가하세요 — 이는 요청이 발송되는 IP를 보여주고 프록시가 올바르게 작동하는지 확인할 수 있습니다.

```