<!-- canonical: https://docs.axelabs.ai/architecture/topology -->
<!-- source: content/architecture/topology.mdx -->

---
title: Topology · 네트워크
description: Cloudflare Tunnel, Docker network, host-side proxy 패턴.
---

# Topology · 네트워크

## 외부 경계 — Cloudflare

모든 외부 트래픽은 Cloudflare 의 anycast 망을 통해 도달합니다.

| 구간 | 도메인 / 호스트 | 처리 |
|---|---|---|
| DNS | `axelabs.ai` zone (Cloudflare) | A/CNAME → Cloudflare proxy IPs |
| 전송 보안 | Cloudflare → cloudflared (HTTPS) | mTLS connector |
| 터널 | `axelabs-tunnel` (Docker, ID `d8efecdd-2c3f-42de-9925-501433e21394`) | tunnel ingress |
| origin | `host.docker.internal:{port}` | per-service routing |

cloudflared config 위치: `/Users/axe/.axe/tunnels/axelabs/config.yml`

### Tunnel ingress 규칙

```yaml
tunnel: d8efecdd-2c3f-42de-9925-501433e21394
ingress:
  - hostname: axe.axelabs.ai
    path: ^/frame(/.*)?$
    service: http://host.docker.internal:3712     # axe-frame-proxy
  - hostname: axe.axelabs.ai
    path: ^/vault(/.*)?$
    service: https://host.docker.internal:8222   # axe-vault-caddy
  - hostname: admin.axelabs.ai
    service: http://axe-caddy:80                  # operator console
  - hostname: axe.axelabs.ai
    service: http://host.docker.internal:3100     # blueprint apex
  - service: http_status:404                       # default deny
```

## ⚠️ 함정 — cloudflared SIGHUP 미지원

```ansi
[1m[31mcloudflared 는 SIGHUP graceful reload 를 지원하지 않습니다.[0m
```

**검증된 사실 (2026-05-15)**: `docker kill -s HUP axelabs-tunnel` 실행 시 프로세스가 종료됩니다. config 변경 = 컨테이너 재시작 = **5초 다운타임**.

**대응**: 변경 잦은 부분 (frame upstream, blue/green swap) 을 cloudflared config 에서 분리하고 **host-side proxy 뒤로 이전**.

→ 결과: cloudflared 는 `host.docker.internal:3712` 한 줄만 알고, blue/green swap 은 그 proxy 내부에서 처리. cloudflared 재시작 없음.

## Host-side proxy 패턴 (axe-frame-proxy)

**axe-frame-proxy** = Caddy reverse-proxy 컨테이너. host port `3712` 노출. 단일 책임: `/frame/*` 트래픽을 docker network 위의 `frame-mcp` alias (blue 또는 green 중 active 쪽) 로 라우팅. blue/green swap = alias 이동 + Caddy graceful reload (SIGHUP 지원, cloudflared 와 달리). frame 컨테이너의 build/recreate 와 무관하게 cloudflared 안정.


```
cloudflared (axelabs-tunnel)
        │
        ↓  HTTP /frame/* → host.docker.internal:3712
        │
        ↓
┌──── axe-frame-proxy (Caddy) ────┐
│                                 │
│  /frame/* → upstream (선택)      │
│              │                  │
│              ↓                  │
│   frame-mcp-blue :3710          │  ← network alias `frame-mcp`
│   frame-mcp-green :3711         │     (blue/green swap = alias move)
│                                 │
└─────────────────────────────────┘
```

**핵심**: cloudflared 는 `axe-frame-proxy` 만 알고, blue/green 의 실제 컨테이너 이름·포트는 모릅니다. swap 은 docker network alias 이동으로 처리 (`axe deploy frame axe --apply`).

## Docker 네트워크 — `artemis_default`

axelabs 플랫폼의 모든 컨테이너 (axelabs-tunnel, axe-frame-proxy, frame-mcp-blue/green, blueprint-app 등) 는 `artemis_default` 외부 docker 네트워크 위에서 통신합니다.

```bash
# 검증
docker network inspect artemis_default | grep '"Name"'
```

frame docker-compose.yml 에서:

```yaml
networks:
  artemis_default:
    external: true   # 별도 docker 명령으로 생성된 망에 합류
```

## 포트 할당 (CLAUDE.md SSOT)

| 범위 | 프로젝트 |
|---|---|
| 31xx | Blueprint |
| 32xx | Cortex |
| 33xx | Artemis |
| 34xx | Distributa |
| 35xx | Kolon Discussion |
| 36xx | mysrt |
| 37xx | frame |

전체 포트 테이블은 [/Users/axe/CLAUDE.md](https://github.com/soohunkang/blueprint/blob/main/CLAUDE.md) 가 SSOT. 새 서비스 추가 시 반드시 비어 있는 범위 확인.

## ⚠️ 함정 모음

| 함정 | 결과 | 회피 |
|---|---|---|
| cloudflared SIGHUP 직접 호출 | process 종료, 다운타임 | host-side proxy 뒤로 |
| frame 컨테이너 이름을 cloudflared 에 직접 명시 | blue/green swap 불가 | network alias 사용 |
| path strip 기대 (cloudflared) | 라우터가 prefix 못 찾음 | 각 서비스에 `/frame` prefix mount |
| 2-level subdomain (`frame.axe.axelabs.ai`) | Cloudflare Universal SSL 무료 미커버 | 1-level + path |
| `axellc.com` 으로 platform traffic | corporate ↔ platform 경계 혼탁 | 평행 운영, 신규는 `axelabs.ai` only |
| `artemis_default` external network 사전 부재 (신규 customer macmini) | `axe deploy` 시 `network artemis_default declared as external, but could not be found` → compose up fail | onboard step 에 `docker network create artemis_default` pre-step (또는 `axe deploy` 자체에 `_svc_step_network` 빌트인 — 2026-05-25 이후 적용 ✅, trap #17 of B-onboard-d-day-traps-2026-05-25) |

상세 결정 근거는 [DECISIONS](/ops/decisions) §3 D-config-13 참조.
