@@ -188,8 +188,67 @@ def get_version(self):
188188 return f .read ().strip ()
189189 return "unknown"
190190
191+ def copy_certs_to_docker_dir (self ):
192+ docker_certs_dir = Path ("/etc/docker" )
193+ docker_certs_dir .mkdir (parents = True , exist_ok = True )
194+
195+ certs_to_copy = ["ca.pem" , "server-cert.pem" , "server-key.pem" , "cert.pem" , "key.pem" ]
196+
197+ for cert in certs_to_copy :
198+ src = self .docker_certs_dir / cert
199+ dst = docker_certs_dir / cert
200+ if src .exists ():
201+ shutil .copy2 (src , dst )
202+ dst .chmod (0o600 )
203+
204+ def setup_docker_daemon_for_tcp (self ):
205+ docker_config_dir = Path ("/etc/docker" )
206+ docker_config_dir .mkdir (parents = True , exist_ok = True )
207+
208+ docker_port = 2376 if self .env == "production" else 2377
209+
210+ daemon_config = {
211+ "hosts" : [f"tcp://0.0.0.0:{ docker_port } " , "unix:///var/run/docker.sock" ],
212+ "tls" : True ,
213+ "tlsverify" : True ,
214+ "tlscacert" : str (self .docker_certs_dir / "ca.pem" ),
215+ "tlscert" : str (self .docker_certs_dir / "server-cert.pem" ),
216+ "tlskey" : str (self .docker_certs_dir / "server-key.pem" )
217+ }
218+
219+ daemon_json_path = docker_config_dir / "daemon.json"
220+
221+ with open (daemon_json_path , "w" ) as f :
222+ json .dump (daemon_config , f , indent = 2 )
223+
224+ try :
225+ result = subprocess .run (["systemctl" , "reload" , "docker" ],
226+ capture_output = True , text = True )
227+ if result .returncode != 0 :
228+ result = subprocess .run (["systemctl" , "restart" , "docker" ],
229+ capture_output = True , text = True )
230+ if result .returncode != 0 :
231+ print ("Error restarting Docker service:" )
232+ print (result .stderr )
233+ raise Exception ("Failed to restart Docker service" )
234+
235+ time .sleep (3 )
236+
237+ result = subprocess .run (["systemctl" , "status" , "docker" ],
238+ capture_output = True , text = True )
239+ if result .returncode != 0 :
240+ print ("Error checking Docker service status:" )
241+ print (result .stderr )
242+ raise Exception ("Failed to check Docker service status" )
243+
244+ except Exception as e :
245+ result = subprocess .run (["journalctl" , "-u" , "docker" , "-n" , "50" ],
246+ capture_output = True , text = True )
247+ print ("\n Docker service error logs:" )
248+ print (result .stdout )
249+ raise Exception (f"Failed to manage Docker service. Error: { str (e )} " )
250+
191251 def create_docker_context (self ):
192- """Create a Docker context for this environment instead of modifying the daemon."""
193252 docker_port = 2376 if self .env == "production" else 2377
194253 local_ip = self .get_local_ip ()
195254
@@ -225,76 +284,36 @@ def create_docker_context(self):
225284
226285 if test_result .returncode != 0 :
227286 print (f"Warning: Docker context created but connection test failed: { test_result .stderr } " )
228- print ("Make sure Docker daemon is configured to listen on TCP port" )
229- print (f"Please check that port { docker_port } is open and Docker is properly configured" )
287+ print ("Attempting to fix TLS configuration..." )
288+
289+ self .copy_certs_to_docker_dir ()
290+
291+ subprocess .run (["systemctl" , "restart" , "docker" ],
292+ capture_output = True , check = False )
293+
294+ time .sleep (5 )
295+
296+ test_result = subprocess .run (
297+ ["docker" , "--context" , self .context_name , "version" , "--format" , "{{.Server.Version}}" ],
298+ capture_output = True , text = True
299+ )
300+
301+ if test_result .returncode != 0 :
302+ print ("Failed to establish secure connection to Docker daemon" )
303+ print ("Please check Docker daemon logs for more information" )
304+ print ("You may need to manually configure Docker daemon TLS settings" )
230305
231306 return self .context_name
232307
233308 except Exception as e :
234309 print (f"Error setting up Docker context: { str (e )} " )
235310 raise
236-
237-
238- def setup_docker_daemon_for_tcp (self ):
239- """Configure Docker daemon to listen on TCP for the context to connect."""
240- docker_config_dir = Path ("/etc/docker" )
241- docker_config_dir .mkdir (parents = True , exist_ok = True )
242-
243- docker_port = 2376 if self .env == "production" else 2377
244-
245- daemon_config = {}
246- daemon_json_path = docker_config_dir / "daemon.json"
247-
248- if daemon_json_path .exists ():
249- with open (daemon_json_path , "r" ) as f :
250- try :
251- daemon_config = json .load (f )
252- except json .JSONDecodeError :
253- print ("Warning: Existing daemon.json is invalid. Starting with empty config." )
254-
255- hosts = daemon_config .get ("hosts" , ["unix:///var/run/docker.sock" ])
256- tcp_endpoint = f"tcp://0.0.0.0:{ docker_port } "
257-
258- if tcp_endpoint not in hosts :
259- hosts .append (tcp_endpoint )
260- daemon_config ["hosts" ] = hosts
261-
262- with open (daemon_json_path , "w" ) as f :
263- json .dump (daemon_config , f , indent = 2 )
264-
265- try :
266- result = subprocess .run (["systemctl" , "reload" , "docker" ],
267- capture_output = True , text = True )
268- if result .returncode != 0 :
269- result = subprocess .run (["systemctl" , "restart" , "docker" ],
270- capture_output = True , text = True )
271- if result .returncode != 0 :
272- print ("Error restarting Docker service:" )
273- print (result .stderr )
274- raise Exception ("Failed to restart Docker service" )
275-
276- time .sleep (3 )
277-
278- result = subprocess .run (["systemctl" , "status" , "docker" ],
279- capture_output = True , text = True )
280- if result .returncode != 0 :
281- print ("Error checking Docker service status:" )
282- print (result .stderr )
283- raise Exception ("Failed to check Docker service status" )
284-
285- except Exception as e :
286- result = subprocess .run (["journalctl" , "-u" , "docker" , "-n" , "50" ],
287- capture_output = True , text = True )
288- print ("\n Docker service error logs:" )
289- print (result .stdout )
290- raise Exception (f"Failed to manage Docker service. Error: { str (e )} " )
291311
292312 def setup_environment (self ):
293313 db_name = f"nixopus_{ self .generate_random_string (8 )} "
294314 username = f"nixopus_{ self .generate_random_string (8 )} "
295315 password = self .generate_random_string (16 )
296316
297- # we will use different ports for staging and production
298317 api_port = 8443 if self .env == "production" else 8444
299318 next_public_port = 7443 if self .env == "production" else 7444
300319 db_port = 5432 if self .env == "production" else 5433
@@ -304,6 +323,7 @@ def setup_environment(self):
304323 local_ip = self .get_local_ip ()
305324
306325 self .setup_docker_certs ()
326+ self .copy_certs_to_docker_dir ()
307327 self .setup_docker_daemon_for_tcp ()
308328 self .create_docker_context ()
309329
0 commit comments