Docker 이미지 다운로드 지연을 해결하는 Clash 투명 프록시 설정

개발자와 DevOps 엔지니어를 위해 Docker와 Clash를 연동하는 실전 설정을 정리했습니다. 호스트와 컨테이너의 트래픽 흐름, CI/CD 적용법, 이미지 pull 실패 원인과 로그 분석 방법을 다룹니다.

Docker 이미지 다운로드가 느린 이유

Docker 이미지 다운로드가 유난히 느리거나 여러 레이어 중 일부에서 멈추는 문제는 단순히 인터넷 회선 속도만으로 설명되지 않습니다. Docker는 사용자가 터미널에서 실행한 클라이언트가 직접 이미지를 받는 구조가 아니라, 대부분 Docker 데몬이 레지스트리와 통신하면서 manifest와 각 레이어를 순서대로 가져오는 구조입니다. 따라서 호스트에서 Clash의 시스템 프록시를 켰더라도 Docker 데몬의 트래픽이 자동으로 프록시를 통과한다고 보장할 수 없습니다.

특히 Linux 환경에서는 Docker CLI, Docker 데몬, 실행 중인 컨테이너가 서로 다른 네트워크 네임스페이스와 프로세스 권한을 사용합니다. 터미널에서 curl이 정상적으로 동작하고 브라우저도 빠르게 열리는데 docker pull만 지연된다면, Docker 데몬이 프록시 설정을 사용하지 않거나 Clash가 해당 연결을 투명하게 가로채지 못하고 있을 가능성이 큽니다. 반대로 컨테이너 내부의 apt, npm, pip 다운로드만 느리다면 이미지 pull 경로와는 별도로 컨테이너의 DNS와 기본 라우팅을 점검해야 합니다.

  • Docker CLI: 명령을 Docker 데몬에 전달합니다. CLI에 프록시 환경 변수를 넣어도 이미지 다운로드의 실제 연결 주체가 바뀌지 않을 수 있습니다.
  • Docker 데몬: 레지스트리의 인증 서버, manifest 서버, blob 저장소에 연결해 이미지를 받습니다. 이미지 pull 문제를 해결할 때 가장 먼저 확인할 대상입니다.
  • 컨테이너: 이미지를 받은 뒤 실행되는 별도의 네트워크 환경입니다. 컨테이너 내부의 웹 요청이나 패키지 설치는 데몬의 pull 요청과 다른 흐름을 가집니다.
  • Clash: 시스템 프록시, TUN, 리눅스 라우팅 규칙 중 어떤 방식으로 트래픽을 인수하는지에 따라 Docker와의 연동 결과가 달라집니다.

컨테이너 환경 변수만으로 docker pull을 해결할 수 없습니다

docker run -e HTTP_PROXY=...는 실행된 컨테이너의 애플리케이션에만 영향을 줍니다. 이미지를 내려받는 Docker 데몬에는 적용되지 않으므로, pull 단계가 실패한다면 데몬 프록시 또는 호스트 투명 프록시를 별도로 설정해야 합니다.

호스트, 데몬, 컨테이너의 트래픽 흐름

설정을 시작하기 전에 어느 요청을 Clash로 보낼지 구분해야 합니다. 일반적인 이미지 pull 흐름은 Docker CLI가 Unix 소켓 또는 TCP 소켓을 통해 데몬에 요청을 전달하고, 데몬이 레지스트리 도메인을 해석한 뒤 HTTPS 연결을 만드는 방식입니다. 이때 CLI가 실행되는 셸의 프록시 환경 변수와 데몬 프로세스의 네트워크 경로는 서로 다를 수 있습니다.

예를 들어 docker pull registry.example.invalid/team/app:1.2를 실행하면 먼저 레지스트리의 인증 엔드포인트에 접근하고, 이후 manifest 응답에 포함된 blob 주소로 여러 개의 HTTPS 연결을 엽니다. 규칙이 레지스트리의 대표 도메인만 프록시로 보내도록 되어 있고 실제 blob 호스트가 다른 도메인이라면, 인증은 성공하지만 레이어 다운로드에서 멈출 수 있습니다. 따라서 로그에 나타난 모든 호스트 이름을 확인하고 필요한 도메인 suffix를 정책 그룹에 포함해야 합니다.

구간실제 연결 주체주요 설정 위치대표 증상
이미지 pullDocker 데몬systemd 환경 변수 또는 데몬 설정manifest, blob 다운로드 지연
컨테이너 내부 요청컨테이너 프로세스환경 변수, Docker 네트워크, TUNapt, npm, pip 요청 타임아웃
호스트 터미널 요청호스트 프로세스시스템 프록시 또는 셸 변수curl은 정상이나 Docker만 실패
Docker DesktopDesktop 관리 VM 또는 백엔드Docker Desktop 프록시 설정호스트 Clash 설정과 동작이 불일치

Linux 호스트에서 mihomo의 TUN 모드를 사용하는 경우에는 호스트 프로세스와 일반 컨테이너의 IP 트래픽을 함께 인수할 수 있습니다. 다만 Docker가 생성한 브리지 네트워크, 내부 DNS 주소, 예약 대역은 프록시 대상에서 제외해야 합니다. Docker의 내부 주소를 무조건 프록시로 보내면 컨테이너가 게이트웨이에 접근하지 못하거나 서비스 간 통신이 끊길 수 있습니다.

mihomo TUN 투명 프록시 기본 설정

Clash Meta 계열인 mihomo를 Linux 호스트에서 사용한다면 TUN 모드가 가장 일반적인 투명 프록시 방법입니다. 아래 예시는 이미 정책 그룹 이름이 PROXY로 존재한다는 전제의 최소 구성입니다. 실제 구독 설정에 맞춰 그룹 이름을 바꾸고, 기존 설정 파일의 dns, proxy-groups와 중복되지 않게 병합해야 합니다.

mixed-port: 7890
allow-lan: true
mode: rule
log-level: info

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - https://1.1.1.1/dns-query
    - https://8.8.8.8/dns-query
  fallback:
    - tls://1.1.1.1:853
  fallback-filter:
    geoip: true
    geoip-code: CN

rules:
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,198.18.0.0/16,DIRECT,no-resolve
  - DOMAIN-SUFFIX,registry.example.invalid,PROXY
  - MATCH,DIRECT

위 예시의 198.18.0.0/16은 fake-ip 주소 대역이므로 실제 인터넷 목적지로 보내면 안 됩니다. Docker 브리지에서 자주 사용하는 172.16.0.0/12, 사설 LAN의 192.168.0.0/16, 로컬호스트 대역도 DIRECT와 no-resolve를 함께 지정해 내부 주소에 대한 불필요한 DNS 질의를 줄이는 편이 안전합니다.

TUN 권한과 네트워크 인터페이스 확인

TUN은 일반 사용자 권한만으로 동작하지 않는 경우가 많습니다. mihomo 서비스에 CAP_NET_ADMIN 권한을 부여하거나 관리자 권한으로 실행해야 하며, 배포판의 방화벽과 NetworkManager가 자동 라우팅을 덮어쓰지 않는지도 확인해야 합니다. TUN을 켠 뒤에는 ip addr로 가상 인터페이스가 생성되었는지, ip route로 기본 경로가 예상대로 바뀌었는지 확인하세요.

Docker가 설치된 호스트에서는 docker0와 사용자 정의 브리지 인터페이스도 함께 확인합니다. 기본적으로 컨테이너의 목적지 트래픽은 NAT를 거쳐 호스트 외부로 나가므로 TUN이 이를 인수해야 합니다. 그러나 Docker가 자체적으로 관리하는 DNS 주소 127.0.0.11은 컨테이너 내부 전용 주소이므로 외부 장치가 직접 접근하는 DNS 서버처럼 설정하면 안 됩니다.

Docker 데몬에 프록시를 지정하는 안정적인 방법

TUN 전체 인수는 편리하지만 서버 운영 환경에서는 Docker 데몬에 명시적으로 프록시를 지정하는 방식이 더 예측 가능합니다. 이 방법은 Docker 데몬이 레지스트리와 통신할 때 HTTP CONNECT 프록시를 사용하게 하며, 이미지 pull 경로만 선택적으로 프록시로 보낼 수 있습니다. Clash의 mixed-port가 호스트에서 7890으로 열려 있고 Docker 데몬이 같은 호스트에서 실행된다는 전제로 설명합니다.

  1. Clash에서 mixed-port 또는 HTTP 프록시 포트가 실제로 열려 있는지 확인합니다. 호스트에서 curl -x http://127.0.0.1:7890 https://registry.example.invalid/v2/를 실행해 프록시 경로를 먼저 검증합니다.
  2. systemd용 Docker 서비스 디렉터리를 만듭니다. 일반적인 경로는 /etc/systemd/system/docker.service.d입니다.
  3. http-proxy.conf 파일에 데몬이 읽을 환경 변수를 작성합니다.
  4. systemd 설정을 다시 읽고 Docker를 재시작한 뒤, 정보 출력과 실제 pull 로그를 차례로 확인합니다.
sudo mkdir -p /etc/systemd/system/docker.service.d

sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1,registry.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker

NO_PROXY는 내부 레지스트리와 사설 네트워크를 직접 연결하기 위한 목록입니다. 사설 레지스트리의 인증서가 내부 CA에 의존하거나 프록시가 내부 호스트 이름을 해석하지 못하는 환경에서는 이 목록이 특히 중요합니다. 반대로 외부 레지스트리의 blob 호스트를 NO_PROXY에 넣으면 인증은 통과해도 실제 레이어만 DIRECT로 나가 다시 지연될 수 있으므로 범위를 신중하게 작성해야 합니다.

Docker Desktop은 별도 프록시 설정이 필요할 수 있습니다

Windows와 macOS의 Docker Desktop은 Linux 호스트의 systemd Docker 서비스와 구조가 다릅니다. 호스트 Clash의 TUN이 Desktop 백엔드까지 인수하지 못한다면 Docker Desktop 설정의 프록시 항목에 Clash의 접근 가능한 주소와 포트를 직접 지정하세요. 컨테이너에 127.0.0.1을 전달하면 컨테이너 자기 자신을 가리키므로, 호스트 접근용 주소를 별도로 사용해야 합니다.

컨테이너 내부 트래픽까지 프록시하는 방법

이미지 pull과 컨테이너 실행 후의 요청을 모두 처리하려면 두 경로를 각각 설정해야 합니다. Docker 데몬에 프록시를 지정했다고 해서 컨테이너 내부의 패키지 관리자와 애플리케이션까지 자동으로 프록시를 사용하지는 않습니다. 컨테이너에 환경 변수를 전달하거나, TUN과 라우팅을 통해 컨테이너 전체 트래픽을 인수해야 합니다.

docker run --rm \
  -e HTTP_PROXY=http://host.docker.internal:7890 \
  -e HTTPS_PROXY=http://host.docker.internal:7890 \
  -e ALL_PROXY=http://host.docker.internal:7890 \
  -e NO_PROXY=localhost,127.0.0.1,db,redis \
  curlimages/curl:8.10.1 \
  -I https://example.invalid

Linux의 일반 Docker Engine에서는 host.docker.internal이 기본으로 제공되지 않는 버전도 있으므로 다음처럼 호스트 게이트웨이를 명시할 수 있습니다.

docker run --rm \
  --add-host=host.docker.internal:host-gateway \
  -e HTTPS_PROXY=http://host.docker.internal:7890 \
  curlimages/curl:8.10.1 -I https://example.invalid

Clash가 호스트의 127.0.0.1:7890에만 바인딩되어 있으면 컨테이너에서 호스트 게이트웨이 주소로 접근할 수 없습니다. 이 경우 allow-lan: true를 켜고 Clash가 Docker 브리지나 호스트 LAN 주소에서 연결을 수신하도록 해야 합니다. 외부 네트워크에 불필요하게 프록시 포트를 공개하지 않도록 방화벽에서 신뢰할 수 있는 Docker 인터페이스와 관리망만 허용하세요.

CI/CD에서는 실행 명령에 프록시를 하드코딩하기보다 러너의 비밀 변수나 Docker Compose의 환경 변수 파일을 이용하는 편이 좋습니다. 프록시 주소에 인증 토큰이 포함되어 있다면 빌드 로그에 명령 전체가 출력되지 않도록 하고, 이미지 레이어에 프록시 환경 변수가 남지 않게 ENV를 신중하게 사용해야 합니다. 빌드 시에만 필요한 설정은 BuildKit의 secret 또는 러너 수준의 환경 변수로 분리하는 것이 안전합니다.

pull 실패 원인과 로그 분석 절차

설정 변경 후에는 곧바로 전체 이미지를 다시 받기보다 작은 테스트와 로그를 순서대로 실행하세요. 캐시가 남아 있으면 실제 연결이 발생하지 않아 잘못된 성공 판정을 할 수 있으므로, 테스트용 태그나 아직 로컬에 없는 이미지를 선택하는 것이 좋습니다.

  1. docker info로 Docker Server가 정상 응답하는지 확인합니다. CLI 자체의 프록시 문제가 아니라 데몬 연결 문제인지 먼저 분리합니다.
  2. journalctl -u docker -f를 실행한 상태에서 docker pull을 다시 수행합니다. timeout, TLS handshake, unauthorized, connection refused를 구분해 기록합니다.
  3. 호스트에서 레지스트리의 인증 주소와 API 주소를 각각 curl -v로 확인합니다. 대표 도메인 하나만 확인하지 말고 로그에 나타난 blob 호스트도 검사합니다.
  4. Clash 로그 레벨을 일시적으로 debug로 올리고 레지스트리 도메인이 어느 정책 그룹으로 매칭되는지 확인합니다.
  5. 필요하면 tcpdump -ni any port 53 또는 대상 포트 캡처로 DNS와 HTTPS 연결이 예상 인터페이스에서 나가는지 확인합니다. 운영 중인 서버에서는 개인정보와 인증 정보가 포함된 캡처를 장기간 보관하지 마세요.
오류 메시지 또는 증상가능성이 높은 원인확인할 항목
context deadline exceededDNS 또는 TCP 경로 지연Clash DNS 로그, TUN 라우트, 레지스트리 도메인 규칙
proxyconnect tcp: connection refused잘못된 프록시 주소나 포트Clash 리슨 주소, Docker 데몬 환경 변수, 방화벽
net/http: TLS handshake timeout프록시 미적용 또는 MTU 문제HTTPS_PROXY, TUN stack, 터널의 MTU와 패킷 손실
unauthorized프록시보다 인증 단계의 문제로그인 토큰, 인증 호스트의 규칙 매칭, 시스템 시간
인증 후 레이어에서 멈춤blob 저장소 도메인이 DIRECT로 빠짐Clash debug 로그와 manifest의 실제 다운로드 호스트

가장 흔한 실수는 registry.example.invalid만 프록시 규칙에 넣고, 인증 서버나 CDN 도메인은 제외하는 것입니다. 레지스트리 구현에 따라 이미지 manifest와 실제 레이어가 서로 다른 호스트에서 제공될 수 있습니다. 처음에는 필요한 외부 레지스트리의 명확한 DOMAIN-SUFFIX 규칙을 적용하고, 로그를 확인한 뒤 사용하지 않는 범위를 줄이는 방식이 안전합니다.

CI/CD에서 재현 가능한 운영 구성

개발 PC에서만 동작하는 투명 프록시 설정은 CI/CD 러너에서 쉽게 실패합니다. 러너가 자체 가상 머신인지, Docker-in-Docker인지, 호스트 Docker 소켓을 공유하는지에 따라 이미지 pull을 담당하는 데몬이 달라지기 때문입니다. 먼저 파이프라인 실행 로그에서 어느 Docker 엔드포인트를 사용하는지 확인하고, 프록시 설정을 그 엔드포인트의 데몬에 적용해야 합니다.

  • 호스트 소켓 공유 방식: 작업 컨테이너의 환경 변수보다 호스트 Docker 데몬의 systemd 설정이 우선입니다. 러너 호스트에 Docker 데몬 프록시를 설치하고 서비스 재시작 시점을 관리하세요.
  • Docker-in-Docker: 내부에서 별도의 Docker 데몬이 실행되므로 외부 호스트의 설정을 자동으로 상속하지 않습니다. DinD 서비스 컨테이너에 프록시 변수를 전달하고, 서비스 시작 전에 데몬 설정이 반영되었는지 확인하세요.
  • 자체 호스팅 러너: mihomo TUN 서비스의 시작 순서, 관리자 권한, 재부팅 후 자동 복구를 점검합니다. TUN이 준비되기 전에 빌드가 시작되면 첫 번째 pull만 실패할 수 있습니다.
  • 공용 러너: 조직의 내부 프록시 주소나 인증 토큰을 직접 노출하지 말고, 제공되는 secret 변수와 공식적인 러너 네트워크 정책을 사용하세요.

운영 안정성을 높이려면 레지스트리 캐시나 사내 pull-through cache를 함께 고려할 수 있습니다. 자주 사용하는 기본 이미지를 가까운 저장소에 캐시하면 모든 빌드가 외부 레지스트리와 직접 통신할 필요가 줄어듭니다. 다만 캐시 서버 자체의 인증, TLS 인증서, 저장 용량, 이미지 보존 정책은 별도로 관리해야 하며, 캐시를 사용하더라도 Docker 데몬이 캐시 주소에 접근할 수 있는지 확인해야 합니다.

검증 기준을 숫자로 남기세요

설정 전후에 같은 이미지의 manifest 응답 시간, 첫 레이어 다운로드 속도, 전체 pull 소요 시간, 재시도 횟수를 기록하면 개선 여부를 객관적으로 판단할 수 있습니다. 단순히 한 번 성공했다는 사실보다 3회 이상 반복했을 때 timeout이 사라졌는지 확인하는 편이 CI 환경에 적합합니다.

최종 점검 체크리스트

Docker와 Clash를 연동할 때 핵심은 CLI와 데몬, 컨테이너의 경계를 분리해 생각하는 것입니다. 이미지 pull이 느리면 먼저 데몬의 경로를 확인하고, 컨테이너 내부 요청이 느리면 별도의 프록시 환경 변수나 TUN 라우팅을 적용해야 합니다. 두 문제를 하나의 HTTP_PROXY 설정으로 해결하려고 하면 원인을 놓치기 쉽습니다.

  • Clash의 프록시 포트가 실제로 열려 있고, Docker 데몬이 접근 가능한 주소에 바인딩되어 있는가?
  • Docker 데몬에 HTTP_PROXY, HTTPS_PROXY, NO_PROXY가 올바르게 적용되었는가?
  • 레지스트리 인증 호스트와 blob 저장소 호스트가 같은 정책 그룹으로 처리되는가?
  • Docker 브리지, 사설망, localhost, fake-ip 대역이 불필요하게 프록시로 전송되지 않는가?
  • mihomo TUN의 auto-route, dns-hijack, 권한, Docker 라우팅이 모두 활성화되어 있는가?
  • CI/CD가 사용하는 Docker 데몬이 개발 PC와 동일한 데몬이라고 가정하고 있지 않은가?
  • Clash 로그와 journalctl -u docker의 시간대별 기록이 일치하는가?

이 순서대로 확인하면 이미지 다운로드 지연을 DNS, 프록시 포트, 레지스트리 인증, blob CDN, Docker 네트워크 문제로 나누어 처리할 수 있습니다. 필요할 때만 TUN 전체 인수를 사용하고, 서버 운영에서는 데몬 프록시와 명시적인 NO_PROXY 범위를 함께 관리하면 예측 가능한 Docker 빌드 환경을 만들 수 있습니다.

Clash 설정 준비하기

Docker 투명 프록시를 적용하기 전 mihomo 커널 지원 여부와 TUN 권한, DNS 및 규칙 설정을 확인하세요. 플랫폼에 맞는 클라이언트를 준비한 뒤 테스트 환경에서 먼저 pull 경로를 검증하는 것이 안전합니다.

자주 나타나는 오류와 원인별 해결법

증상가능한 원인확인할 항목
로그인 명령이 즉시 연결 거부Clash가 꺼져 있거나 포트가 다름mixed-port, HTTP 포트, 로컬 리스닝 상태
브라우저 인증은 끝났지만 CLI가 대기콜백 주소가 프록시나 보안 프로그램에 의해 차단됨localhost를 NO_PROXY에 포함했는지 확인
TLS handshake timeout노드 품질 저하, 잘못된 규칙, MTU 문제Clash 로그, 다른 노드, TUN 사용 여부
인증 성공 후 요청만 실패API 요청이 다른 호스트로 이동하거나 규칙에서 DIRECT 처리됨요청 도메인의规则匹配 결과와 프록시 그룹
명령을 찾을 수 없음CLI 설치 경로가 PATH에 없음codex --help, 운영체제 PATH, 설치 방식
인증 정보가 반복해서 사라짐권한 문제, 임시 컨테이너, 자격 증명 저장 실패설정 디렉터리 쓰기 권한과 실행 환경

로그인 콜백이 멈추는 경우에는 NO_PROXY가 지나치게 넓게 설정되지 않았는지 확인하세요. localhost127.0.0.1은 로컬 콜백을 위해 직접 연결하는 것이 일반적이지만, 외부 인증 서버 도메인을 무심코 NO_PROXY에 넣으면 브라우저 인증 페이지와 CLI의 인증 요청이 서로 다른 경로로 나갈 수 있습니다.

반대로 TUN 모드에서 localhost까지 가상 인터페이스로 보내면 콜백 서버가 정상적으로 응답하지 않을 수 있습니다. 이런 환경에서는 DNS 하이재킹과 자동 라우팅을 켜더라도 로컬 주소 예외를 유지하세요. TUN을 켠 뒤 문제가 시작됐다면 TUN을 끄고 환경 변수 방식으로 재시험하면 원인을 빠르게 분리할 수 있습니다.

프록시 오류와 인증 오류를 구분하세요

“connection refused”, “timeout”, “TLS handshake”는 대체로 네트워크 경로 문제이고, 인증 만료·권한 부족·잘못된 계정은 서버가 반환하는 인증 단계의 오류입니다. 전자는 Clash 로그와 포트를 먼저 보고, 후자는 Codex CLI의 로그아웃 후 재로그인과 계정 권한을 확인해야 합니다.

TUN과 DNS를 사용할 때의 추가 점검

Codex CLI가 실행하는 셸 명령이나 패키지 도구까지 같은 네트워크 정책으로 처리해야 한다면 TUN 모드가 편리할 수 있습니다. 다만 TUN은 단순히 브라우저를 프록시로 바꾸는 기능이 아니라 시스템 라우팅과 DNS 흐름을 변경하는 기능입니다. Windows에서는 서비스 모드와 관리자 권한이 필요할 수 있고, macOS에서는 네트워크 확장 또는 VPN 구성 허용이 요구될 수 있습니다.

mihomo 기반 클라이언트에서는 auto-route, auto-detect-interface, dns-hijack 설정이 서로 맞물립니다. 자동 라우팅이 꺼져 있으면 TUN 인터페이스가 만들어져도 일부 트래픽이 기존 네트워크 카드로 빠질 수 있습니다. DNS 하이재킹이 빠지면 도메인 조회는 운영체제 DNS로 남아 규칙 매칭이 불안정해질 수 있습니다. fake-ip을 사용하는 경우 198.18.0.1/16과 같은 가상 대역이 로컬 네트워크 규칙에 의해 차단되지 않는지도 확인하세요.

  • Clash 로그에서 DNS 요청이 기록되는지 확인합니다.
  • nslookup 또는 dig 결과가 매번 바뀌는지, 특정 잘못된 주소가 반복되는지 비교합니다.
  • 사내 도메인과 로컬 프린터 주소는 NO_PROXY 또는 DIRECT 규칙으로 분리합니다.
  • 패키지 설치 명령이 실패하면 Codex 자체가 아니라 패키지 저장소의 인증서, 별도 프록시 설정, 저장소 정책을 확인합니다.

터미널 명령 실행을 허용할 때는 네트워크가 안정적이라는 이유만으로 모든 명령을 자동 승인하지 마세요. Codex CLI가 파일을 수정하거나 외부 패키지를 설치하도록 설정되어 있다면 프로젝트 디렉터리, 셸 권한, 환경 변수에 저장된 비밀 정보까지 함께 고려해야 합니다. 먼저 읽기 작업으로 검증하고, 변경 작업은 명령별로 확인하는 것이 안전합니다.

FAQ: Codex CLI와 Clash 연결 문제

시스템 프록시를 켰는데도 Codex CLI가 직접 연결되는 이유는 무엇인가요?

터미널 프로그램이나 내부 HTTP 라이브러리가 운영체제의 시스템 프록시를 읽지 않을 수 있습니다. 현재 셸에 HTTP_PROXYHTTPS_PROXY를 직접 지정한 뒤 다시 실행하세요. 그래도 로그가 보이지 않으면 TUN 모드로 비교 테스트를 진행해 프로세스가 프록시 변수를 무시하는지 확인할 수 있습니다.

HTTP_PROXY와 HTTPS_PROXY에 서로 다른 포트를 넣어야 하나요?

Clash의 mixed 포트를 사용한다면 두 변수에 같은 HTTP 주소를 넣어도 됩니다. 다만 실제 클라이언트에서 HTTP와 SOCKS 포트가 분리되어 있다면 HTTPS 요청에 SOCKS 포트를 HTTP 주소로 입력하지 않도록 주의하세요. 포트 형식과 프로토콜이 맞지 않으면 연결 거부 또는 TLS 오류가 발생합니다.

Codex 로그인 후에는 환경 변수를 삭제해도 되나요?

로그인 정보가 안전하게 저장되고 이후 요청이 직접 연결로도 허용되는 환경이라면 가능하지만, 인증 후 API 요청도 프록시가 필요한 네트워크라면 환경 변수를 계속 유지해야 합니다. 테스트할 때는 변수를 삭제한 새 셸에서 간단한 요청을 실행해 인증 경로와 실제 작업 경로가 모두 정상인지 구분하세요.

노드를 바꾸면 Codex CLI 인증을 다시 해야 하나요?

일반적으로 노드 변경만으로 저장된 인증 정보가 사라지지는 않습니다. 그러나 출구 지역이나 IP가 바뀌면서 보안 확인이 추가되거나, 이전 연결이 만료되어 재인증이 요구될 수 있습니다. 짧은 시간에 여러 지역의 노드를 반복해서 바꾸기보다 안정적인 하나의 그룹을 선택하고 Clash 로그에서 연결 상태를 확인하세요.

다음 단계: Clash 설정과 Codex 실행 환경 정리

Codex CLI 연결 문제는 대부분 클라이언트 자체보다 로컬 포트, 셸 환경 변수, DNS 경로, 규칙 순서 중 하나에서 발생합니다. 먼저 mixed 포트와 전역 연결을 이용해 기본 경로를 검증한 뒤, 규칙 모드와 TUN 모드로 범위를 좁히면 불필요한 설정 변경을 줄일 수 있습니다. 설치 파일과 클라이언트 선택이 아직 정해지지 않았다면 다운로드 센터에서 플랫폼에 맞는 mihomo 기반 클라이언트를 확인하고, 적용 후에는 단계별 튜토리얼에 따라 프로필과 프록시 모드를 설정하세요.

Clash 클라이언트 다운로드

규칙 분리를 적용하려면 먼저 클라이언트가 트래픽을 인계받아야 합니다. 다운로드 센터에서 사용 중인 플랫폼에 맞는 클라이언트를 선택한 뒤, 다시 가이드로 돌아와 시스템 프록시 또는 TUN 인계를 완료하세요.

Clash 다운로드