@@ -10,6 +10,7 @@ import (
1010 "github.com/google/uuid"
1111 "github.com/raghavyuva/nixopus-api/internal/features/deploy/types"
1212 "github.com/raghavyuva/nixopus-api/internal/features/logger"
13+ "github.com/raghavyuva/nixopus-api/internal/features/ssh"
1314 shared_types "github.com/raghavyuva/nixopus-api/internal/types"
1415)
1516
@@ -66,20 +67,53 @@ func (s *DeployService) prepareContainerConfig(
6667
6768// prepareHostConfig creates Docker host configuration with port bindings
6869func (s * DeployService ) prepareHostConfig (port nat.Port ) container.HostConfig {
70+ availablePort , err := s .getAvailablePort ()
71+ if err != nil {
72+ s .logger .Log (logger .Error , types .ErrFailedToGetAvailablePort .Error (), err .Error ())
73+ return container.HostConfig {}
74+ }
75+
6976 return container.HostConfig {
7077 NetworkMode : "bridge" ,
7178 PortBindings : map [nat.Port ][]nat.PortBinding {
7279 port : {
7380 {
7481 HostIP : "0.0.0.0" ,
75- HostPort : port . Port () ,
82+ HostPort : availablePort ,
7683 },
7784 },
7885 },
7986 PublishAllPorts : true ,
8087 }
8188}
8289
90+ func (s * DeployService ) getAvailablePort () (string , error ) {
91+ ssh := ssh .NewSSH ()
92+ client , err := ssh .Connect ()
93+ if err != nil {
94+ return "" , err
95+ }
96+ defer client .Close ()
97+
98+ generatePorts := "seq 49152 65535"
99+
100+ getUsedPorts := "command -v ss >/dev/null 2>&1 && ss -tan | awk '{print $4}' | cut -d':' -f2 | grep '[0-9]\\ {1,5\\ }' | sort -u || netstat -tan | awk '{print $4}' | grep ':[0-9]' | cut -d':' -f2 | sort -u"
101+
102+ cmd := fmt .Sprintf ("comm -23 <(%s) <(%s) | sort -R | head -n 1 | tr -d '\\ n'" , generatePorts , getUsedPorts )
103+
104+ output , err := client .Run (cmd )
105+ if err != nil {
106+ return "" , fmt .Errorf ("failed to find available port: %w" , err )
107+ }
108+
109+ port := string (output )
110+ if port == "" {
111+ return "" , fmt .Errorf ("no available ports found in range 49152-65535" )
112+ }
113+
114+ return port , nil
115+ }
116+
83117// prepareNetworkConfig creates Docker network configuration
84118func (s * DeployService ) prepareNetworkConfig () network.NetworkingConfig {
85119 return network.NetworkingConfig {
0 commit comments