Skip to content

Allowing multiple Fides containers in Docker#7327

Merged
galvana merged 5 commits intomainfrom
port-dedupe
Feb 7, 2026
Merged

Allowing multiple Fides containers in Docker#7327
galvana merged 5 commits intomainfrom
port-dedupe

Conversation

@galvana
Copy link
Copy Markdown
Contributor

@galvana galvana commented Feb 5, 2026

Description Of Changes

Allows multiple Fides servers to start in Docker. Generates unique image/container names and uses unallocated ports.

Steps to Confirm

  1. Run nox -s dev in one repo, verify the server starts
  2. Run nox -s dev in another Fides repo, verify the second server starts as well

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Feb 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fides-plus-nightly Ready Ready Preview, Comment Feb 7, 2026 2:46am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
fides-privacy-center Ignored Ignored Feb 7, 2026 2:46am

Request Review

@galvana galvana requested a review from johnewart February 5, 2026 21:54
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 5, 2026

Greptile Overview

Greptile Summary

This PR enables running multiple Fides development servers simultaneously by implementing dynamic port allocation and unique container naming based on git branch names. When port 8080 is already in use by a Fides container, the system automatically generates alternate ports using a hash of the branch name and appends branch-based suffixes to container and image names.

Key Changes:

  • Modified docker-compose.yml to use environment variables for all port mappings and container names
  • Added port conflict detection in dev_nox.py that checks if default ports are in use
  • Implemented branch-based hashing to generate alternate port ranges (9000-13900)
  • Dynamic image tagging with branch name suffixes to avoid image conflicts

Issues Found:

  • Mid-function os import violates Python import conventions
  • Container name detection checks static "fides" name, won't detect secondary instances with suffixes
  • Port collision risk: limited to 50 base port ranges, multiple branches could hash to same ports
  • Race condition between port availability check and container startup

Confidence Score: 3/5

  • This PR has moderate risk due to port collision logic issues and race conditions that could cause conflicts in multi-developer scenarios
  • The implementation successfully addresses the core requirement of running multiple instances, but has several logical flaws: (1) the container detection won't find secondary instances because it checks for static names, (2) the port hashing has collision risk with only 50 possible ranges, (3) race conditions exist between checking ports and binding them, and (4) a Python import style violation. These issues could cause unexpected failures when multiple developers try to run concurrent instances.
  • Pay close attention to noxfiles/dev_nox.py, particularly the port allocation and conflict detection logic

Important Files Changed

Filename Overview
docker-compose.yml Added environment variable support for dynamic port mapping and container naming
noxfiles/dev_nox.py Implemented port conflict detection and dynamic port allocation for multiple concurrent instances
noxfiles/docker_nox.py Modified build function to support dynamic image suffix for unique image tags

Copy link
Copy Markdown
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

return DEFAULT_PORTS.copy(), "", ""

# Port is in use - check if it's a fides or fidesplus container
if is_container_running("fides") or is_container_running("fidesplus-slim"):
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.

Check if container name should be fides${CONTAINER_SUFFIX:-} to match the dynamic naming in docker-compose.yml. Currently checking for static name "fides" which won't detect secondary instances running with suffixes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This check is intentionally looking for the primary container name. The logic flow is:

  1. If port 8080 is NOT in use → use defaults
  2. If port 8080 IS in use AND it's a fides/fidesplus container → use alternate ports
  3. If port 8080 IS in use by something else → error

Secondary instances use alternate ports (not 8080), so they wouldn't trigger this code path in the first place. The purpose of this check is to verify whether the port 8080 conflict is caused by a Fides instance (so we can safely use alternate ports) vs some other application (which should error). Checking for the static "fides" name (the primary container) is correct here.

Comment on lines +169 to +172
import os

if image_suffix:
os.environ["IMAGE_SUFFIX"] = image_suffix
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.

The os import is placed in the middle of a function rather than at the top of the module. Move this import to the top of the file with the other imports.

Suggested change
import os
if image_suffix:
os.environ["IMAGE_SUFFIX"] = image_suffix
# Check for port conflicts with existing fides instances BEFORE building
ports, container_suffix, image_suffix = check_for_conflicts(session)
# Set IMAGE_SUFFIX env var for the build process
if image_suffix:

Then add import os at the top of the file (around line 6).

Context Used: Rule from dashboard - Python imports should always be placed at the top of the file, not near the code that uses them. (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +60 to +70
def get_alternate_ports(branch: str) -> dict:
"""Calculate alternate ports based on branch name."""
hash_val = int(hashlib.md5(branch.encode()).hexdigest()[:8], 16)
base = 9000 + (hash_val % 50) * 100
return {
"api": base + 80,
"db": base + 32,
"redis": base + 79,
"admin_ui": base,
"privacy_center": base + 1,
}
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.

Port collision risk: if two different branches hash to the same base port range (hash_val % 50), they'll use identical ports and conflict. The modulo operation limits to 50 possible base values (9000-13900), which means collisions are likely with many branches.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is technically correct, but not a practical concern for this use case. This is a local development tool where developers typically run 2-3 instances at most. With 50 possible port ranges, the probability of collision for a small number of branches is very low.

That said, a potential improvement would be to verify the calculated alternate ports are actually available before using them, rather than assuming they will be free.

Comment on lines +85 to +88
# Check if the default API port is in use
if not is_port_in_use(DEFAULT_PORTS["api"]):
# No conflict, use defaults
return DEFAULT_PORTS.copy(), "", ""
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.

Race condition: between checking is_port_in_use() and actually starting containers, another process could bind to the port. Consider checking all required ports (api, db, redis, ui, pc) are available, not just the API port.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The race condition concern is theoretical - the window is milliseconds, and if Docker can't bind the port, it will error with a clear message. This is acceptable for a dev tool.

However, the suggestion to check all ports (not just API) has merit. If DB (5432) or Redis (6379) are in use by something else, those conflicts wouldn't be detected currently. This could be a future improvement, but isn't blocking for this PR.

Adrian Galvan and others added 2 commits February 5, 2026 17:00
Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown
Contributor

@thabofletcher thabofletcher left a comment

Choose a reason for hiding this comment

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

It works for me, but I did run into the race condition where they still both tried the same port from starting at the same time. I dont think its a typical use case for this though. Greptile needs to know an improvement when it sees one, considering running nox -s dev twice before wasn't even possible! Perfect is the enemy of the good @greptileai 😂

Image

@galvana galvana enabled auto-merge February 6, 2026 21:40
@galvana galvana added this pull request to the merge queue Feb 6, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks Feb 7, 2026
@galvana galvana enabled auto-merge February 7, 2026 02:42
@galvana galvana added this pull request to the merge queue Feb 7, 2026
Merged via the queue into main with commit ba6b874 Feb 7, 2026
54 of 55 checks passed
@galvana galvana deleted the port-dedupe branch February 7, 2026 03:22
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