개발 및 AI · Clash 기술 블로그

Docker 및 WSL2에서 Clash 프록시를 사용하는 방법: 이미지 가져오기 시간 초과 및 네트워크 구성

docker pull, WSL2 다운로드, 컨테이너 내부 요청은 서로 다른 프로세스에서 실행됩니다. 오류 위치에 따라 호스트 주소와 해당 프록시 설정을 확인하고 빌드나 컨테이너에 변수를 따로 전달하며 NO_PROXY로 데이터베이스와 내부 서비스의 직접 연결을 유지하세요.

  • Docker
  • WSL2
  • 개발 환경
이 글의 목차

개발 환경에서는 컴퓨터에서 잘 되는 프록시 주소를 모든 터미널과 컨테이너에 그대로 복사해 설정을 잘못하기 쉽습니다. 오류를 출력한 프로세스가 무엇인지, 그 프로세스가 프록시를 실행하는 호스트에 연결할 수 있는지 확인해야 합니다. 연결 테스트를 통과한 뒤 영구 설정을 저장하고, 데이터베이스 같은 내부 서비스에는 직접 연결할 수 있도록 하세요.

docker pull, WSL 다운로드, 컨테이너 요청의 프록시 설정

오류가 발생한 요청을 보낸 프로그램

실패한 작업요청을 보내는 프로그램
WSL의 curl / apt / git 시간 초과WSL 배포판 내부 프로세스
docker pull 시간 초과Docker Desktop 또는 Docker Engine 데몬
빌드 중 RUN apt-get 시간 초과BuildKit / 빌드 컨테이너
시작한 앱의 요청 실패실행 중인 컨테이너

Windows에서 Clash가 127.0.0.1에서 연결을 수신해도 해당 Windows 컴퓨터 자체에서의 접근만 보장됩니다. WSL2는 기본적으로 NAT 가상 네트워크에서 실행되며 컨테이너에도 독립적인 네트워크 환경이 있습니다. 이들이 127.0.0.1에 접근하면 보통 호스트가 아니라 자기 자신에 연결됩니다.

Windows, WSL2, 컨테이너 사이의 프록시 경로
  1. Windows의 ClashLAN에서 접근 가능한 mixed-port 수신
  2. WSL2호스트 주소로 해당 포트 접근
  3. Docker 빌드HTTP_PROXY와 HTTPS_PROXY를 명시적으로 전달
  4. 컨테이너 내부 도구Git, npm 또는 패키지 관리자를 별도로 처리

Windows, WSL2와 각 컨테이너에서 127.0.0.1에 접속하면 보통 각자의 네트워크 환경에 연결됩니다. 프록시 주소에는 현재 환경에서 접근할 수 있는 호스트 주소를 입력하세요.

WSL이 Windows 프록시 포트에 접근하도록 설정

먼저 Clash에서 실제 HTTP 또는 mixed-port를 확인하세요. 흔한 예시는 7890이지만 클라이언트마다 다를 수 있습니다. WSL에서 호스트 IP로 접근하면 LAN 연결로 취급되므로 클라이언트가 LAN 접근을 허용하고 WSL에서 도달할 수 있는 주소에서 수신해야 합니다.

LAN 허용은 포트 접근 범위를 넓힙니다. 신뢰할 수 있는 가정 또는 조직의 사설 네트워크에서만 사용하고 Windows 방화벽에서 출발지를 제한하세요. 인증 없는 프록시를 공용 Wi-Fi나 인터넷에 노출하지 마세요. 시험 후 더 이상 필요하지 않으면 LAN 접근을 끌 수 있습니다.

기본 NAT와 미러링 네트워크의 호스트 주소

기본 NAT 모드에서는 WSL의 기본 경로에서 다음 홉을 읽을 수 있으며 보통 WSL 가상 네트워크의 Windows 호스트 주소입니다. Windows 11 22H2 이상에서 mirrored networking을 켜면 WSL이 127.0.0.1을 통해 Windows 서비스에 직접 접근할 수 있습니다.

WSL 기본 NAT 시험, 7890은 교체할 Clash 포트
HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }')
CLASH_PORT=7890
echo "Windows host: $HOST_IP"
curl -I -x "http://${HOST_IP}:${CLASH_PORT}" https://example.com

이 curl이 HTTP 응답을 받은 뒤에 WSL 환경 변수를 설정할 필요가 있습니다. 프록시 포트가 바로 Connection refused를 반환하면 Clash 수신 대기, LAN 허용 또는 방화벽의 문제입니다. 포트에는 접근하지만 외부 요청이 timeout이라면 노드와 규칙을 확인하세요.

WSL shell의 HTTP_PROXY와 HTTPS_PROXY 설정

현재 WSL shell에 임시 적용, 7890은 포트 자리표시자
HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }')
CLASH_PORT=7890
export HTTP_PROXY="http://${HOST_IP}:${CLASH_PORT}"
export HTTPS_PROXY="http://${HOST_IP}:${CLASH_PORT}"
export NO_PROXY="localhost,127.0.0.1,::1"
curl -I https://example.com

임시 변수는 현재 터미널에서 시작한 프로그램이 읽습니다. git 또는 curl로 같은 HTTPS 요청을 다시 실행하고 성공한 설정을 사용하는 shell의 시작 파일에 추가하세요. curl이 HTTP 주소에 접근할 때는 소문자 http_proxy를 읽으므로 HTTP_PROXY만으로는 적용되지 않습니다.

apt의 HTTP 전송은 소문자 http_proxy, no_proxy 또는 자체 Acquire::http::Proxy 설정을 읽습니다. sudo로 실행할 때는 환경이 유지되는지도 확인하세요. 위 변수 설정이 모든 도구에 공통으로 적용된다고 생각하면 안 됩니다.

Windows에서 지원되는 WSL 버전에서는 .wslconfig에 autoProxy=true를 사용해 Windows의 HTTP 프록시 정보를 가져올 수도 있습니다. 활성화한 뒤 WSL을 다시 시작하고 실제 변수 값을 확인하세요.

NO_PROXY에는 WSL 내부에서만 제공되는 서비스를 포함해 localhost 접근이 Windows 프록시로 우회되지 않게 하세요. 회사 내부 도메인과 사설 네트워크 범위를 넣을지는 실제 네트워크에 따라 결정합니다.

Docker Desktop과 독립 Engine의 프록시 설정 위치

Docker Desktop 이미지 가져오기와 WSL shell 다운로드는 서로 다른 프로세스에서 실행됩니다. WSL에서 export HTTP_PROXY만 실행해도 Desktop의 이미지 가져오기가 자동으로 설정되지는 않습니다.

Docker Desktop의 Settings를 열고 Resources / Proxies(이름은 버전에 따라 달라질 수 있음)에 호스트에서 사용할 수 있는 HTTP, HTTPS 프록시를 입력한 뒤 적용하세요.

화면에 Docker Desktop proxy와 Containers proxy가 나뉘어 있으면 이미지 가져오기에 사용하는 Containers proxy를 확인하세요. Containers proxy가 설정되지 않은 경우에만 Docker Desktop proxy가 대신 사용됩니다. 변경 후 docker pull로 확인하세요.

Docker 공식 문서는 Desktop이 daemon.json의 데몬 프록시 설정을 읽지 않는다고 명시합니다. WSL 터미널에서 이미 접속할 수 있다고 Docker Desktop 자체 프록시 설정을 건너뛰지 마세요.

Docker Desktop이 아니라 독립형 Linux Docker Engine을 사용할 때만 Engine 문서에 따라 daemon.json 또는 systemd 환경에 데몬 프록시를 설정하고 Docker 서비스를 다시 시작하세요. 실행 형태부터 확인해 읽히지 않는 파일을 수정하지 않도록 합니다.

이미지 빌드와 실행 컨테이너에 프록시 설정을 각각 전달

Docker 클라이언트 설정은 새 컨테이너와 빌드에 프록시 환경을 자동으로 주입하거나 단일 명령에서 명시적으로 전달할 수 있습니다. 빌드에는 --build-arg, 실행에는 --env를 사용하세요. 자격 증명이 포함된 프록시 주소를 Dockerfile의 ENV로 고정하지 마세요. 이미지 기록과 설정에 남을 수 있습니다.

이 예시는 Dockerfile이 있는 프로젝트 디렉터리에서 실행합니다. demo-app은 이번 빌드의 이미지 이름이며 프로젝트에 맞게 바꿀 수 있습니다. 독립적인 연결 테스트가 아니므로 프록시 포트에 접근할 수 있는지는 앞의 curl 점검으로 먼저 확인하세요.

Docker Desktop의 기존 프로젝트 예시. 7890은 실제 Clash 포트로 바꾸세요
CLASH_PROXY=http://host.docker.internal:7890

docker build \
  --build-arg HTTP_PROXY="$CLASH_PROXY" \
  --build-arg HTTPS_PROXY="$CLASH_PROXY" \
  -t demo-app .

docker run --rm \
  --env HTTP_PROXY="$CLASH_PROXY" \
  --env HTTPS_PROXY="$CLASH_PROXY" \
  --env NO_PROXY="localhost,127.0.0.1" \
  demo-app

Docker Desktop은 보통 host.docker.internal로 호스트를 가리킵니다. 네이티브 Linux Engine에서의 사용 가능 여부는 환경에 따라 다르며 명확한 호스트 게이트웨이 또는 추가 host-gateway 설정이 필요합니다. 명령 실행 전에 컨테이너 내부 curl 또는 앱 로그로 이 호스트 이름과 포트에 실제로 접근할 수 있는지 검증하세요.

NO_PROXY: 데이터베이스와 내부 서비스의 직접 연결 유지

데이터베이스 이름, Compose 서비스 이름, localhost, 내부 서브넷은 보통 외부 프록시를 거치지 않아야 합니다. 실제 내부 도메인을 NO_PROXY에 넣어 db:5432나 redis:6379 요청이 먼저 Windows 프록시로 가지 않도록 하세요. 도구마다 와일드카드와 CIDR 지원이 다르므로 설정 후 대상 프로세스에서 변수를 출력하고 실제 요청을 보내 확인해야 합니다.

프록시 주소에 사용자 이름 또는 비밀번호가 있다면 공개 compose.yaml, Dockerfile 또는 이미지에 작성하지 마세요. 로컬 환경 파일이나 프로젝트의 secret 관리 방식을 사용하고 로그에 완전한 URL이 출력되지 않게 합니다.

실제 사용 방식에 따라 네 번 검증

  • WSL의 curl이 Windows Clash를 통해 응답을 받음
  • docker pull로 작은 이미지를 가져올 수 있음
  • docker build의 네트워크 단계가 더 이상 시간 초과되지 않음
  • 실행 컨테이너에서 인터넷에 접근하고 내부 서비스에도 직접 연결할 수 있음

참고 자료