--- tags: [infra, 51123, ip, ssot, runtime, research] --- # 51123 구 IP 하드코딩 실행 경로와 런타임 SSOT 불일치 리서치 ## 상위 원칙 - [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) - [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) - [Operational Guardrails](../../00_Philosophy/02_GUARDRAILS/Operational_Guardrails.md) - 공통 작성 원칙: [0_VALUE Writing Principles](https://github.com/happybell80/0_VALUE/blob/main/02_Governance/writing-principles.md) ## 관련 문서 - [Infra Journey](../README.md) - [51123 구 IP 하드코딩과 런타임 SSOT 불일치 이슈](../troubleshooting/260309_51123_구IP하드코딩_런타임SSOT불일치_이슈.md) - [24서버 우분투 터미널 불가, 네트워크 대역 오류, python3-apt 복구 기록](../troubleshooting/260309_24서버_우분투터미널불가_네트워크대역오류_python3apt복구.md) - [51123 구 IP 하드코딩 실행 경로 제거 계획](../plans/260309_51123_구IP하드코딩_실행경로제거_계획.md) ## Facts ### 1. 현재 51123의 실주소와 SSOT는 `192.168.0.100`이다 - 2026-03-09 현재 23 서버 호스트는 `robeing-brains`다. - `ip -brief addr` 기준 물리 NIC `enp6s0`의 IPv4는 `192.168.0.100/24`다. - `ip route` 기준 기본 게이트웨이는 `192.168.0.1`이다. - `/home/admin/workspace-config/runtime.env`에는 다음 값이 기록돼 있다. - `HOST_51123=192.168.0.100` - `ROBEING_DEFAULT_HOST=192.168.0.100` - `MONITOR_URL=http://192.168.0.100:9024` - `/home/admin/workspace-config/secrets.env`에는 `ROBEING_MONITOR_DATABASE_URL=postgresql://robeings:robeings@192.168.0.100:5432/main_db`가 기록돼 있다. ### 2. 과거 IP `192.168.219.45`는 실행 경로에도 아직 남아 있다 - 문서를 제외하고 검색했을 때 과거 IP가 남은 주요 실행 경로는 다음과 같다. - `auth-server/app/providers/gmail_passport.py` - `fluent-bit/data-prepper/pipelines.yaml` - `robeing/skill-email/docker-compose.yml` - `robeing/skill-calendar/docker-compose.yml` - `robeing/skill-calendar/services/google_calendar_service.py` - `robeing/admin-dashboard/backend/services/system_service.py` - 이 중 `frontend-* vite.config.ts`, `rb8001/.env.deploy.example`, `skill-rag-file/scripts/test_db_page_count.py` 같은 파일은 현재 서버 런타임보다 개발/예시/테스트 성격이 강하다. ### 3. 현재 active runtime에서 과거 IP를 실제로 사용하는 서비스가 있다 - `docker ps` 기준 23 서버에서 동작 중인 관련 컨테이너는 `auth-server`, `skill-email`, `skill-calendar`, `robeing_monitor`, `data-prepper`, `opensearch`다. - 컨테이너 env 확인 결과: - `auth-server` - `DATABASE_URL=postgresql://robeings:robeings@host.docker.internal:5432/main_db` - `skill-email` - `AUTH_SERVER_URL=http://192.168.219.45:9000` - `DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db` - `skill-calendar` - `DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db` - `robeing_monitor` - `HOST_51123=192.168.0.100` - `DATABASE_URL=postgresql://robeings:robeings@192.168.0.100:5432/main_db` - `MONITOR_URL=http://192.168.0.100:9024` - `data-prepper`는 env가 아니라 `pipelines.yaml`의 sink host를 사용하며, 현재 설정값이 `http://192.168.219.45:9200`다. ### 3-1. `skill-email`, `skill-calendar`의 주입 원천은 `.env`로 확정됐다 - `/home/admin/robeing/skill-email/.env`에는 아래 값이 직접 기록돼 있다. - `AUTH_SERVER_URL=http://192.168.219.45:9000` - `DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db` - `POSTGRES_CONNECTION_STRING=postgresql://robeings:robeings@192.168.219.45:5432/main_db` - `/home/admin/robeing/skill-calendar/.env`에는 아래 값이 직접 기록돼 있다. - `DATABASE_URL=postgresql://robeings:robeings@192.168.219.45:5432/main_db` - `docker compose ... config` 확인 결과, 두 서비스 모두 `.env` 값이 최종 environment로 해석돼 컨테이너에 주입된다. - 따라서 `skill-email`, `skill-calendar`의 현재 과거 IP 사용 원천은 "미확정 fallback"이 아니라 `.env`의 직접 주입으로 확정된다. ### 4. active runtime의 과거 IP 경로는 실제로 timeout을 낸다 - 23 서버 호스트에서 TCP 확인 결과: - `192.168.219.45:9000` -> `tcp_fail timed out` - `192.168.0.100:9000` -> `tcp_ok` - `192.168.219.45:5432` -> `tcp_fail timed out` - `192.168.0.100:5432` -> `tcp_ok` - `192.168.219.45:9200` -> `tcp_fail timed out` - `192.168.0.100:9200` -> `tcp_ok` - `skill-email` 컨테이너 내부에서 TCP 확인 결과: - `192.168.219.45:9000` -> `tcp_fail timed out` - `192.168.0.100:9000` -> `tcp_ok` - `skill-calendar` 컨테이너 내부에서 TCP 확인 결과: - `192.168.219.45:5432` -> `tcp_fail timed out` - `192.168.0.100:5432` -> `tcp_ok` - `data-prepper` 로그에는 아래 패턴이 반복 기록된다. - `Failed to initialize OpenSearch sink, retrying: Timeout connecting to [/192.168.219.45:9200]` ### 5. active runtime 후보이지만 현재 직접 장애 경로로 확인되지 않은 항목도 있다 - `auth-server`는 compose fallback에 `host.docker.internal:5432`를 사용하고 있고, 현재 컨테이너 env도 그 값으로 주입돼 있다. - 따라서 `auth-server/app/providers/gmail_passport.py`의 `192.168.219.45` 기본값은 코드 fallback 잔존이지만, 현재 컨테이너에서는 그 경로가 직접 사용 중이라고 확인되지는 않았다. - 24 서버의 `admin-dashboard` 코드에는 23 서버 fallback 구조가 존재하지만, 2026-03-09 현재 24 서버 `docker ps`는 빈 상태였고 해당 컨테이너는 active runtime으로 확인되지 않았다. - 과거 `ivada_project` 경로는 현재 워크스페이스에서 이미 제거돼, 이번 리서치 범위에서는 active 실행 경로 후보에서 제외한다. ### 6. active runtime의 주입 원천과 영향 범위를 구분할 수 있다 - `skill-email` - 현재 원천: `/home/admin/robeing/skill-email/.env` - 보조 잔존: `docker-compose.yml` fallback - `skill-calendar` - 현재 원천: `/home/admin/robeing/skill-calendar/.env` - 보조 잔존: `docker-compose.yml` fallback, `services/google_calendar_service.py` code default - `data-prepper` - 현재 원천: `/home/admin/fluent-bit/data-prepper/pipelines.yaml` - `auth-server` - 현재 active runtime 원천: `host.docker.internal:5432` - 보조 잔존: `gmail_passport.py` code default ### 7. 공용 SSOT 이름은 바뀌었지만 일부 실행 경로는 아직 옛 경로를 참조한다 - `/home/admin/robeing-gateway/docker-compose.yml`은 아직 `env_file`로 `/home/admin/infra-config/runtime.env`, `/home/admin/infra-config/secrets.env`를 사용한다. - 현재 `/home/admin/infra-config`는 존재하지 않으므로, 이 compose는 지금 상태 그대로는 공용 SSOT를 읽을 수 없다. - 다만 `robeing-gateway` 자체는 24로 옮기는 대상이 아니라 23 서버 제어면에 유지하는 것으로 방향이 고정됐다. - 따라서 51123 구 IP 문제는 값 치환 문제이면서 동시에 `workspace-config` 단일화가 아직 끝나지 않은 구조 문제이기도 하다. ## Interpretation ### 1. 문제는 “문서 잔존”이 아니라 “실행 중 서비스가 과거 IP를 실제 사용 중”인 상태다 - `skill-email`, `skill-calendar`, `data-prepper`는 현재도 과거 IP `192.168.219.45`를 런타임 값으로 사용한다. - 이 세 경로는 단순 잔존 문자열이 아니라, 실제 연결 시도와 실제 timeout 로그로 검증된 active 장애 경로다. ### 2. SSOT는 만들어졌지만 active runtime까지 치환되지 않았다 - `/home/admin/workspace-config/runtime.env`와 `secrets.env`는 이미 `192.168.0.100`으로 정리돼 있다. - 반면 host network 기반 compose와 개별 코드 기본값은 예전 IP를 여전히 보존하고 있어, SSOT가 “문서/공용 env”까지만 적용되고 “실행 경로”까지 내려오지 못했다. ### 3. 직접 원인은 host network 서비스의 fallback 구조와 개별 기본값 분산이다 - `skill-email`, `skill-calendar`, `data-prepper`는 모두 `network_mode: host` 또는 host 직접 접근 전제를 사용한다. - 이 구조에서 서비스 discovery 대신 서버 IP literal을 직접 박았고, 성수 이전 후 새 SSOT로 교체되지 않았다. - 따라서 문제의 직접 원인은 “과거 IP를 fallback으로 둔 compose/env/config가 active runtime에 남아 있는 것”이다. ### 4. 근본 원인은 인프라 기준값이 코드/compose/config마다 분산된 구조다 - 같은 51123 주소가 `runtime.env`, compose fallback, 코드 default, 구 디렉터리 복제본에서 각각 관리됐다. - 이 구조에서는 SSOT가 생겨도 기존 fallback을 제거하지 않으면 재배포, 개별 실행, 신규 컨테이너 생성 시 과거 값이 다시 살아난다. - 즉 이번 이슈는 값 하나의 오타가 아니라 “주소 기준값의 관리 경로가 여러 개”인 구조 문제다. ### 5. 트러블슈팅 문서를 닫으려면 active runtime 0건과 fallback 0건을 함께 달성해야 한다 - active runtime만 고쳐도 코드 fallback이 남아 있으면 다음 재빌드 때 재발할 수 있다. - 반대로 코드만 고치고 현재 돌고 있는 컨테이너 env와 pipeline이 그대로면 실제 장애는 즉시 남는다. - 따라서 닫힘 조건은 `현재 주입 원천 제거 + fallback 제거 + 재검증`의 3단계여야 한다. ## Unresolved - `robeing-gateway/docker-compose.yml`의 `workspace-config` 전환은 [51123 구 IP 하드코딩 실행 경로 제거 계획](../plans/260309_51123_구IP하드코딩_실행경로제거_계획.md)에 포함돼 더 이상 결정 미확정이 아니다. - 현재 남은 미확정은 `admin-dashboard`를 24에서 다시 활성화할 때 SSOT를 어떤 env 경로로 주입할지의 구현 방식이며, 이 항목은 active runtime 문제보다 후순위다. ## 상위 원칙/근거 문서 연결 - [Infra Project Identity](../../00_Philosophy/00_IDENTITY/Infra_Project_Identity.md) - [Core Infrastructure Principles](../../00_Philosophy/01_PRINCIPLES/Core_Infrastructure_Principles.md) - [Operational Guardrails](../../00_Philosophy/02_GUARDRAILS/Operational_Guardrails.md)