dokploy icon indicating copy to clipboard operation
dokploy copied to clipboard

Feature Request: Allow Binding Published Ports to a Specific Host IP for Enhanced Security

Open FrOz3nFir3 opened this issue 2 months ago • 3 comments

What problem will this feature address?

As a user deploying services on a server with multiple network interfaces (e.g., a public IP and a private VPN IP from Netbird/Tailscale), I need to control which network interface a service's port binds to. Currently, when a port is published in Dokploy, the code automatically detect the server's primary public IP address and binds the published port to that specific IP. This forces the service to be exposed on the public internet, even if the user's intention is to only access it via a secure, private network. Security is then entirely reliant on an external firewall, rather than being enforceable at the application/service level. This violates the Principle of Least Privilege, as the service is forced to listen on an interface it doesn't need to.

Use Case Example: A server has a public IP 203.0.113.10 and a private Netbird /Tailscale VPN IP 100.115.30.50. I deploy a PostgreSQL database and publish port 5432. Current Behavior: Dokploy binds the port to 203.0.113.10:5432, exposing it to the internet. Desired Behavior: I want to specify that the port should bind only to 100.115.30.50:5432, making it accessible exclusively over my private Netbird / Tailscale network and invisible to the public internet.

Describe the solution you'd like

I propose adding an optional "Host IP / External IP" text field in the "External Credentials" section for each database application. If the "Host IP" field is left blank, the system should maintain its current default behavior (binding to the server's public IP). This ensures backward compatibility. If a specific IP address is provided (e.g., 100.115.30.50), Dokploy should instruct Docker to bind the port exclusively to that IP.

Describe alternatives you've considered

none actually, it's not possible in docker update command to bind to specific ip address tried all possible ways.

Additional context

No response

Will you send a PR to implement it?

Maybe, need help

FrOz3nFir3 avatar Oct 29 '25 06:10 FrOz3nFir3

After extensive research and testing, I've confirmed that Docker Swarm services have a fundamental limitation and cannot be bound to a specific host IP address using the --publish flag. The hostip is not supported error is a known constraint of Swarm's design. This means my original feature request is not directly feasible. However, the core security problem remains services are exposed on 0.0.0.0 by if used external port (internet).

FrOz3nFir3 avatar Oct 29 '25 08:10 FrOz3nFir3

As an alternative, I found that using alpine/socat as a proxy service can help bind a database port to a specific ip host. Example:

docker run -d --name redis-netbird-proxy --restart always \
  -p 100.115.30.50:6379:6379 \
  --network dokploy-network \
  alpine/socat TCP-LISTEN:6379,fork,reuseaddr TCP:docker_app_name:6379

This keeps the database port internal (not directly exposed on all interfaces) and uses a socat proxy to control access. However, socat introduces user-space overhead and adds latency compared to direct kernel-level routing, also you need to manage the image / upgrade as well probably using the cron job.

Alternatively, exposing the database via an external port (internet) and protecting it with both a network firewall (e.g., provider-level or VPS firewall) and a host-based firewall (e.g., iptables) can provide defense in depth without the proxy performance hit. Still violation of Principle of least privilege due to binding of all interfaces (0.0.0.0)

Open to other solutions before closing this issue.

FrOz3nFir3 avatar Nov 02 '25 06:11 FrOz3nFir3

Yea, now only way to achieve this feature is manual docker compose file, but I think a single docker container doesn't require a Docker Compose file, a simpler approach is sufficient.

3RDNature avatar Nov 20 '25 07:11 3RDNature