Skip to content

fix(compose): rebuild loopback publishing on current main - #138

Merged
seonghobae merged 5 commits into
mainfrom
fix/compose-loopback-publishing-v2
Aug 12, 2026
Merged

fix(compose): rebuild loopback publishing on current main#138
seonghobae merged 5 commits into
mainfrom
fix/compose-loopback-publishing-v2

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Purpose

Rebuild the standalone Compose loopback-publishing security boundary directly on the current protected-main line instead of carrying the stale ancestry of #91.

TDD / replacement boundary

This replacement starts from protected main at 20283526e3b23f9ceb144a90467763e1f4910321. The original #91 feature owns five paths; current protected-main changes since #91's old base do not touch docker-compose.yml, docs/doctoring/compose-loopback-publishing.md, or tests/test_compose_network_boundary.py. README/CHANGELOG require deliberate composition rather than conflict-side selection.

Current RED head 9abb15a2ffa6e9464cd318809ab8b6dbf6e910f8 adds the exact normalized-Compose security regression first. It must fail while protected main still publishes PostgreSQL and health on all interfaces and still advertises the obsolete PG_LLM_BATCH_HEALTH_PORT environment knob. Production/docs changes follow only after that RED is observed.

No evidence from #91 transfers to this branch; all required checks/reviews must be reacquired on this replacement head.

Intended bounded behavior

  • PostgreSQL host publication: 127.0.0.1:5432:5432 only.
  • Component health host publication: 127.0.0.1:8080:8080 only.
  • No extra host-published service in the bundled standalone profile.
  • Remove the inert shell-era PG_LLM_BATCH_HEALTH_PORT Compose environment override.
  • Preserve Compose-internal networking and valid pgdata volume structure.
  • Document that production/remote ingress is an explicit deployment decision, not a widening of the standalone profile.

Keep Draft until RED -> GREEN, focused/full validation, exact-current-head required workflows, and current review-thread policy are satisfied.

Summary by CodeRabbit

  • 보안 개선

    • 독립형 Compose 환경의 PostgreSQL 및 컴포넌트 상태 확인 포트를 로컬 IPv4 루프백으로 제한했습니다.
    • 명시적인 설정이 없으면 외부 호스트 인터페이스에 포트가 노출되지 않습니다.
  • 문서

    • 로컬 접근, 내부 통신 및 추가 운영 보안 요구사항을 문서화했습니다.
  • 테스트

    • 허용된 포트 바인딩과 예상치 못한 호스트 포트 공개 여부를 자동으로 검증합니다.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

독립형 Compose 프로필의 PostgreSQL 및 component 포트를 IPv4 loopback으로 제한했습니다. 레거시 health port 설정을 제거했습니다. Compose 정규화 결과를 검사하는 네트워크 경계 테스트와 운영 문서를 추가했습니다.

Changes

Compose loopback 포트 경계

Layer / File(s) Summary
Compose 포트 바인딩 변경
docker-compose.yml
PostgreSQL과 component의 호스트 포트를 127.0.0.1에만 게시합니다. PG_LLM_BATCH_HEALTH_PORT 환경 변수를 제거하고 기본 health port 동작을 주석으로 설명합니다.
네트워크 경계 계약 검증
tests/test_compose_network_boundary.py
정규화된 Compose 설정에서 게시 서비스, 포트 수, IPv4 주소, 포트 번호 및 TCP 프로토콜을 검증합니다. 레거시 환경 변수와 예기치 않은 호스트 포트 게시도 검사합니다.
운영 결정 및 검증 문서
docs/doctoring/compose-loopback-publishing.md, CHANGELOG.md
loopback 게시, Compose 내부 통신, 외부 접근 시 별도 경계, 보안 요구사항 및 CI 검증 계약을 문서화합니다. Docker 공식 참고문헌을 추가합니다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 Compose의 loopback 포트 게시 보안 경계를 재구축하는 주요 변경 사항을 명확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/compose-loopback-publishing-v2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 12, 2026 00:25
@seonghobae
seonghobae merged commit b7f8a48 into main Aug 12, 2026
31 of 33 checks passed
@seonghobae
seonghobae deleted the fix/compose-loopback-publishing-v2 branch August 12, 2026 00:27

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_compose_network_boundary.py`:
- Around line 20-41: Require Docker Engine 28.0.0 or newer across the Compose
security checks: update _compose_model in tests/test_compose_network_boundary.py
to query and validate the daemon Server version, failing below 28.0.0; update
the local-only comment in docker-compose.yml at lines 17-19 to state the
supported runtime requirement; and update
docs/doctoring/compose-loopback-publishing.md at line 11 to document the minimum
version and the L2 exposure risk on older engines.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1614785d-ab15-4e01-8da9-841930331ecc

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6a021 and f9e6233.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • docker-compose.yml
  • docs/doctoring/compose-loopback-publishing.md
  • tests/test_compose_network_boundary.py

Comment on lines +20 to +41
def _compose_model() -> dict[str, Any]:
"""Return Docker Compose's normalized JSON model for the standalone stack."""
docker = shutil.which("docker")
assert docker is not None, "Docker CLI is required to validate Compose security"
result = subprocess.run(
[
docker,
"compose",
"-f",
str(_COMPOSE_PATH),
"config",
"--format",
"json",
],
cwd=_ROOT,
check=True,
capture_output=True,
text=True,
)
model = json.loads(result.stdout)
assert isinstance(model, dict)
return model

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

sed -n '1,120p' tests/test_compose_network_boundary.py
printf '\n--- docker-compose.yml ---\n'
sed -n '1,80p' docker-compose.yml
printf '\n--- documentation ---\n'
sed -n '1,80p' docs/doctoring/compose-loopback-publishing.md
printf '\n--- repository references ---\n'
rg -n --hidden -S '28\.0\.0|Server Version|docker version|compose_network|loopback|local-only|5432:5432|8080:8080' \
  -g '!node_modules' -g '!dist' -g '!build' .

Repository: ContextualWisdomLab/pg-llm-batch

Length of output: 11486


🌐 Web query:

Docker Engine port publishing localhost L2 access 28.0.0 release notes

💡 Result:

In Docker Engine 28.0.0, a significant security improvement addresses how ports bound to the loopback interface (localhost) are accessed [1][2]. Historically, in versions older than 28.0.0, ports published to localhost (e.g., -p 127.0.0.1:8080:80) could still be accessed by other hosts on the same Layer 2 (L2) network segment due to the way Docker managed iptables rules [1][3]. This meant that traffic destined for 127.0.0.1 could bypass expected host-level restrictions and be reached by remote devices on the local area network [3][2]. Docker Engine 28.0.0 resolves this by hardening container networking, ensuring that ports explicitly bound to the localhost interface are not accessible from external hosts on the LAN [1][2]. Additionally, Docker 28.0.0 introduces a default "secure by default" posture where unpublished container ports are no longer accessible from remote LAN hosts, even if the host's filter-FORWARD policy is set to ACCEPT [2][4]. For further details, refer to the official Docker Engine 28 release notes and the associated documentation on port publishing [5][1].

Citations:


Docker Engine 28.0.0 이상을 요구하고 강제하세요.

Docker Engine 28.0.0 미만에서는 127.0.0.1에 게시한 포트가 같은 L2 네트워크의 원격 호스트에서 접근될 수 있습니다.

  • 테스트에서 Docker daemon의 Server 버전을 검사하고, 28.0.0 미만이면 실패시키세요.
  • docker-compose.ymllocal-only 주석을 지원 런타임 조건에 맞게 수정하세요.
  • 문서에 Docker Engine 28.0.0 이상 요구사항과 이전 버전의 L2 노출 위험을 명시하세요.
🧰 Tools
🪛 ast-grep (0.45.1)

[error] 23-37: Command coming from incoming request
Context: subprocess.run(
[
docker,
"compose",
"-f",
str(_COMPOSE_PATH),
"config",
"--format",
"json",
],
cwd=_ROOT,
check=True,
capture_output=True,
text=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

📍 Affects 3 files
  • tests/test_compose_network_boundary.py#L20-L41 (this comment)
  • docker-compose.yml#L17-L19
  • docs/doctoring/compose-loopback-publishing.md#L11-L11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_compose_network_boundary.py` around lines 20 - 41, Require Docker
Engine 28.0.0 or newer across the Compose security checks: update _compose_model
in tests/test_compose_network_boundary.py to query and validate the daemon
Server version, failing below 28.0.0; update the local-only comment in
docker-compose.yml at lines 17-19 to state the supported runtime requirement;
and update docs/doctoring/compose-loopback-publishing.md at line 11 to document
the minimum version and the L2 exposure risk on older engines.

@Musthaq22

Copy link
Copy Markdown

138

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants