opencode_cloud_core/docker/
mod.rs1mod client;
16pub mod container;
17mod dockerfile;
18mod error;
19pub mod exec;
20mod health;
21pub mod image;
22pub mod progress;
23pub mod update;
24pub mod users;
25mod version;
26pub mod volume;
27
28pub use client::DockerClient;
30pub use error::DockerError;
31pub use progress::ProgressReporter;
32
33pub use health::{
35 ExtendedHealthResponse, HealthError, HealthResponse, check_health, check_health_extended,
36};
37
38pub use dockerfile::{DOCKERFILE, IMAGE_NAME_DOCKERHUB, IMAGE_NAME_GHCR, IMAGE_TAG_DEFAULT};
40
41pub use image::{build_image, image_exists, pull_image};
43
44pub use update::{UpdateResult, has_previous_image, rollback_image, update_image};
46
47pub use version::{VERSION_LABEL, get_cli_version, get_image_version, versions_compatible};
49
50pub use exec::{exec_command, exec_command_exit_code, exec_command_with_stdin};
52
53pub use users::{
55 UserInfo, create_user, delete_user, list_users, lock_user, set_user_password, unlock_user,
56 user_exists,
57};
58
59pub use volume::{
61 MOUNT_CONFIG, MOUNT_PROJECTS, MOUNT_SESSION, VOLUME_CONFIG, VOLUME_NAMES, VOLUME_PROJECTS,
62 VOLUME_SESSION, ensure_volumes_exist, remove_all_volumes, remove_volume, volume_exists,
63};
64
65pub use container::{
67 CONTAINER_NAME, OPENCODE_WEB_PORT, container_exists, container_is_running, container_state,
68 create_container, remove_container, start_container, stop_container,
69};
70
71pub async fn setup_and_start(
84 client: &DockerClient,
85 opencode_web_port: Option<u16>,
86 env_vars: Option<Vec<String>>,
87 bind_address: Option<&str>,
88 cockpit_port: Option<u16>,
89 cockpit_enabled: Option<bool>,
90) -> Result<String, DockerError> {
91 volume::ensure_volumes_exist(client).await?;
93
94 let container_id = if container::container_exists(client, container::CONTAINER_NAME).await? {
96 let info = client
98 .inner()
99 .inspect_container(container::CONTAINER_NAME, None)
100 .await
101 .map_err(|e| {
102 DockerError::Container(format!("Failed to inspect existing container: {e}"))
103 })?;
104 info.id
105 .unwrap_or_else(|| container::CONTAINER_NAME.to_string())
106 } else {
107 container::create_container(
109 client,
110 None,
111 None,
112 opencode_web_port,
113 env_vars,
114 bind_address,
115 cockpit_port,
116 cockpit_enabled,
117 )
118 .await?
119 };
120
121 if !container::container_is_running(client, container::CONTAINER_NAME).await? {
123 container::start_container(client, container::CONTAINER_NAME).await?;
124 }
125
126 Ok(container_id)
127}
128
129pub async fn stop_service(client: &DockerClient, remove: bool) -> Result<(), DockerError> {
135 let name = container::CONTAINER_NAME;
136
137 if !container::container_exists(client, name).await? {
139 return Err(DockerError::Container(format!(
140 "Container '{name}' does not exist"
141 )));
142 }
143
144 if container::container_is_running(client, name).await? {
146 container::stop_container(client, name, None).await?;
147 }
148
149 if remove {
151 container::remove_container(client, name, false).await?;
152 }
153
154 Ok(())
155}