@@ -21,6 +21,7 @@ use crate::analytics::{self, AnalyticsClient, CommandSource};
2121use crate :: api:: streaming:: spawn_agent_shell_if_configured;
2222use crate :: handlers;
2323use crate :: state:: StateDb ;
24+ use coast_docker:: host:: { docker_endpoint_source_label, DockerEndpoint } ;
2425
2526#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
2627pub enum UpdateOperationKind {
@@ -120,6 +121,10 @@ pub struct AppState {
120121 /// Bollard Docker client connected to the host daemon.
121122 /// None in test environments where Docker is not available.
122123 pub docker : Option < bollard:: Docker > ,
124+ /// Resolved Docker endpoint metadata, if endpoint resolution succeeded.
125+ pub docker_endpoint : Option < DockerEndpoint > ,
126+ /// Last Docker connection error captured at daemon startup, if any.
127+ pub docker_connect_error : Option < String > ,
123128 /// Broadcast channel for WebSocket event notifications.
124129 pub event_bus : tokio:: sync:: broadcast:: Sender < CoastEvent > ,
125130 /// Persistent PTY sessions for the host terminal feature.
@@ -186,11 +191,23 @@ pub struct AppState {
186191impl AppState {
187192 /// Create a new `AppState` with the given state database and Docker client.
188193 pub fn new ( db : StateDb ) -> Self {
189- let docker = match coast_docker:: host:: connect_to_host_docker ( ) {
190- Ok ( docker) => Some ( docker) ,
194+ let probe = coast_docker:: host:: probe_host_docker ( ) ;
195+ let docker_endpoint = probe. endpoint . clone ( ) ;
196+ let ( docker, docker_connect_error) = match probe. docker {
197+ Ok ( docker) => ( Some ( docker) , None ) ,
191198 Err ( error) => {
192- warn ! ( error = %error, "Docker is unavailable at daemon startup" ) ;
193- None
199+ if let Some ( ref endpoint) = docker_endpoint {
200+ warn ! (
201+ source = docker_endpoint_source_label( & endpoint. source) ,
202+ host = %endpoint. host,
203+ context = endpoint. context. as_deref( ) . unwrap_or( "" ) ,
204+ error = %error,
205+ "Docker is unavailable at daemon startup"
206+ ) ;
207+ } else {
208+ warn ! ( error = %error, "Docker is unavailable at daemon startup" ) ;
209+ }
210+ ( None , Some ( error. to_string ( ) ) )
194211 }
195212 } ;
196213 let ( event_bus, _) = tokio:: sync:: broadcast:: channel ( 256 ) ;
@@ -214,6 +231,8 @@ impl AppState {
214231 Self {
215232 db : Mutex :: new ( db) ,
216233 docker,
234+ docker_endpoint,
235+ docker_connect_error,
217236 event_bus,
218237 pty_sessions : Mutex :: new ( std:: collections:: HashMap :: new ( ) ) ,
219238 exec_sessions : Mutex :: new ( std:: collections:: HashMap :: new ( ) ) ,
@@ -249,6 +268,8 @@ impl AppState {
249268 Self {
250269 db : Mutex :: new ( db) ,
251270 docker : None ,
271+ docker_endpoint : None ,
272+ docker_connect_error : None ,
252273 event_bus,
253274 pty_sessions : Mutex :: new ( std:: collections:: HashMap :: new ( ) ) ,
254275 exec_sessions : Mutex :: new ( std:: collections:: HashMap :: new ( ) ) ,
@@ -290,6 +311,11 @@ impl AppState {
290311 )
291312 . expect ( "bollard stub client creation should not fail" ) ,
292313 ) ;
314+ s. docker_endpoint = Some ( DockerEndpoint {
315+ host : "http://127.0.0.1:0" . to_string ( ) ,
316+ source : coast_docker:: host:: DockerEndpointSource :: EnvHost ,
317+ context : None ,
318+ } ) ;
293319 s
294320 }
295321
0 commit comments