Clash Meta Docker 배포: Compose와 이미지 갱신까지 한 번에
이미 Linux·헤드리스·systemd로 코어를 올린 경험이 있다면, 같은 목표를 Docker로 달성하는 사람은 다른 검색 의도를 가집니다. 이미지 태그로 버전을 고정하고, docker compose 한 장으로 재배포하며, 볼륨에 설정과 구독(provider) 캐시를 남겨 컨테이너를 지워도 다시 받을 수 있게 만드는 흐름입니다. NAS·가정용 서버·소형 VPS 모두에서 흔한 패턴이며, 본문에서는 Clash Meta(mihomo) 계열을 전제로 이미지 선택, 디렉터리 구조, 네트워크 모드, 헤드리스에서의 API 바인딩, 이미지 갱신·롤백 절차를 순서대로 정리합니다. systemd 직접 설치와의 차이는 Linux 헤드리스 Meta 가이드와 함께 보면 이해도가 올라갑니다.
왜 Docker·Compose 인가
호스트에 바이너리를 깔고 유닛 파일을 쓰는 방식은 가볍고 투명하지만, 배포판·커널·glibc 차이를 직접 감당합니다. Docker는 실행 환경을 이미지로 묶어 «이 태그면 이 동작»을 팀·장비 간에 맞추기 쉽습니다. Docker Compose는 서비스 이름·환경 변수·볼륨·재시작 정책을 한 파일에 두어 같은 저장소만 있으면 어디서든 같은 스택을 띄울 수 있게 합니다. 특히 NAS나 멀티 앱 호스트에서는 백업 정책(볼륨 스냅샷)과 맞물릴 때 이점이 큽니다.
반대로 컨테이너는 네트워크 네임스페이스가 기본적으로 호스트와 분리되므로, mixed-port를 다른 머신에 노출하려면 포트 퍼블리시나 호스트 네트워크 선택을 명시적으로 설계해야 합니다. TUN·캡처 계열은 호스트 권한·커널 모듈 이슈로 Docker만으로 깔끔하지 않은 경우가 많아, 본 글은 SOCKS/HTTP 프록시 포트와 REST 컨트롤러 중심의 전형적인 서버·헤드리스 운영을 범위로 합니다.
이미지 선택과 버전 고정
공개 레지스트리에는 메타 코어를 감싼 이미지가 여럿 있습니다. 선택 기준은 (1) 유지보수 빈도와 태그 명확성, (2) 아키텍처(amd64·arm64) 지원, (3) 엔트리포인트가 공식 문서의 -d <설정 디렉터리> 패턴과 맞는지입니다. latest만 쓰면 어느 날 갑자기 메이저 업그레이드가 들어와 YAML 키 호환 문제로 기동 실패할 수 있으므로, 운영에서는 의도한 버전 태그를 compose 파일에 박아 두고 갱신할 때만 올리는 편이 안전합니다.
실무 팁
이미지 줄에 주석으로 «왜 이 태그인지»와 «직전에 잘 돌아가던 다이제스트」를 적어 두면, 동료나 6개월 뒤의 본인이 롤백할 때 시간을 덜 씁니다.
디렉터리·볼륨: 설정과 구독 지속
컨테이너 파일시스템은 삭제되면 사라집니다. 구독 자동 갱신을 쓰려면 proxy-providers 등이 내려받는 파일이 디스크에 남아야 하므로, 최소한 다음을 볼륨으로 빼는 구성이 일반적입니다.
- 설정 루트:
config.yaml과 로컬로 두는 룰 조각. - 데이터·캐시: provider가 쓰는
./providers/등 쓰기 가능한 하위 경로(설정의path와 일치).
호스트 경로 권한은 컨테이너 실행 UID와 맞추거나, 읽기 전용으로 걸 수 있는 파일은 :ro로 마운트해 실수로 덮어쓰기를 줄입니다. 시크릿(구독 URL에 토큰이 붙은 경우)은 환경 변수나 Docker secret으로 넘기고, git에 올리지 않는 습관과 병행하세요.
docker-compose 예시 스켈레톤
아래는 관계를 보여 주기 위한 예시입니다. 이미지 이름·태그·명령행은 실제 사용하는 이미지 문서에 맞게 바꾸세요. 포트는 호스트에서 쓸 값으로 조정합니다.
services:
mihomo:
image: example/mihomo:v1.19.0
container_name: mihomo
restart: unless-stopped
volumes:
- ./config:/etc/mihomo
- ./data:/var/lib/mihomo
ports:
- "7893:7893"
- "127.0.0.1:9090:9090"
command: ["-d", "/etc/mihomo"]
external-controller를 컨테이너 안에서 0.0.0.0:9090으로 열어두었다면, 호스트에서는 반드시 127.0.0.1:9090:9090처럼 루프백에만 묶거나 방화벽으로 막으세요. 인터넷에 그대로 노출하면 원격에서 정책을 바꾸는 리모컨이 공개되는 것과 같습니다.
보안
secret 없는 컨트롤러·인증 없는 대시보드는 스캔 대상입니다. SSH 터널이나 역방향 프록시 뒤에 두고, 가능하면 시크릿을 필수로 설정하세요.
네트워크: bridge와 host
기본 bridge는 포트 매핑(ports)으로 호스트와 연결합니다. 다른 컨테이너가 같은 호스트의 Clash를 쓰려면 서비스 이름으로 DNS 되는 내부 주소를 쓰거나, extra_hosts·공유 네트워크를 구성합니다. host 네트워크는 호스트 네임스페이스를 공유해 포트 매핑이 단순해지지만, 같은 포트를 쓰는 다른 프로세스와 충돌하기 쉽고 NAS OS마다 지원 형태가 달라 이식성이 떨어질 수 있습니다.
| 모드 | 장점 | 주의 |
|---|---|---|
| bridge + ports | 격리·예측 가능, 문서화된 매핑 | 포트 충돌 시 호스트 쪽 번호 조정 |
| host | NAT 없이 리스닝 | 포트 단일 점유, 스택마다 다름 |
헤드리스 운영과 리로드
GUI가 없는 서버에서는 외부 컨트롤러 API로 헬스 확인·설정 리로드를 자동화합니다. 컨테이너 안에서 API를 호출할 때는 루프백을 쓰고, 호스트에서는 퍼블리시한 포트나 docker exec로 curl합니다. 구독은 proxy-providers의 interval로 주기 갱신되며, 이미지를 바꾸지 않아도 노드 목록이 갱신되는 경우가 많습니다. 반대로 config.yaml 구조 자체를 바꿨다면 API 리로드나 컨테이너 재생성 중 하나가 필요합니다.
배포 후 스모크 체크
docker compose ps로 상태가running인지 확인합니다.- 설정한 mixed/SOCKS 포트에 대해 호스트에서
curl -x또는 테스트 URL을 사용합니다. - 문제 시
docker compose logs -f로 YAML 오류·DNS·포트 바인딩 메시지를 봅니다.
이미지 갱신·업그레이드·롤백
절차를 문서화해 두면 재현성이 생깁니다. 일반적인 업그레이드 흐름은 다음과 같습니다.
- 현재 잘 동작하는 태그와
docker compose config출력을 백업합니다. - compose의
image:태그를 새 버전으로 바꿉니다. docker compose pull후docker compose up -d로 재기동합니다.- 프록시·구독 갱신·필요 시 API 리로드를 검증합니다.
문제가 있으면 compose에서 이전 태그로 되돌린 뒤 다시 up -d하면 됩니다. 볼륨에 설정과 provider 캐시가 남아 있으면 데이터는 유지된 채 바이너리만 교체됩니다. 대규모 메이저 업그레이드 전에는 릴리스 노트에서 YAML 키 변경 여부를 확인하세요.
NAS 사용자
GUI 위저드가 latest 끌어오기를 기본으로 할 수 있습니다. «한 번에 올리기» 전에 태그를 수동으로 고정했는지, 볼륨 경로가 앱 재설치 후에도 같은지 확인하세요.
자주 묻는 질문
구독 URL이 프록시 없이는 안 받아진다
콜드 스타트에서 provider HTTP GET이 실패하면 캐시도 비어 있어 기동만 반복할 수 있습니다. 헤드리스 systemd 글에서 말한 것처럼, 다른 신뢰 호스트에서 초기 파일을 넣거나 잠시 직접 닿는 경로에서 첫 페치를 마친 뒤 컨테이너에 맡기는 방법을 고려하세요.
provider 쓰기 권한 오류
볼륨 마운트의 UID/GID가 컨테이너 사용자와 맞지 않으면 캐시 디렉터리에 쓰지 못합니다. 이미지 문서의 사용자 ID를 확인하고 호스트 폴더 소유자를 맞추거나, 해당 이미지가 지원하면 user 네임스페이스 매핑을 사용하세요.
DNS·fake-ip 이슈
컨테이너 내부 DNS는 호스트와 다를 수 있습니다. 이상 증상이면 DNS·fake-ip 점검 글의 순서를 참고해, 모드와 nameserver를 한 번에 하나씩만 바꿔 가며 좁히세요.
요약 체크리스트
- 이미지는 명시적 태그로 고정하고, 갱신은 의도된 시점에만 한다.
- 설정·provider 데이터는 볼륨으로 분리해 컨테이너 재생성에도 남긴다.
- 컨트롤러는 인증·바인딩을 전제로 하고 외부에 그대로 노출하지 않는다.
- 업그레이드는
pull+up -d, 이상 시 태그 롤백으로 복구한다. - systemd 직접 설치와 역할을 비교해 팀에 맞는 쪽을 택한다.
데스크톱·모바일 클라이언트
서버 쪽은 Docker로 고정하고, 일상 설정은 GUI 클라이언트가 편한 경우가 많습니다. 통합 빌드가 필요하면 다운로드 페이지를 함께 이용하세요.