GitHub·Docker·npm 다운로드가 느린 이유부터 확인하기
개발 환경에서 GitHub 저장소를 내려받거나 Docker 이미지를 가져오거나 npm 패키지를 설치할 때 속도가 일정하지 않은 이유는 단순히 인터넷 회선이 느려서만은 아닙니다. 실제 경로에는 로컬 네트워크, DNS 조회, 중간 라우팅, 해외 서비스의 접속 지역, 저장소 또는 레지스트리의 응답 상태가 함께 영향을 줍니다. 브라우저는 정상적으로 열리는데 git clone, docker pull, npm install만 오래 걸리는 경우도 이러한 차이에서 발생합니다.
특히 GitHub의 저장소와 릴리스 파일, Docker Hub 또는 기타 이미지 레지스트리, npm 레지스트리는 서로 다른 도메인과 CDN을 사용할 수 있습니다. 따라서 한 사이트가 잘 열린다고 해서 모든 개발 도구의 다운로드 경로가 좋은 것은 아닙니다. 먼저 어느 단계에서 문제가 발생하는지 분리해야 합니다. DNS 조회가 늦은지, TLS 연결이 실패하는지, 파일을 받는 도중 속도가 떨어지는지, 아니면 특정 레지스트리만 응답하지 않는지를 구분하면 불필요하게 클라이언트 전체를 바꾸는 일을 줄일 수 있습니다.
100+
지원 국가
180+
지원 회선
5
지원 플랫폼
不限
동시 접속 기기
VPN을 사용하면 모든 문제가 자동으로 해결되는 것은 아닙니다. VPN은 개발 도구와 원격 서버 사이의 경로를 바꾸는 수단이며, 실제 결과는 선택한 지역, 회선 유형, 프로토콜, 로컬 프록시 설정에 따라 달라집니다. 가까운 지역의 노드가 항상 최선이라고 단정하기보다는 GitHub, Docker 레지스트리, npm처럼 실제로 사용하는 목적지에 맞춰 확인해야 합니다.
개발 작업에 맞는 회선과 프로토콜 고르기
개발용 연결에서는 최고 속도 하나보다 안정적인 세션 유지가 중요합니다. 저장소를 복제하는 동안 연결이 끊기면 다시 처음부터 받아야 할 수 있고, Docker 이미지가 여러 레이어로 나뉘어 있으면 일부 레이어만 반복해서 실패할 수 있습니다. npm 설치도 패키지 수가 많거나 의존성이 깊을수록 짧은 연결 실패가 전체 작업을 중단시킬 가능성이 커집니다.
- IEPL 전용선: 전용 경로를 사용하는 방식으로, 피크 시간대의 공용망 혼잡 영향을 줄이는 데 초점을 둡니다. 장시간 다운로드나 원격 개발 세션처럼 연결 안정성이 중요한 작업에 적합합니다.
- BGP 중계: 중계 구간을 거쳐 목적지로 연결합니다. 지역에 따라 경로가 달라질 수 있으므로 한 지역에서 불안정하면 다른 회선 또는 다른 출구를 비교하는 것이 좋습니다.
- 직접 연결: 구성이 단순하고 짧은 작업에는 편리하지만, 중간 경로의 혼잡이나 통신사 정책에 따라 시간대별 편차가 커질 수 있습니다.
프로토콜도 용도에 맞게 선택해야 합니다. Shadowsocks는 비교적 가벼운 구성이며, VMess와 Trojan은 각각 V2Ray 계열 또는 TLS 기반 구성에서 널리 사용됩니다. VLESS는 불필요한 오버헤드를 줄인 형태로 다른 전송 계층과 함께 구성되는 경우가 많습니다. Hysteria2는 QUIC/UDP 기반이라 손실이 있는 환경에서 유리할 수 있지만, 네트워크가 UDP를 제한하면 오히려 연결이 불안정해질 수 있습니다. WireGuard는 설정이 간결하고 성능이 좋은 편이지만, 모든 네트워크 환경에서 같은 결과를 보장하지는 않습니다.
| 작업 | 우선 확인할 요소 | 문제가 생겼을 때의 접근 |
|---|---|---|
| Git clone / fetch | 장시간 연결 유지, DNS, 저장소 도메인 | 다른 출구를 선택하고 Git 프록시 적용 여부를 확인 |
| Docker pull | 레지스트리 주소, 레이어별 다운로드, 데몬 환경 | Docker 데몬 프록시와 터미널 프록시를 분리해서 점검 |
| npm install | registry 설정, 의존성 수, 인증서 | npm 설정과 셸 환경 변수가 서로 다른지 확인 |
| CI/CD 빌드 | 러너의 네트워크와 비밀 변수 관리 | 개인 PC 설정을 그대로 복사하지 말고 러너에서 별도 구성 |
로컬 개발 환경에서 단계별로 설정하기
로컬 컴퓨터에서는 먼저 VPN 클라이언트가 정상적으로 연결되는지 확인한 뒤 개발 도구에 프록시를 적용하는 순서가 안전합니다. Windows, macOS, Android, iOS, Linux 공식 클라이언트는 운영체제 전체 트래픽을 처리하는 방식이 일반적입니다. Clash Verge, sing-box, Shadowrocket 같은 호환 클라이언트는 규칙 기반 분기 또는 시스템 프록시를 제공하므로, 업무용 내부 주소와 외부 개발 서비스의 경로를 나누는 데 활용할 수 있습니다.
- 공식 클라이언트 또는 호환 클라이언트에 구독 링크를 가져옵니다. 링크를 직접 수정하지 말고 클라이언트의 구독 업데이트 기능을 사용합니다.
- VPN을 연결한 뒤 브라우저에서 GitHub와 npm 레지스트리 주소가 열리는지 확인합니다. 연결이 되더라도 모든 서비스가 같은 지역으로 처리되는 것은 아니므로 실제 명령어로 확인해야 합니다.
- 먼저 Git 저장소 하나를 읽기 작업으로 테스트합니다. 이후 작은 브랜치 조회나 fetch를 실행하고, 문제가 없을 때 clone 또는 대용량 릴리스 파일 다운로드를 진행합니다.
- Docker에서는 터미널의 프록시와 Docker 데몬의 프록시가 별개일 수 있다는 점을 기억합니다. Docker Desktop을 사용한다면 앱 설정을 확인하고, Linux 데몬을 사용한다면 systemd 서비스 환경을 별도로 점검해야 합니다.
- npm에서는 현재 registry 주소와 프록시 값을 확인합니다. 셸에 설정한
HTTP_PROXY,HTTPS_PROXY가 npm 설정과 충돌하지 않는지도 살펴봅니다.
Git은 전역 프록시를 적용할 수도 있지만, 회사 내부 저장소나 사설 Git 서버까지 같은 프록시로 보내면 접근이 실패할 수 있습니다. 따라서 외부 저장소와 내부 저장소를 구분하는 규칙을 두고, 필요한 경우 저장소별 설정을 사용하세요. SSH 방식의 Git 접속은 HTTPS 방식과 다른 프록시 설정이 필요할 수 있으므로, HTTPS 저장소에서 잘 된다는 이유만으로 SSH 연결도 정상이라고 판단하면 안 됩니다.
Docker도 마찬가지입니다. 셸에서 curl이 프록시를 타고 있어도 Docker 데몬이 별도의 서비스 계정으로 실행되면 해당 프록시를 모를 수 있습니다. 이미지 이름이 실제로 어느 레지스트리를 가리키는지 확인하고, Docker Desktop의 네트워크 설정과 Linux 서비스 설정을 각각 점검해야 합니다. 이미지 레지스트리에 인증이 필요한 경우에는 토큰을 명령줄에 직접 남기지 말고 Docker가 제공하는 인증 저장 방식을 사용하세요.
npm은 전역 설정과 프로젝트별 설정이 함께 작동할 수 있습니다. npm config get registry로 현재 레지스트리를 확인하고, 프로젝트에 커밋된 설정 파일에 개인 토큰이나 내부 프록시 주소가 들어 있지 않은지 확인합니다. lockfile은 가능한 한 유지하는 것이 좋습니다. 연결 문제를 해결한다는 이유로 lockfile을 삭제하면 네트워크 문제와 의존성 변경 문제가 섞여 원인을 더 찾기 어려워집니다.
- ✅ VPN 연결을 켠 뒤 브라우저가 아니라 Git, Docker, npm 명령어로 각각 확인
- ✅ 운영체제 프록시와 애플리케이션별 프록시가 중복 적용되지 않는지 점검
- ✅ Docker 데몬과 현재 터미널이 서로 다른 프록시 환경을 가질 수 있음을 고려
- ✅ 사설 저장소, 사내 도메인, 로컬 주소는 프록시 우회 규칙으로 분리
- ❌ 여러 VPN 클라이언트를 동시에 실행해 라우팅 테이블을 충돌시키지 않기
CI/CD 러너에서는 로컬 설정을 그대로 복사하지 않기
CI/CD 환경은 개인 컴퓨터와 전혀 다릅니다. 러너는 매번 새로 생성되거나 컨테이너 안에서 실행될 수 있고, VPN 클라이언트가 연결되기 전에 빌드 단계가 시작될 수도 있습니다. 로컬에서 작동했던 HTTP_PROXY 값을 그대로 파이프라인 파일에 넣는 방식은 보안과 재현성 측면에서 적절하지 않습니다.
먼저 러너의 실행 위치를 구분해야 합니다. 자체 관리형 러너라면 운영체제 서비스 수준에서 VPN 또는 프록시를 구성할 수 있습니다. 클라우드형 러너라면 해당 플랫폼이 제공하는 네트워크 정책과 비밀 변수 기능을 확인해야 합니다. 어떤 방식이든 프록시 인증 정보와 구독 링크를 일반 로그에 출력하지 말아야 하며, 명령어 디버그 옵션을 켤 때 민감한 환경 변수가 노출되지 않는지 확인해야 합니다.
- 빌드 시작 전에 DNS 조회와 대상 레지스트리의 TLS 연결만 점검합니다.
- Git fetch, Docker pull, npm 설치를 한 단계씩 실행해 어느 작업에서 실패하는지 로그를 분리합니다.
- 필요한 단계에만 프록시 환경 변수를 주입하고, 테스트나 배포 단계까지 무조건 전체 트래픽을 우회하지 않습니다.
- Docker 빌드 내부에서 패키지를 설치한다면 호스트의 프록시와 빌드 컨테이너의 프록시 전달 방식을 따로 확인합니다.
- 실패 시 재시도만 반복하지 말고, 저장소 주소·레지스트리 주소·DNS·인증 오류를 구분해 기록합니다.
CI에서 가장 흔한 실수는 러너 호스트에는 프록시가 설정되어 있지만 Docker 빌드 컨테이너에는 전달되지 않는 경우입니다. 반대로 컨테이너에는 프록시가 전달됐지만 인증서 체인이 준비되지 않아 HTTPS 검증이 실패할 수도 있습니다. 자체 인증서를 무조건 신뢰하도록 설정하거나 TLS 검증을 끄는 방법은 임시 진단 외에는 피해야 합니다. 정상적인 CA 체인을 설치하고, 어떤 인증서가 신뢰되는지 확인하는 방식이 안전합니다.
캐시도 네트워크 비용과 실패 빈도를 줄이는 데 도움이 됩니다. Git 작업은 얕은 복제나 필요한 브랜치만 가져오는 전략을 검토할 수 있고, npm은 러너가 지원하는 패키지 캐시를 사용할 수 있습니다. Docker는 레이어 캐시와 레지스트리 캐시를 활용할 수 있지만, 오래된 취약 이미지가 계속 재사용되지 않도록 갱신 정책과 보안 검사를 함께 운영해야 합니다. 캐시는 VPN의 대체재가 아니라, 반복 다운로드를 줄이는 보조 수단입니다.
실패 원인 진단과 비용 관리
속도 개선을 시도할 때는 측정 기준을 고정해야 합니다. 같은 명령을 여러 번 무작정 반복하기보다 현재 선택한 노드, 프로토콜, 네트워크 유형, 대상 도메인을 기록하고 하나씩 바꾸세요. GitHub만 느린지 Docker 레지스트리도 느린지, npm 설치만 실패하는지에 따라 해결책이 달라집니다. 연결이 끊겼다는 메시지만 보고 서버 문제로 단정하지 말고, DNS 실패와 인증 실패를 구분해야 합니다.
| 증상 | 가능한 원인 | 먼저 할 일 |
|---|---|---|
| 저장소 주소를 찾지 못함 | DNS 또는 라우팅 문제 | DNS 조회와 다른 노드 연결을 비교 |
| clone 중간에 연결 종료 | 회선 혼잡, 세션 유지 문제 | 다른 회선 유형과 프로토콜을 시험 |
| Docker 일부 레이어만 실패 | 데몬 프록시 또는 레지스트리 경로 문제 | Docker 데몬 로그와 레지스트리 주소 확인 |
| npm 인증서 오류 | CA 체인 또는 프록시의 TLS 처리 | 시스템 인증서와 npm 설정을 점검 |
| CI에서만 실패 | 러너와 로컬의 환경 차이 | 환경 변수, 서비스 계정, 컨테이너 네트워크 확인 |
비용은 트래픽 사용 패턴에 맞춰 계산해야 합니다. 월 구독은 ¥9.9/월에 60GB, ¥18/월에 250GB, ¥28/월에 500GB이며 트래픽은 개통일을 기준으로 매월 초기화됩니다. 중간에 업그레이드하면 남은 기간에 따라 차액이 계산됩니다. 반복적인 Docker 이미지 다운로드나 CI 빌드가 많고 매월 초기화되는 용량이 맞지 않는다면, 사용한 만큼 줄어드는 월 구독과 다르게 다 쓸 때까지 유지되는 트래픽 패키지를 비교할 수 있습니다. 트래픽 패키지는 ¥158/300GB, ¥358/1000GB, ¥658/3000GB이며 사용 후에도 영구 만료되지 않습니다.
개발팀에서 여러 기기를 사용한다면 동시 온라인 기기 수 제한도 확인할 항목입니다. 39VPN은 동시에 온라인 상태인 기기 수에 제한이 없으므로 데스크톱, 노트북, 테스트 기기, CI 관련 관리 장비를 같은 계정 정책 안에서 운영할 수 있습니다. 다만 계정 정보를 팀 전체에 무분별하게 공유하기보다는 접근 권한과 트래픽 사용량을 내부적으로 관리하는 편이 안전합니다. 결제는 Alipay, WeChat Pay, USDT를 지원하고 이메일 주소 없이 사용자명과 비밀번호로 가입할 수 있습니다.
보안 주의: 구독 링크와 프록시 인증 정보는 코드 저장소, Dockerfile, CI 로그, 공개 이슈에 넣지 마세요. 이미 노출했다면 링크를 재발급하거나 고객지원에 문의하고, 토큰과 비밀번호도 함께 교체해야 합니다.
가장 재현성 높은 적용 순서
처음부터 모든 트래픽을 VPN으로 보내는 것보다 작은 범위에서 시작하는 편이 문제를 쉽게 찾을 수 있습니다. 아래 순서는 로컬 개발자와 CI 담당자가 공통으로 적용하기 좋은 흐름입니다.
- 현재 VPN을 끈 상태에서 Git, Docker, npm 각각의 실패 지점과 오류 메시지를 기록합니다.
- 공식 클라이언트 또는 Clash Verge, sing-box, Shadowrocket 같은 호환 클라이언트에 구독을 가져옵니다.
- 가까운 지역 노드 하나를 선택하고 GitHub의 저장소 조회처럼 읽기 작업부터 시험합니다.
- Docker 데몬과 npm에 프록시가 실제로 전달되는지 각각 확인합니다. 터미널에서만 환경 변수가 보이는 것은 충분한 확인이 아닙니다.
- 문제가 계속되면 노드, 회선 유형, 프로토콜을 한 번에 하나만 바꿔 결과를 비교합니다.
- 안정적인 구성이 정해진 뒤에만 CI 러너에 적용하고, 비밀 변수와 로그 마스킹을 검토합니다.
- 마지막으로 캐시 정책과 트래픽 사용량을 점검해 매월 필요한 용량과 패키지형 사용 방식 중 하나를 선택합니다.
연결 상태가 정상인데 특정 작업만 실패한다면 VPN을 계속 재연결하기보다 애플리케이션 설정을 확인하세요. Git의 HTTPS와 SSH는 프록시 처리 방식이 다르고, Docker CLI와 Docker 데몬은 실행 주체가 다르며, npm은 프로젝트 설정과 사용자 전역 설정이 합쳐질 수 있습니다. 이 세 가지 차이를 이해하면 동일한 노드를 여러 번 바꾸는 시행착오를 줄일 수 있습니다.
설정 후에는 IP 확인 도구를 이용해 현재 출구 지역을 확인하고, 실제 사용하는 GitHub 저장소·Docker 레지스트리·npm 레지스트리로 최종 테스트를 진행하세요. 모든 개발 작업을 하나의 고정 노드에 의존하지 말고, 문제가 생겼을 때 교체할 수 있는 대체 회선과 복구 절차를 준비하는 것이 장기적으로 더 안정적입니다.