Skip to content

Isolate networks of sensitive services - #196

Merged
bubacoder merged 1 commit into
mainfrom
feature/container-network-separation
Sep 9, 2025
Merged

Isolate networks of sensitive services#196
bubacoder merged 1 commit into
mainfrom
feature/container-network-separation

Conversation

@bubacoder

@bubacoder bubacoder commented Sep 8, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Automatically detects and creates required external Docker networks before running compose commands, reducing setup errors.
  • Improvements

    • Services moved to dedicated, isolated networks (backup, security, tools, dev) for better isolation and reliability.
    • Traefik now attaches to and routes across these networks so routing uses the correct network bindings.
    • Removed unnecessary shared proxy attachments from services that no longer require them.
  • Documentation

    • Added guidance on using isolated networks and overriding Traefik’s Docker network.
  • Chores

    • Standardized compose files to declare external networks explicitly.

@coderabbitai

coderabbitai Bot commented Sep 8, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Compose files move selected services off the shared proxy network into dedicated external networks and add traefik.docker.network labels; Traefik is attached to those networks. Endlessh removes external network usage. scripts/labctl.py now detects and creates external networks per compose file and removes hardcoded proxy creation.

Changes

Cohort / File(s) Summary
Backup Kopia services
docker/backup/kopia-b2.yaml, docker/backup/kopia-nas.yaml
Services changed network from proxy to external backup-kopia; added traefik.docker.network: backup-kopia label; top-level networks updated to backup-kopia: external: true.
Security services
docker/security/authelia.yaml, docker/security/wg-easy.yaml, docker/security/endlessh.yaml
authelia and wg-easy moved from proxy to security-authelia/security-wg-easy and gained traefik.docker.network labels; endlessh had its networks: - proxy and external network declaration removed.
Traefik router
docker/security/traefik.yaml, docker/security/traefik/traefik.yml
Traefik service attached to additional external networks (security-authelia, security-wg-easy, dev-code-server, tools-vaultwarden, backup-kopia); corresponding external network declarations added; comment added in static config about docker.network override.
Tools: Vaultwarden
docker/tools/vaultwarden.yaml
Moved service network from proxy to external tools-vaultwarden; added traefik.docker.network: tools-vaultwarden; top-level networks updated to tools-vaultwarden: external: true.
Dev: code-server
docker/dev/code-server.yaml
Restored/changed network from proxy to external dev-code-server; added traefik.docker.network: dev-code-server; top-level networks updated accordingly.
CLI: labctl
scripts/labctl.py
Added get_external_networks(compose_file) -> list[str] and create_service_networks(compose_file) -> None; docker_command(...) now calls create_service_networks to ensure external networks exist; removed hardcoded creation of the proxy network in cmd_config_apply.
Docs: Networking guidelines
docker/guidelines.md
Introduced pattern and guidance for isolated per-service external networks, examples for wiring Traefik with traefik.docker.network, and updated Traefik/network examples to reflect multi-network model.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant L as labctl.py
  participant CF as Compose File
  participant D as Docker Engine

  U->>L: run docker_command(compose_file, ...)
  L->>CF: read compose YAML
  L->>L: get_external_networks(compose_file)
  alt external networks found
    loop for each network
      L->>D: create_network_if_missing(network)
    end
  else none or parse error
    note right of L: proceed without creating networks
  end
  L->>D: docker compose <subcommand> ...
  D-->>U: output / result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Pre-merge checks (2 passed, 1 inconclusive)

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description Check ❓ Inconclusive There is no pull request description provided to verify alignment with the changeset, so it is unclear whether the description outlines the scope and rationale of the network isolation updates. Please add a description that summarizes the objective of isolating sensitive-service networks, lists the affected services, and explains the rationale behind the changes to guide reviewers.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title “Isolate networks of sensitive services” succinctly and accurately captures the primary purpose of the changeset, which is to move sensitive services onto dedicated external Docker networks and update related configurations. It is concise, focuses on the main change, and avoids extraneous details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/container-network-separation

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
scripts/labctl.py (1)

61-70: Minor: avoid duplicate network creates.

Deduplicate with a set before iterating.

-    networks = get_external_networks(compose_file)
-    for network_name in networks:
+    networks = set(get_external_networks(compose_file))
+    for network_name in sorted(networks):
         create_network_if_missing(network_name)
docker/security/traefik.yaml (1)

74-81: Top-level external networks declared—matches service attachments.

Nice. Optional: consider documenting intended trust level per network (sensitive vs general) for future audits.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b64c856 and 3126179.

📒 Files selected for processing (9)
  • docker/backup/kopia-b2.yaml (2 hunks)
  • docker/backup/kopia-nas.yaml (2 hunks)
  • docker/security/authelia.yaml (2 hunks)
  • docker/security/endlessh.yaml (0 hunks)
  • docker/security/traefik.yaml (2 hunks)
  • docker/security/traefik/traefik.yml (1 hunks)
  • docker/security/wg-easy.yaml (2 hunks)
  • docker/tools/vaultwarden.yaml (2 hunks)
  • scripts/labctl.py (2 hunks)
💤 Files with no reviewable changes (1)
  • docker/security/endlessh.yaml
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

All YAML files must be linted and valid

Files:

  • docker/security/traefik/traefik.yml
  • docker/security/traefik.yaml
  • docker/backup/kopia-nas.yaml
  • docker/security/authelia.yaml
  • docker/security/wg-easy.yaml
  • docker/tools/vaultwarden.yaml
  • docker/backup/kopia-b2.yaml
docker/**/*.{yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

docker/**/*.{yml,yaml}: Run KICS security scanning on Docker Compose YAML
Place Docker service definitions as YAML in category directories under docker/ (security, media, storage, monitoring, ai, tools)

Files:

  • docker/security/traefik/traefik.yml
  • docker/security/traefik.yaml
  • docker/backup/kopia-nas.yaml
  • docker/security/authelia.yaml
  • docker/security/wg-easy.yaml
  • docker/tools/vaultwarden.yaml
  • docker/backup/kopia-b2.yaml
scripts/**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Python code must pass Ruff linting

Files:

  • scripts/labctl.py
🪛 Ruff (0.12.2)
scripts/labctl.py

55-55: Consider moving this statement to an else block

(TRY300)


56-56: Do not catch blind exception: Exception

(BLE001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: check
🔇 Additional comments (8)
docker/security/traefik/traefik.yml (1)

32-32: Comment-only change looks good.

The inline note clarifies override behavior; no functional impact. YAML remains valid.

scripts/labctl.py (1)

151-153: Pre-flight network creation is in the right place.

Creating external networks before any compose action prevents “network not found” errors.

docker/backup/kopia-b2.yaml (1)

55-56: Network isolation + Traefik binding are consistent.

Service joins backup-kopia and label matches; external network declared. Looks good.

Also applies to: 59-59, 69-71

docker/security/wg-easy.yaml (1)

35-35: WG UI isolated via dedicated network and Traefik binding.

Bindings align (51821 service port via Traefik; only 51820/udp exposed). Good segmentation.

Also applies to: 38-38, 49-51

docker/security/authelia.yaml (1)

45-45: Authelia correctly moved to its own external network and bound in Traefik.

Matches the Traefik attachment plan.

Also applies to: 51-51, 62-64

docker/backup/kopia-nas.yaml (1)

53-53: Kopia NAS isolated and Traefik binding updated.

Network and label are aligned; external network declared.

Also applies to: 57-57, 67-69

docker/tools/vaultwarden.yaml (1)

22-22: Vaultwarden moved off proxy; Traefik binding updated.

Matches the per-service network isolation pattern.

Also applies to: 25-25, 36-38

docker/security/traefik.yaml (1)

37-40: Traefik network labels verified—no action needed. All traefik.docker.network labels are present in the Traefik service’s networks.

Comment thread scripts/labctl.py
@bubacoder
bubacoder force-pushed the feature/container-network-separation branch from 3126179 to 307f6e3 Compare September 9, 2025 17:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
docker/dev/code-server.yaml (1)

47-48: External network declaration is fine; ensure lifecycle is handled.

Since dev-code-server is external: true, make sure your labctl create step (or docs) guarantees network creation on new hosts to avoid “network not found” at compose up.

If desired, I can add a preflight Task that calls your create logic before docker compose up. Want me to open a small PR?

docker/guidelines.md (4)

38-46: Clear split between shared proxy and isolated networks.

Section reads well. Consider adding one sentence noting that external networks must pre-exist (or be auto-created by labctl) to prevent compose failures on first deploys.


48-104: Isolated-network pattern is solid; add two operational caveats.

  • Call out explicitly: Traefik must be joined to each isolated network used by services, and services must specify traefik.docker.network matching that network.
  • Note that services should not also join proxy unless there's a specific need.

You can append this note after the code blocks:

Note: For each isolated network a service uses, ensure the Traefik container is attached to the same network. Set `traefik.docker.network` to that network name. Do not attach the service to `proxy` in addition to the isolated network unless there is a justified cross-service requirement.

Also, the repo uses docker/dev/ (e.g., code-server). Please add “Dev” to the documented category list to stay consistent with directory structure. I can submit the doc tweak if you want.


240-245: Template: show the isolated-network label explicitly.

Good hint via comments. Recommend including a concrete example so copy-paste works.

     networks:
-      - proxy  # Or service-specific network for sensitive services
+      - proxy  # Or service-specific network for sensitive services
     labels:
       traefik.enable: true
-      # If using isolated network, specify which network Traefik should use
-      # traefik.docker.network: service-category-name
+      # If using isolated network, specify which network Traefik should use
+      # Example:
+      # traefik.docker.network: service-category-name

And optionally add a second full example block showing a service wired only to an isolated network with the label set.


254-255: Networks footer: include a commented isolated-network example.

This helps avoid forgetting to define the external network in service files that choose isolation.

 networks:
-  proxy:  # Or service-specific network for sensitive services
+  proxy:  # Or service-specific network for sensitive services
     external: true
+  # service-category-name:
+  #   external: true

If helpful, I can also add a short “Preflight” section with a one-liner to create any missing external networks via labctl before deploy.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3126179 and 307f6e3.

📒 Files selected for processing (11)
  • docker/backup/kopia-b2.yaml (2 hunks)
  • docker/backup/kopia-nas.yaml (2 hunks)
  • docker/dev/code-server.yaml (2 hunks)
  • docker/guidelines.md (3 hunks)
  • docker/security/authelia.yaml (2 hunks)
  • docker/security/endlessh.yaml (0 hunks)
  • docker/security/traefik.yaml (2 hunks)
  • docker/security/traefik/traefik.yml (1 hunks)
  • docker/security/wg-easy.yaml (2 hunks)
  • docker/tools/vaultwarden.yaml (2 hunks)
  • scripts/labctl.py (2 hunks)
💤 Files with no reviewable changes (1)
  • docker/security/endlessh.yaml
🚧 Files skipped from review as they are similar to previous changes (8)
  • docker/security/traefik.yaml
  • docker/security/authelia.yaml
  • docker/tools/vaultwarden.yaml
  • docker/security/wg-easy.yaml
  • scripts/labctl.py
  • docker/security/traefik/traefik.yml
  • docker/backup/kopia-b2.yaml
  • docker/backup/kopia-nas.yaml
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

All YAML files must be linted and valid

Files:

  • docker/dev/code-server.yaml
docker/**/*.{yml,yaml}

📄 CodeRabbit inference engine (CLAUDE.md)

docker/**/*.{yml,yaml}: Run KICS security scanning on Docker Compose YAML
Place Docker service definitions as YAML in category directories under docker/ (security, media, storage, monitoring, ai, tools)

Files:

  • docker/dev/code-server.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: check
🔇 Additional comments (1)
docker/dev/code-server.yaml (1)

33-36: Ensure Traefik service joins dev-code-server network and that network is declared external
Manually verify in your Traefik compose (e.g. docker/security/traefik.yaml) that under services.traefik.networks you include dev-code-server and that in networks: the dev-code-server entry is defined with external: true .

@bubacoder
bubacoder merged commit 351efeb into main Sep 9, 2025
4 checks passed
@bubacoder
bubacoder deleted the feature/container-network-separation branch September 9, 2025 18:22
@coderabbitai coderabbitai Bot mentioned this pull request Dec 25, 2025
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.

1 participant