Skip to main content

docker_compose_config/
service.rs

1use super::*;
2
3#[cfg(feature = "presets")]
4pub use presets::*;
5
6#[doc(hidden)]
7#[cfg(feature = "presets")]
8mod presets {
9	use super::*;
10
11	/// Ways of representing a service in a Docker preset.
12	#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
13	#[cfg_attr(feature = "schemars", derive(JsonSchema))]
14	#[serde(untagged)]
15	pub enum ServicePresetRef {
16		/// The id of a service preset.
17		PresetId(String),
18
19		/// The defitinion for a Docker service.
20		Preset(Box<DockerServicePreset>),
21	}
22
23	impl ServicePresetRef {
24		pub fn as_config(self) -> Option<Service> {
25			match self {
26				Self::PresetId(_) => None,
27				Self::Preset(docker_service_preset) => Some(docker_service_preset.config),
28			}
29		}
30
31		#[doc(hidden)]
32		pub fn requires_processing(&self) -> bool {
33			match self {
34				Self::PresetId(_) => true,
35				Self::Preset(data) => !data.extends_presets.is_empty(),
36			}
37		}
38	}
39
40	/// A preset for a Docker service
41	#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default, Merge)]
42	#[cfg_attr(feature = "schemars", derive(JsonSchema))]
43	#[serde(default)]
44	pub struct DockerServicePreset {
45		/// The list of extended presets.
46		#[serde(skip_serializing)]
47		#[merge(skip)]
48		pub extends_presets: IndexSet<String>,
49
50		#[serde(flatten)]
51		pub config: Service,
52	}
53}
54
55/// Defines a service for a Compose application.
56///
57/// See more: https://docs.docker.com/reference/compose-file/services/
58#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default, Merge)]
59#[cfg_attr(feature = "schemars", derive(JsonSchema))]
60#[serde(default)]
61pub struct Service {
62	/// `extends` lets you share common configurations among different files, or even different projects entirely.
63	///
64	/// See more: https://docs.docker.com/reference/compose-file/services/#extends
65	#[serde(skip_serializing_if = "Option::is_none")]
66	pub extends: Option<Extends>,
67
68	/// A string that specifies a custom container name, rather than a name generated by default. Compose does not scale a service beyond one container if the Compose file specifies a container_name. Attempting to do so results in an error.
69	///
70	/// container_name follows the regex format of [a-zA-Z0-9][a-zA-Z0-9_.-]+
71	///
72	/// See more: https://docs.docker.com/reference/compose-file/services/#container_name
73	#[serde(skip_serializing_if = "Option::is_none")]
74	pub container_name: Option<String>,
75
76	/// A custom host name to use for the service container. It must be a valid RFC 1123 hostname.
77	#[serde(skip_serializing_if = "Option::is_none")]
78	pub hostname: Option<String>,
79
80	/// Specifies the image to start the container from. See more: https://docs.docker.com/reference/compose-file/services/#image
81	#[serde(skip_serializing_if = "Option::is_none")]
82	pub image: Option<String>,
83
84	/// Specifies the build configuration for creating a container image from source, as defined in the [Compose Build Specification](https://docs.docker.com/reference/compose-file/build/).
85	#[serde(skip_serializing_if = "Option::is_none", rename = "build")]
86	#[merge(with = merge_options)]
87	pub build_: Option<BuildStep>,
88
89	/// With the depends_on attribute, you can control the order of service startup and shutdown. It is useful if services are closely coupled, and the startup sequence impacts the application's functionality.
90	///
91	/// See more: https://docs.docker.com/reference/compose-file/services/#depends_on
92	#[serde(skip_serializing_if = "Option::is_none")]
93	#[merge(with = merge_options)]
94	pub depends_on: Option<DependsOn>,
95
96	/// Overrides the default command declared by the container image, for example by Dockerfile's CMD.
97	///
98	/// See more: https://docs.docker.com/reference/compose-file/services/#command
99	#[serde(skip_serializing_if = "Option::is_none")]
100	pub command: Option<StringOrList>,
101
102	/// Declares the default entrypoint for the service container. This overrides the ENTRYPOINT instruction from the service's Dockerfile.
103	///
104	/// See more: https://docs.docker.com/reference/compose-file/services/#entrypoint
105	#[serde(skip_serializing_if = "Option::is_none")]
106	pub entrypoint: Option<StringOrList>,
107
108	/// Declares a check that's run to determine whether or not the service containers are "healthy".
109	///
110	/// See more: https://docs.docker.com/reference/compose-file/services/#healthcheck
111	#[serde(skip_serializing_if = "Option::is_none")]
112	pub healthcheck: Option<Healthcheck>,
113
114	/// Defines the (incoming) port or a range of ports that Compose exposes from the container. These ports must be accessible to linked services and should not be published to the host machine. Only the internal container ports can be specified.
115	///
116	/// See more: https://docs.docker.com/reference/compose-file/services/#expose
117	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
118	pub expose: BTreeSet<StringOrNum>,
119
120	/// One or more files that contain environment variables to be passed to the containers.
121	///
122	/// See more: https://docs.docker.com/reference/compose-file/services/#env_file
123	#[serde(skip_serializing_if = "Option::is_none")]
124	#[merge(with = merge_options)]
125	pub env_file: Option<Envfile>,
126
127	/// Defines environment variables set in the container. environment can use either an array or a map. Any boolean values; true, false, yes, no, should be enclosed in quotes to ensure they are not converted to True or False by the YAML parser.
128	///
129	/// See more: https://docs.docker.com/reference/compose-file/services/#environment
130	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
131	pub environment: ListOrMap,
132
133	/// Defines annotations for the container. annotations can use either an array or a map.
134	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
135	pub annotations: ListOrMap,
136
137	/// Requires: Docker Compose 2.20.0 and later
138	///
139	/// When attach is defined and set to false Compose does not collect service logs, until you explicitly request it to.
140	#[serde(skip_serializing_if = "Option::is_none")]
141	pub attach: Option<bool>,
142
143	/// Defines a set of configuration options to set block I/O limits for a service.
144	///
145	/// See more: https://docs.docker.com/reference/compose-file/services/#blkio_config
146	#[serde(skip_serializing_if = "Option::is_none")]
147	pub blkio_config: Option<BlkioSettings>,
148
149	/// Specifies additional container [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) as strings.
150	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
151	pub cap_add: BTreeSet<String>,
152
153	/// Specifies container [capabilities](https://man7.org/linux/man-pages/man7/capabilities.7.html) to drop as strings.
154	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
155	pub cap_drop: BTreeSet<String>,
156
157	/// Requires: Docker Compose 2.15.0 and later
158	///
159	/// Specifies the cgroup namespace to join. When unset, it is the container runtime's decision to select which cgroup namespace to use, if supported.
160	///
161	/// host: Runs the container in the Container runtime cgroup namespace.
162	/// private: Runs the container in its own private cgroup namespace.
163	#[serde(skip_serializing_if = "Option::is_none")]
164	pub cgroup: Option<Cgroup>,
165
166	/// Specifies an optional parent cgroup for the container.
167	#[serde(skip_serializing_if = "Option::is_none")]
168	pub cgroup_parent: Option<String>,
169
170	/// Lets services adapt their behaviour without the need to rebuild a Docker image.
171	///
172	/// See more: https://docs.docker.com/reference/compose-file/services/#configs
173	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
174	pub configs: BTreeSet<ServiceConfigOrSecret>,
175
176	/// The number of usable CPUs for service container.
177	#[serde(skip_serializing_if = "Option::is_none")]
178	pub cpu_count: Option<StringOrNum>,
179
180	/// The usable percentage of the available CPUs.
181	#[serde(skip_serializing_if = "Option::is_none")]
182	pub cpu_percent: Option<StringOrNum>,
183
184	/// Configures CPU CFS (Completely Fair Scheduler) period when a platform is based on Linux kernel.
185	#[serde(skip_serializing_if = "Option::is_none")]
186	pub cpu_period: Option<StringOrNum>,
187
188	/// Configures CPU CFS (Completely Fair Scheduler) quota when a platform is based on Linux kernel.
189	#[serde(skip_serializing_if = "Option::is_none")]
190	pub cpu_quota: Option<StringOrNum>,
191
192	/// A service container's relative CPU weight versus other containers.
193	#[serde(skip_serializing_if = "Option::is_none")]
194	pub cpu_shares: Option<StringOrNum>,
195
196	/// Configures CPU allocation parameters for platforms with support for real-time scheduler. It can be either an integer value using microseconds as unit or a duration.
197	#[serde(skip_serializing_if = "Option::is_none")]
198	pub cpu_rt_period: Option<StringOrNum>,
199
200	/// Configures CPU allocation parameters for platforms with support for real-time scheduler. It can be either an integer value using microseconds as unit or a duration.
201	#[serde(skip_serializing_if = "Option::is_none")]
202	pub cpu_rt_runtime: Option<StringOrNum>,
203
204	/// The number of (potentially virtual) CPUs to allocate to service containers. This is a fractional number. 0.000 means no limit.
205	///
206	/// When set, cpus must be consistent with the cpus attribute in the Deploy Specification.
207	#[serde(skip_serializing_if = "Option::is_none")]
208	pub cpus: Option<StringOrNum>,
209
210	/// The explicit CPUs in which to permit execution. Can be a range 0-3 or a list 0,1
211	#[serde(skip_serializing_if = "Option::is_none")]
212	pub cpuset: Option<String>,
213
214	/// Configures the credential spec for a managed service account.
215	///
216	/// See more: https://docs.docker.com/reference/compose-file/services/#credential_spec
217	#[serde(skip_serializing_if = "Option::is_none")]
218	pub credential_spec: Option<CredentialSpec>,
219
220	/// Specifies the configuration for the deployment and lifecycle of services, as defined in the [Compose Deploy Specification](https://docs.docker.com/reference/compose-file/deploy)
221	#[serde(skip_serializing_if = "Option::is_none")]
222	pub deploy: Option<Deploy>,
223
224	/// Specifies the development configuration for maintaining a container in sync with source.
225	///
226	/// See more: https://docs.docker.com/reference/compose-file/develop
227	#[serde(skip_serializing_if = "Option::is_none")]
228	#[merge(with = merge_options)]
229	pub develop: Option<DevelopmentSettings>,
230
231	/// A list of device cgroup rules for this container. The format is the same format the Linux kernel specifies in the Control [Groups Device Whitelist Controller]().
232	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
233	pub device_cgroup_rules: BTreeSet<String>,
234
235	/// Defines a list of device mappings for created containers.
236	///
237	/// See more: https://docs.docker.com/reference/compose-file/services/#devices
238	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
239	pub devices: BTreeSet<DeviceMapping>,
240
241	/// Custom DNS servers to set on the container network interface configuration. It can be a single value or a list.
242	#[serde(default, skip_serializing_if = "StringOrSortedList::is_empty")]
243	pub dns: StringOrSortedList,
244
245	/// Custom DNS options to be passed to the container’s DNS resolver (/etc/resolv.conf file on Linux).
246	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
247	pub dns_opt: BTreeSet<String>,
248
249	/// Custom DNS search domains to set on container network interface configuration. It can be a single value or a list.
250	#[serde(default, skip_serializing_if = "StringOrSortedList::is_empty")]
251	pub dns_search: StringOrSortedList,
252
253	/// A custom domain name to use for the service container. It must be a valid RFC 1123 hostname.
254	#[serde(skip_serializing_if = "Option::is_none")]
255	pub domainname: Option<String>,
256
257	/// Requires: Docker Compose 2.27.1 and later
258	///
259	/// Specifies a list of options as key-value pairs to pass to the driver. These options are driver-dependent.
260	/// Consult the [network drivers documentation](https://docs.docker.com/engine/network/) for more information.
261	#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
262	pub driver_opts: BTreeMap<String, StringOrNum>,
263
264	/// `external_links` link service containers to services managed outside of your Compose application. `external_links` define the name of an existing service to retrieve using the platform lookup mechanism.
265	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
266	pub external_links: BTreeSet<String>,
267
268	/// Adds hostname mappings to the container network interface configuration (/etc/hosts for Linux).
269	///
270	/// See more: https://docs.docker.com/reference/compose-file/services/#extra_hosts
271	#[serde(skip_serializing_if = "Option::is_none")]
272	#[merge(with = merge_options)]
273	pub extra_hosts: Option<ExtraHosts>,
274
275	/// Requires: Docker Compose 2.30.0 and later
276	///
277	/// Specifies GPU devices to be allocated for container usage.
278	#[serde(skip_serializing_if = "Option::is_none")]
279	#[merge(with = merge_options)]
280	pub gpus: Option<Gpus>,
281
282	/// Additional groups, by name or number, which the user inside the container must be a member of.
283	///
284	/// See more: https://docs.docker.com/reference/compose-file/services/#group_add
285	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
286	pub group_add: BTreeSet<StringOrNum>,
287
288	/// Runs an init process (PID 1) inside the container that forwards signals and reaps processes. Set this option to true to enable this feature for the service.
289	///
290	/// The init binary that is used is platform specific.
291	#[serde(skip_serializing_if = "Option::is_none")]
292	pub init: Option<bool>,
293
294	/// ipc configures the IPC isolation mode set by the service container.
295	///
296	/// shareable: Gives the container its own private IPC namespace, with a possibility to share it with other containers.
297	///
298	/// service:{name}: Makes the container join another container's (shareable) IPC namespace.
299	///
300	/// See more: https://docs.docker.com/reference/compose-file/services/#ipc
301	#[serde(skip_serializing_if = "Option::is_none")]
302	pub ipc: Option<String>,
303
304	/// Container isolation technology to use. Supported values are platform-specific.
305	#[serde(skip_serializing_if = "Option::is_none")]
306	pub isolation: Option<String>,
307
308	/// Add metadata to containers. You can use either an array or a map.
309	///
310	/// See more: https://docs.docker.com/reference/compose-file/services/#labels
311	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
312	pub labels: ListOrMap,
313
314	/// Requires: Docker Compose 2.32.2 and later
315	///
316	///The label_file attribute lets you load labels for a service from an external file or a list of files. This provides a convenient way to manage multiple labels without cluttering the Compose file.
317	/// See more: https://docs.docker.com/reference/compose-file/services/#label_file
318	#[serde(default, skip_serializing_if = "StringOrSortedList::is_empty")]
319	pub label_file: StringOrSortedList,
320
321	/// Defines a network link to containers in another service. Either specify both the service name and a link alias (SERVICE:ALIAS), or just the service name.
322	///
323	/// See more: https://docs.docker.com/reference/compose-file/services/#links
324	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
325	pub links: BTreeSet<String>,
326
327	/// Defines the logging configuration for the service.
328	///
329	/// See more: https://docs.docker.com/reference/compose-file/services/#logging
330	#[serde(skip_serializing_if = "Option::is_none")]
331	pub logging: Option<LoggingSettings>,
332
333	/// Sets a Mac address for the service container.
334	///
335	/// See more: https://docs.docker.com/reference/compose-file/services/#mac_address
336	#[serde(skip_serializing_if = "Option::is_none")]
337	pub mac_address: Option<String>,
338
339	/// Memory limit for the container. A string value can use suffix like '2g' for 2 gigabytes.
340	///
341	/// When set, mem_limit must be consistent with the limits.memory attribute in the [Deploy Specification](https://docs.docker.com/reference/compose-file/deploy/#memory).
342	#[serde(skip_serializing_if = "Option::is_none")]
343	pub mem_limit: Option<StringOrNum>,
344
345	/// Configures a reservation on the amount of memory a container can allocate, set as a string expressing a [byte value](https://docs.docker.com/reference/compose-file/extension/#specifying-byte-values).
346	///
347	/// When set, mem_reservation must be consistent with the reservations.memory attribute in the [Deploy Specification](https://docs.docker.com/reference/compose-file/deploy/#memory).
348	#[serde(skip_serializing_if = "Option::is_none")]
349	pub mem_reservation: Option<StringOrNum>,
350
351	/// Defines as a percentage, a value between 0 and 100, for the host kernel to swap out anonymous memory pages used by a container.
352	///
353	///  0: Turns off anonymous page swapping.
354	/// 100: Sets all anonymous pages as swappable.
355	///
356	/// The default value is platform specific.
357	#[serde(skip_serializing_if = "Option::is_none")]
358	pub mem_swappiness: Option<u8>,
359
360	/// Defines the amount of memory the container is allowed to swap to disk.
361	///
362	/// See more: https://docs.docker.com/reference/compose-file/services/#memswap_limit
363	#[serde(skip_serializing_if = "Option::is_none")]
364	pub memswap_limit: Option<StringOrNum>,
365
366	/// Requires: Docker Compose 2.38.0 and later
367	///
368	/// Defines which AI models the service should use at runtime. Each referenced model must be defined under the [`models` top-level element](https://docs.docker.com/reference/compose-file/models/).
369	///
370	/// See more: https://docs.docker.com/reference/compose-file/services/#models
371	#[serde(skip_serializing_if = "Option::is_none")]
372	#[merge(with = merge_options)]
373	pub models: Option<ServiceModels>,
374
375	/// Sets a service container's network mode.
376	///
377	/// none: Turns off all container networking.
378	/// host: Gives the container raw access to the host's network interface.
379	/// service:{name}: Gives the container access to the specified container by referring to its service name.
380	/// container:{name}: Gives the container access to the specified container by referring to its container ID.
381	///
382	/// See more: https://docs.docker.com/reference/compose-file/services/#network_mode
383	#[serde(skip_serializing_if = "Option::is_none")]
384	pub network_mode: Option<NetworkMode>,
385
386	/// The networks attribute defines the networks that service containers are attached to, referencing entries under the networks top-level element.
387	///
388	/// See more: https://docs.docker.com/reference/compose-file/services/#networks
389	#[serde(skip_serializing_if = "Option::is_none")]
390	#[merge(with = merge_options)]
391	pub networks: Option<ServiceNetworks>,
392
393	/// If `oom_kill_disable` is set, Compose configures the platform so it won't kill the container in case of memory starvation.
394	#[serde(skip_serializing_if = "Option::is_none")]
395	pub oom_kill_disable: Option<bool>,
396
397	/// Tunes the preference for containers to be killed by platform in case of memory starvation. Value must be within -1000,1000 range.
398	#[serde(skip_serializing_if = "Option::is_none")]
399	pub oom_score_adj: Option<i32>,
400
401	/// Sets the PID mode for container created by Compose. Supported values are platform specific.
402	#[serde(skip_serializing_if = "Option::is_none")]
403	pub pid: Option<String>,
404
405	/// Tune a container's PIDs limit. Set to -1 for unlimited PIDs.
406	///
407	/// When set, pids_limit must be consistent with the pids attribute in the [Deploy Specification](https://docs.docker.com/reference/compose-file/deploy/#pids).
408	#[serde(skip_serializing_if = "Option::is_none")]
409	pub pids_limit: Option<i64>,
410
411	/// The target platform the containers for the service run on. It uses the os[/arch[/variant]] syntax.
412	///
413	/// The values of os, arch, and variant must conform to the convention used by the OCI Image Spec.
414	///
415	/// Compose uses this attribute to determine which version of the image is pulled and/or on which platform the service’s build is performed.
416	#[serde(skip_serializing_if = "Option::is_none")]
417	pub platform: Option<String>,
418
419	/// Used to define the port mappings between the host machine and the containers.
420	///
421	/// See more: https://docs.docker.com/reference/compose-file/services/#ports
422	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
423	pub ports: BTreeSet<Port>,
424
425	/// Requires: Docker Compose 2.30.0 and later
426	///
427	///Defines a sequence of lifecycle hooks to run after a container has started. The exact timing of when the command is run is not guaranteed.
428	///
429	/// See more: https://docs.docker.com/reference/compose-file/services/#post_start
430	#[serde(default, skip_serializing_if = "Vec::is_empty")]
431	pub post_start: Vec<ServiceHook>,
432
433	/// Defines a sequence of lifecycle hooks to run before the container is stopped. These hooks won't run if the container stops by itself or is terminated suddenly.
434	#[serde(default, skip_serializing_if = "Vec::is_empty")]
435	pub pre_stop: Vec<ServiceHook>,
436
437	/// Configures the service container to run with elevated privileges. Support and actual impacts are platform specific.
438	#[serde(skip_serializing_if = "Option::is_none")]
439	pub privileged: Option<bool>,
440
441	/// Defines a list of named profiles for the service to be enabled under. If unassigned, the service is always started but if assigned, it is only started if the profile is activated.
442	///
443	/// See more: https://docs.docker.com/reference/compose-file/services/#profiles
444	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
445	pub profiles: BTreeSet<String>,
446
447	/// Defines a service that Compose won't manage directly. Compose delegated the service lifecycle to a dedicated or third-party component.
448	///
449	/// See more: https://docs.docker.com/reference/compose-file/services/#provider
450	#[serde(skip_serializing_if = "Option::is_none")]
451	pub provider: Option<Provider>,
452
453	/// Defines the decisions Compose makes when it starts to pull images.
454	///
455	/// See more: https://docs.docker.com/reference/compose-file/services/#pull_policy
456	#[serde(skip_serializing_if = "Option::is_none")]
457	pub pull_policy: Option<PullPolicy>,
458
459	/// Time after which to refresh the image. Used with pull_policy=refresh.
460	#[serde(skip_serializing_if = "Option::is_none")]
461	pub pull_refresh_after: Option<String>,
462
463	/// Configures the service container to be created with a read-only filesystem.
464	#[serde(skip_serializing_if = "Option::is_none")]
465	pub read_only: Option<bool>,
466
467	/// Defines the policy that the platform applies on container termination.
468	///
469	/// See more: https://docs.docker.com/reference/compose-file/services/#restart
470	#[serde(skip_serializing_if = "Option::is_none")]
471	pub restart: Option<Restart>,
472
473	/// Specifies which runtime to use for the service’s containers.
474	///
475	/// See more: https://docs.docker.com/reference/compose-file/services/#runtime
476	#[serde(skip_serializing_if = "Option::is_none")]
477	pub runtime: Option<String>,
478
479	/// Specifies the default number of containers to deploy for this service. When both are set, scale must be consistent with the replicas attribute in the [Deploy Specification](https://docs.docker.com/reference/compose-file/deploy/#replicas).
480	#[serde(skip_serializing_if = "Option::is_none")]
481	pub scale: Option<u64>,
482
483	/// The secrets attribute grants access to sensitive data defined by the secrets top-level element on a per-service basis. Services can be granted access to multiple secrets.
484	///
485	/// See more: https://docs.docker.com/reference/compose-file/services/#secrets
486	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
487	pub secrets: BTreeSet<ServiceConfigOrSecret>,
488
489	/// Overrides the default labeling scheme for each container.
490	///
491	/// See more: https://docs.docker.com/reference/compose-file/services/#security_opt
492	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
493	pub security_opt: BTreeSet<String>,
494
495	/// Size of /dev/shm. A string value can use suffix like '2g' for 2 gigabytes.
496	#[serde(skip_serializing_if = "Option::is_none")]
497	pub shm_size: Option<StringOrNum>,
498
499	/// Configures a service's container to run with an allocated stdin. This is the same as running a container with the -i flag. For more information, see [Keep stdin open](https://docs.docker.com/reference/cli/docker/container/run/#interactive).
500	#[serde(skip_serializing_if = "Option::is_none")]
501	pub stdin_open: Option<bool>,
502
503	/// Specifies how long Compose must wait when attempting to stop a container if it doesn't handle SIGTERM (or whichever stop signal has been specified with stop_signal), before sending SIGKILL. It's specified as a duration.
504	///
505	/// Default value is 10 seconds for the container to exit before sending SIGKILL.
506	#[serde(skip_serializing_if = "Option::is_none")]
507	pub stop_grace_period: Option<String>,
508
509	/// The signal that Compose uses to stop the service containers. If unset containers are stopped by Compose by sending SIGTERM.
510	#[serde(skip_serializing_if = "Option::is_none")]
511	pub stop_signal: Option<String>,
512
513	/// Defines storage driver options for a service.
514	#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
515	pub storage_opt: BTreeMap<String, Value>,
516
517	/// Defines kernel parameters to set in the container. sysctls can use either an array or a map.
518	///
519	/// See more: https://docs.docker.com/reference/compose-file/services/#sysctls
520	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
521	pub sysctls: ListOrMap,
522
523	/// Mounts a temporary file system inside the container. It can be a single value or a list.
524	///
525	/// See more: https://docs.docker.com/reference/compose-file/services/#tmpfs
526	#[serde(skip_serializing_if = "Option::is_none")]
527	pub tmpfs: Option<StringOrList>,
528
529	/// Configures a service's container to run with a TTY. This is the same as running a container with the -t or --tty flag. For more information, see [Allocate a pseudo-TTY](https://docs.docker.com/reference/cli/docker/container/run/#tty).
530	#[serde(skip_serializing_if = "Option::is_none")]
531	pub tty: Option<bool>,
532
533	/// Overrides the default ulimits for a container. It's specified either as an integer for a single limit or as mapping for soft/hard limits.
534	///
535	/// See more: https://docs.docker.com/reference/compose-file/services/#ulimits
536	#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
537	pub ulimits: BTreeMap<String, Ulimit>,
538
539	/// When `use_api_socket` is set, the container is able to interact with the underlying container engine through the API socket. Your credentials are mounted inside the container so the container acts as a pure delegate for your commands relating to the container engine. Typically, commands ran by container can pull and push to your registry.
540	#[serde(skip_serializing_if = "Option::is_none")]
541	pub use_api_socket: Option<bool>,
542
543	/// Overrides the user used to run the container process. The default is set by the image, for example Dockerfile USER. If it's not set, then root.
544	#[serde(skip_serializing_if = "Option::is_none")]
545	pub user: Option<String>,
546
547	/// Sets the user namespace for the service. Supported values are platform specific and may depend on platform configuration.
548	#[serde(skip_serializing_if = "Option::is_none")]
549	pub userns_mode: Option<String>,
550
551	/// /// Configures the UTS namespace mode set for the service container. When unspecified it is the runtime's decision to assign a UTS namespace, if supported.
552	#[serde(skip_serializing_if = "Option::is_none")]
553	pub uts: Option<Uts>,
554
555	/// The volumes attribute define mount host paths or named volumes that are accessible by service containers.
556	///
557	/// See more: https://docs.docker.com/reference/compose-file/services/#volumes
558	#[serde(default, skip_serializing_if = "Vec::is_empty")]
559	pub volumes: Vec<ServiceVolume>,
560
561	/// Mounts all of the volumes from another service or container. You can optionally specify read-only access ro or read-write rw. If no access level is specified, then read-write access is used.
562	///
563	/// You can also mount volumes from a container that is not managed by Compose by using the container: prefix.
564	#[serde(default, skip_serializing_if = "Vec::is_empty")]
565	pub volumes_from: Vec<String>,
566
567	/// Overrides the container's working directory which is specified by the image, for example Dockerfile's WORKDIR.
568	#[serde(skip_serializing_if = "Option::is_none")]
569	pub working_dir: Option<String>,
570}
571
572/// `extends` lets you share common configurations among different files, or even different projects entirely.
573///
574/// See more: https://docs.docker.com/reference/compose-file/services/#extends
575#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
576#[cfg_attr(feature = "schemars", derive(JsonSchema))]
577#[serde(untagged)]
578pub enum Extends {
579	/// The name of the service to extend.
580	Simple(String),
581	Detailed {
582		/// The name of the service to extend.
583		service: String,
584
585		/// The file path where the service to extend is defined.
586		#[serde(default)]
587		file: Option<String>,
588	},
589}
590
591/// Requires: Docker Compose 2.30.0 and later
592///
593/// Specifies GPU devices to be allocated for container usage.
594#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
595#[cfg_attr(feature = "schemars", derive(JsonSchema))]
596pub enum Gpus {
597	/// Use all available GPUs.
598	#[serde(rename = "all")]
599	All,
600	/// List of specific GPU devices to use.
601	#[serde(untagged)]
602	List(BTreeSet<GpuSettings>),
603}
604
605impl Merge for Gpus {
606	fn merge(&mut self, other: Self) {
607		match self {
608			Self::All => {}
609			Self::List(left_gpus) => match other {
610				Self::All => *self = Self::All,
611				Self::List(right_gpus) => left_gpus.extend(right_gpus),
612			},
613		}
614	}
615}
616
617/// Requires: Docker Compose 2.30.0 and later
618///
619/// Specifies GPU devices to be allocated for container usage.
620#[derive(Clone, Debug, Serialize, Default, Deserialize, PartialEq, Eq)]
621#[cfg_attr(feature = "schemars", derive(JsonSchema))]
622#[serde(default)]
623#[serde(deny_unknown_fields)]
624pub struct GpuSettings {
625	/// List of capabilities the GPU needs to have (e.g., 'compute', 'utility').
626	#[serde(skip_serializing_if = "Option::is_none")]
627	pub capabilities: Option<BTreeSet<String>>,
628
629	// Number of GPUs to use.
630	#[serde(skip_serializing_if = "Option::is_none")]
631	pub count: Option<usize>,
632
633	/// List of specific GPU device IDs to use.
634	#[serde(skip_serializing_if = "Option::is_none")]
635	pub device_ids: Option<BTreeSet<String>>,
636
637	/// GPU driver to use (e.g., 'nvidia').
638	#[serde(skip_serializing_if = "Option::is_none")]
639	pub driver: Option<String>,
640
641	/// Driver-specific options for the GPU.
642	#[serde(skip_serializing_if = "Option::is_none")]
643	pub options: Option<ListOrMap>,
644}
645
646impl PartialOrd for GpuSettings {
647	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
648		Some(self.cmp(other))
649	}
650}
651
652impl Ord for GpuSettings {
653	fn cmp(&self, other: &Self) -> Ordering {
654		self.driver
655			.cmp(&other.driver)
656			.then_with(|| self.count.cmp(&other.count))
657	}
658}
659
660/// Requires: Docker Compose 2.38.0 and later
661///
662/// Defines which AI models the service should use at runtime. Each referenced model must be defined under the [`models` top-level element](https://docs.docker.com/reference/compose-file/models/).
663///
664/// See more: https://docs.docker.com/reference/compose-file/services/#models
665#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
666#[cfg_attr(feature = "schemars", derive(JsonSchema))]
667#[serde(untagged)]
668pub enum ServiceModels {
669	List(BTreeSet<String>),
670	Map(BTreeMap<String, ServiceModelSettings>),
671}
672
673impl Merge for ServiceModels {
674	fn merge(&mut self, other: Self) {
675		if let Self::List(left_list) = self
676			&& let Self::List(right_list) = other
677		{
678			left_list.extend(right_list);
679		} else if let Self::Map(left_list) = self
680			&& let Self::Map(right_list) = other
681		{
682			left_list.extend(right_list);
683		} else {
684			*self = other;
685		}
686	}
687}
688
689#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Default)]
690#[cfg_attr(feature = "schemars", derive(JsonSchema))]
691#[serde(default)]
692#[serde(deny_unknown_fields)]
693pub struct ServiceModelSettings {
694	/// Environment variable set to AI model name.
695	#[serde(skip_serializing_if = "Option::is_none")]
696	pub model_var: Option<String>,
697
698	/// Environment variable set to AI model endpoint.
699	#[serde(skip_serializing_if = "Option::is_none")]
700	pub endpoint_var: Option<String>,
701}
702
703impl PartialOrd for ServiceModelSettings {
704	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
705		Some(self.cmp(other))
706	}
707}
708
709impl Ord for ServiceModelSettings {
710	fn cmp(&self, other: &Self) -> Ordering {
711		self.model_var.cmp(&other.model_var)
712	}
713}
714
715/// Sets a service container's network mode.
716///
717///
718/// See more: https://docs.docker.com/reference/compose-file/services/#network_mode
719#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
720#[cfg_attr(feature = "schemars", derive(JsonSchema))]
721pub enum NetworkMode {
722	Bridge,
723	/// Gives the container raw access to the host's network interface.
724	Host,
725	/// Turns off all container networking.
726	None,
727	#[serde(untagged)]
728	Other(String),
729}
730
731#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
732#[cfg_attr(feature = "schemars", derive(JsonSchema))]
733#[serde(untagged)]
734pub enum ServiceNetworks {
735	List(BTreeSet<String>),
736	Map(BTreeMap<String, ServiceNetworkSettings>),
737}
738
739impl ServiceNetworks {
740	pub fn contains(&self, key: &str) -> bool {
741		match self {
742			Self::List(list) => list.contains(key),
743			Self::Map(map) => map.contains_key(key),
744		}
745	}
746}
747
748impl Merge for ServiceNetworks {
749	fn merge(&mut self, other: Self) {
750		if let Self::List(left_list) = self
751			&& let Self::List(right_list) = other
752		{
753			left_list.extend(right_list);
754		} else if let Self::Map(left_list) = self
755			&& let Self::Map(right_list) = other
756		{
757			left_list.extend(right_list);
758		} else {
759			*self = other;
760		}
761	}
762}
763
764/// The networks attribute defines the networks that service containers are attached to, referencing entries under the networks top-level element.
765///
766/// See more: https://docs.docker.com/reference/compose-file/services/#networks
767#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
768#[cfg_attr(feature = "schemars", derive(JsonSchema))]
769#[serde(default)]
770#[serde(deny_unknown_fields)]
771pub struct ServiceNetworkSettings {
772	/// Interface network name used to connect to network
773	#[serde(skip_serializing_if = "Option::is_none")]
774	pub interface_name: Option<String>,
775
776	/// Alternative hostnames for this service on the network.
777	#[serde(skip_serializing_if = "Option::is_none")]
778	pub aliases: Option<BTreeSet<String>>,
779
780	/// Specify a static IPv4 address for this service on this network.
781	#[serde(skip_serializing_if = "Option::is_none")]
782	pub ipv4_address: Option<String>,
783
784	/// Specify a static IPv6 address for this service on this network.
785	#[serde(skip_serializing_if = "Option::is_none")]
786	pub ipv6_address: Option<String>,
787
788	/// Specify a MAC address for this service on this network.
789	#[serde(skip_serializing_if = "Option::is_none")]
790	pub mac_address: Option<String>,
791
792	/// Specify the priority for the network connection.
793	#[serde(skip_serializing_if = "Option::is_none")]
794	pub priority: Option<i64>,
795
796	/// Specify the gateway priority for the network connection.
797	#[serde(skip_serializing_if = "Option::is_none")]
798	pub gw_priority: Option<i64>,
799
800	/// List of link-local IPs.
801	#[serde(skip_serializing_if = "Option::is_none")]
802	pub link_local_ips: Option<BTreeSet<String>>,
803
804	/// Driver options for this network.
805	#[serde(skip_serializing_if = "Option::is_none")]
806	pub driver_opts: Option<BTreeMap<String, SingleValue>>,
807}
808
809#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
810#[cfg_attr(feature = "schemars", derive(JsonSchema))]
811#[serde(untagged)]
812pub enum ProviderOptions {
813	Single(SingleValue),
814	List(Vec<SingleValue>),
815}
816
817/// Defines a service that Compose won't manage directly. Compose delegated the service lifecycle to a dedicated or third-party component.
818///
819/// See more: https://docs.docker.com/reference/compose-file/services/#provider
820#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
821#[cfg_attr(feature = "schemars", derive(JsonSchema))]
822pub struct Provider {
823	/// External component used by Compose to manage setup and teardown lifecycle of the service.
824	#[serde(rename = "type")]
825	pub type_: String,
826
827	/// Provider-specific options.
828	#[serde(skip_serializing_if = "Option::is_none")]
829	#[serde(default)]
830	pub options: Option<BTreeMap<String, ProviderOptions>>,
831}
832
833#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
834#[cfg_attr(feature = "schemars", derive(JsonSchema))]
835#[serde(rename_all = "kebab-case")]
836pub enum Restart {
837	Always,
838	No,
839	OnFailure,
840	UnlessStopped,
841	#[serde(untagged)]
842	Other(String),
843}
844
845#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
846#[cfg_attr(feature = "schemars", derive(JsonSchema))]
847#[serde(untagged)]
848pub enum BuildStep {
849	/// Path to the build context. Can be a relative path or a URL.
850	Simple(String),
851	/// Configuration options for building the service's image.
852	Advanced(Box<AdvancedBuildStep>),
853}
854
855impl Merge for BuildStep {
856	fn merge(&mut self, other: Self) {
857		if let Self::Advanced(left_data) = self
858			&& let Self::Advanced(right_data) = other
859		{
860			left_data.merge(right_data);
861		} else {
862			*self = other;
863		}
864	}
865}
866
867/// Specifies the build configuration for creating a container image from source, as defined in the [Compose Build Specification](https://docs.docker.com/reference/compose-file/build/).
868#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq, Default, Merge)]
869#[cfg_attr(feature = "schemars", derive(JsonSchema))]
870#[serde(deny_unknown_fields)]
871#[serde(default)]
872pub struct AdvancedBuildStep {
873	/// Defines either a path to a directory containing a Dockerfile, or a URL to a Git repository.
874	///
875	/// When the value supplied is a relative path, it is interpreted as relative to the project directory. Compose warns you about the absolute path used to define the build context as those prevent the Compose file from being portable.
876	///
877	/// See more: https://docs.docker.com/reference/compose-file/build/#context
878	#[serde(skip_serializing_if = "Option::is_none")]
879	pub context: Option<String>,
880
881	/// Requires: Docker Compose 2.17.0 and later
882	///
883	/// Defines a list of named contexts the image builder should use during image build. Can be a mapping or a list.
884	/// See more: https://docs.docker.com/reference/compose-file/build/#additional_contexts
885	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
886	pub additional_contexts: ListOrMap,
887
888	/// Sets an alternate Dockerfile. A relative path is resolved from the build context. Compose warns you about the absolute path used to define the Dockerfile as it prevents Compose files from being portable.
889	///
890	/// When set, dockerfile_inline attribute is not allowed and Compose rejects any Compose file having both set.
891	#[serde(skip_serializing_if = "Option::is_none")]
892	pub dockerfile: Option<String>,
893
894	/// Requires: Docker Compose 2.17.0 and later
895	///
896	/// dockerfile_inline defines the Dockerfile content as an inlined string in a Compose file. When set, the dockerfile attribute is not allowed and Compose rejects any Compose file having both set.
897	#[serde(skip_serializing_if = "Option::is_none")]
898	pub dockerfile_inline: Option<String>,
899
900	/// Define build arguments, that is Dockerfile ARG values.
901	///
902	/// Cache location syntax follows the global format [NAME|type=TYPE[,KEY=VALUE]]. Simple NAME is actually a shortcut notation for type=registry,ref=NAME.
903	///
904	/// See more: https://docs.docker.com/reference/compose-file/build/#args
905	#[serde(skip_serializing_if = "Option::is_none")]
906	pub args: Option<ListOrMap>,
907
908	/// Defines a list of sources the image builder should use for cache resolution.
909	///
910	/// See more: https://docs.docker.com/reference/compose-file/build/#cache_from
911	#[serde(default, skip_serializing_if = "Vec::is_empty")]
912	pub cache_from: Vec<String>,
913
914	/// Defines a list of export locations to be used to share build cache with future builds.
915	///
916	/// Cache location syntax follows the global format [NAME|type=TYPE[,KEY=VALUE]]. Simple NAME is actually a shortcut notation for type=registry,ref=NAME.
917	///
918	/// See more: https://docs.docker.com/reference/compose-file/build/#cache_to
919	#[serde(default, skip_serializing_if = "Vec::is_empty")]
920	pub cache_to: Vec<String>,
921
922	/// Requires: Docker Compose 2.27.1 and later
923	///
924	/// Defines extra privileged entitlements to be allowed during the build.
925	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
926	pub entitlements: BTreeSet<String>,
927
928	/// Adds hostname mappings at build-time. Use the same syntax as [extra_hosts](https://docs.docker.com/reference/compose-file/services/#extra_hosts).
929	#[serde(skip_serializing_if = "Option::is_none")]
930	#[merge(with = merge_options)]
931	pub extra_hosts: Option<ExtraHosts>,
932
933	/// Specifies a build’s container isolation technology. Supported values are platform specific.
934	#[serde(skip_serializing_if = "Option::is_none")]
935	pub isolation: Option<String>,
936
937	/// Add metadata to the resulting image. Can be set either as an array or a map.
938	///
939	/// It's recommended that you use reverse-DNS notation to prevent your labels from conflicting with other software.
940	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
941	pub labels: ListOrMap,
942
943	/// Network mode to use for the build. Options include 'default', 'none', 'host', or a network name.
944	///
945	/// See more: https://docs.docker.com/reference/compose-file/build/#network
946	#[serde(skip_serializing_if = "Option::is_none")]
947	pub network: Option<String>,
948
949	/// Disables image builder cache and enforces a full rebuild from source for all image layers. This only applies to layers declared in the Dockerfile, referenced images can be retrieved from local image store whenever tag has been updated on registry (see [pull](https://docs.docker.com/reference/compose-file/build/#pull)).
950	#[serde(skip_serializing_if = "Option::is_none")]
951	pub no_cache: Option<bool>,
952
953	/// Defines a list of target [platforms](https://docs.docker.com/reference/compose-file/services/#platform).
954	///
955	/// See more: https://docs.docker.com/reference/compose-file/build/#platforms
956	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
957	pub platforms: BTreeSet<String>,
958
959	/// Requires: Docker Compose 2.15.0 and later
960	///
961	/// Configures the service image to build with elevated privileges. Support and actual impacts are platform specific.
962	#[serde(skip_serializing_if = "Option::is_none")]
963	pub privileged: Option<bool>,
964
965	/// Requires: Docker Compose 2.39.0 and later
966	///
967	/// Configures the builder to add a provenance attestation to the published image.
968	///
969	/// The value can be either a boolean to enable/disable provenance attestation, or a key=value string to set provenance configuration. You can use this to select the level of detail to be included in the provenance attestation by setting the mode parameter.
970	#[serde(skip_serializing_if = "Option::is_none")]
971	pub provenance: Option<bool>,
972
973	/// Requires the image builder to pull referenced images (FROM Dockerfile directive), even if those are already available in the local image store.
974	#[serde(skip_serializing_if = "Option::is_none")]
975	pub pull: Option<bool>,
976
977	/// Requires: Docker Compose 2.39.0 and later
978	///
979	/// Configures the builder to add a provenance attestation to the published image.
980	///
981	/// See more: https://docs.docker.com/reference/compose-file/build/#sbom
982	#[serde(skip_serializing_if = "Option::is_none")]
983	pub sbom: Option<bool>,
984
985	/// Grants access to sensitive data defined by secrets on a per-service build basis.
986	///
987	/// See more: https://docs.docker.com/reference/compose-file/build/#secrets
988	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
989	pub secrets: BTreeSet<ServiceConfigOrSecret>,
990
991	/// SSH agent socket or keys to expose to the build. Format is either a string or a list of 'default|<id>[=<socket>|<key>[,<key>]]'.
992	///
993	/// See more: https://docs.docker.com/reference/compose-file/build/#ssh
994	#[serde(default, skip_serializing_if = "ListOrMap::is_empty")]
995	pub ssh: ListOrMap,
996
997	/// Size of /dev/shm for the build container. A string value can use suffix like '2g' for 2 gigabytes.
998	///
999	/// See more: https://docs.docker.com/reference/compose-file/build/#shm_size
1000	#[serde(skip_serializing_if = "Option::is_none")]
1001	pub shm_size: Option<StringOrNum>,
1002
1003	/// Defines a list of tag mappings that must be associated to the build image. This list comes in addition to the image property defined in the service section.
1004	#[serde(default, skip_serializing_if = "BTreeSet::is_empty")]
1005	pub tags: BTreeSet<String>,
1006
1007	/// Defines the stage to build as defined inside a multi-stage Dockerfile.
1008	#[serde(skip_serializing_if = "Option::is_none")]
1009	pub target: Option<String>,
1010
1011	/// Requires: Docker Compose 2.23.1 and later
1012	///
1013	/// ulimits overrides the default ulimits for a container. It's specified either as an integer for a single limit or as mapping for soft/hard limits.
1014	///
1015	/// See more: https://docs.docker.com/reference/compose-file/build/#ulimits
1016	#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
1017	pub ulimits: BTreeMap<String, Ulimit>,
1018}
1019
1020/// Configures the UTS namespace mode set for the service container. When unspecified it is the runtime's decision to assign a UTS namespace, if supported.
1021#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
1022#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1023#[serde(rename = "kebab-case")]
1024pub enum Uts {
1025	/// Results in the container using the same UTS namespace as the host.
1026	Host,
1027}
1028
1029/// With the depends_on attribute, you can control the order of service startup and shutdown.
1030///
1031/// It is useful if services are closely coupled, and the startup sequence impacts the application's functionality.
1032///
1033/// See more: https://docs.docker.com/reference/compose-file/services/#depends_on
1034#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1035#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1036#[serde(untagged)]
1037pub enum DependsOn {
1038	Simple(Vec<String>),
1039
1040	Conditional(IndexMap<String, DependsOnSettings>),
1041}
1042
1043impl Merge for DependsOn {
1044	fn merge(&mut self, other: Self) {
1045		if let Self::Simple(left_list) = self
1046			&& let Self::Simple(right_list) = other
1047		{
1048			left_list.extend(right_list);
1049		} else if let Self::Conditional(left_list) = self
1050			&& let Self::Conditional(right_list) = other
1051		{
1052			left_list.extend(right_list);
1053		} else {
1054			*self = other;
1055		}
1056	}
1057}
1058
1059impl Default for DependsOn {
1060	fn default() -> Self {
1061		Self::Simple(Default::default())
1062	}
1063}
1064
1065impl DependsOn {
1066	pub fn is_empty(&self) -> bool {
1067		match self {
1068			Self::Simple(v) => v.is_empty(),
1069			Self::Conditional(m) => m.is_empty(),
1070		}
1071	}
1072}
1073
1074#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1075#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1076#[serde(rename_all = "snake_case")]
1077pub enum DependsOnCondition {
1078	/// Waits until the service has completed successfully.
1079	ServiceCompletedSuccessfully,
1080	/// Waits until the service is healthy (as defined by its healthcheck).
1081	ServiceHealthy,
1082	/// Waits until the service has started.
1083	ServiceStarted,
1084}
1085
1086/// With the depends_on attribute, you can control the order of service startup and shutdow```
1087///
1088/// It is useful if services are closely coupled, and the startup sequence impacts the application's functionality.
1089///
1090/// See more: https://docs.docker.com/reference/compose-file/services/#depends_on
1091#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1092#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1093#[serde(deny_unknown_fields)]
1094pub struct DependsOnSettings {
1095	/// Condition to wait for.
1096	pub condition: DependsOnCondition,
1097
1098	/// Whether to restart dependent services when this service is restarted.
1099	#[serde(skip_serializing_if = "Option::is_none")]
1100	#[serde(default)]
1101	pub restart: Option<bool>,
1102
1103	/// Whether the dependency is required for the dependent service to start. (default: true)
1104	#[serde(skip_serializing_if = "Option::is_none")]
1105	#[serde(default)]
1106	pub required: Option<bool>,
1107}
1108
1109/// Defines the logging configuration.
1110///
1111/// See more: https://docs.docker.com/engine/logging/configure/
1112#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
1113#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1114#[serde(default)]
1115#[serde(deny_unknown_fields)]
1116pub struct LoggingSettings {
1117	/// Logging driver to use, such as 'json-file', 'syslog', 'journald', etc.
1118	#[serde(skip_serializing_if = "Option::is_none")]
1119	pub driver: Option<LoggingDriver>,
1120
1121	/// Options for the logging driver.
1122	#[serde(skip_serializing_if = "Option::is_none")]
1123	pub options: Option<BTreeMap<String, Option<StringOrNum>>>,
1124}
1125
1126/// A logging driver for Docker.
1127#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1128#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1129#[serde(rename_all = "kebab-case")]
1130pub enum LoggingDriver {
1131	/// Logs are stored in a custom format designed for minimal overhead.
1132	Local,
1133	/// The logs are formatted as JSON. The default logging driver for Docker.
1134	JsonFile,
1135	/// Writes logging messages to the syslog facility. The syslog daemon must be running on the host machine.
1136	Syslog,
1137	/// Writes log messages to journald. The journald daemon must be running on the host machine.
1138	Journald,
1139	/// Writes log messages to a Graylog Extended Log Format (GELF) endpoint such as Graylog or Logstash.
1140	Gelf,
1141	/// Writes log messages to fluentd (forward input). The fluentd daemon must be running on the host machine.
1142	Fluentd,
1143	/// Writes log messages to Amazon CloudWatch Logs.
1144	Awslogs,
1145	/// Writes log messages to splunk using the HTTP Event Collector.
1146	Splunk,
1147	/// Writes log messages as Event Tracing for Windows (ETW) events. Only available on Windows platforms.
1148	Etwlogs,
1149	/// Writes log messages to Google Cloud Platform (GCP) Logging.
1150	Gcplogs,
1151}
1152
1153/// Declares a check that's run to determine whether or not the service containers are "healthy".
1154///
1155/// See more: https://docs.docker.com/reference/compose-file/services/#healthcheck
1156#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Default)]
1157#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1158#[serde(deny_unknown_fields)]
1159#[serde(default)]
1160pub struct Healthcheck {
1161	/// Disable any container-specified healthcheck. Set to true to disable.
1162	#[serde(skip_serializing_if = "Option::is_none")]
1163	pub disable: Option<bool>,
1164
1165	/// The test to perform to check container health. Can be a string or a list. The first item is either NONE, CMD, or CMD-SHELL. If it's CMD, the rest of the command is exec'd. If it's CMD-SHELL, the rest is run in the shell.
1166	#[serde(skip_serializing_if = "Option::is_none")]
1167	pub test: Option<StringOrList>,
1168
1169	/// Time between running the check (e.g., '1s', '1m30s'). Default: 30s.
1170	#[serde(skip_serializing_if = "Option::is_none")]
1171	pub interval: Option<String>,
1172
1173	/// Start period for the container to initialize before starting health-retries countdown (e.g., '1s', '1m30s'). Default: 0s.
1174	#[serde(skip_serializing_if = "Option::is_none")]
1175	pub start_period: Option<String>,
1176
1177	/// Time between running the check during the start period (e.g., '1s', '1m30s'). Default: interval value.
1178	#[serde(skip_serializing_if = "Option::is_none")]
1179	pub start_interval: Option<String>,
1180
1181	/// Number of consecutive failures needed to consider the container as unhealthy. Default: 3.
1182	#[serde(skip_serializing_if = "Option::is_none")]
1183	pub retries: Option<StringOrNum>,
1184
1185	/// Maximum time to allow one check to run (e.g., '1s', '1m30s'). Default: 30s.
1186	#[serde(skip_serializing_if = "Option::is_none")]
1187	pub timeout: Option<String>,
1188}
1189
1190/// Defines an environment file(s) to use to define default values when interpolating variables in the Compose file being parsed.
1191///
1192/// It defaults to .env file in the project_directory for the Compose file being parsed.
1193///
1194/// See more: https://docs.docker.com/reference/compose-file/include/#env_file
1195#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1196#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1197#[serde(untagged)]
1198pub enum Envfile {
1199	/// Path to a file containing environment variables.
1200	Simple(String),
1201	List(Vec<EnvfileFormat>),
1202}
1203
1204impl Merge for Envfile {
1205	fn merge(&mut self, other: Self) {
1206		match self {
1207			Self::Simple(_) => {
1208				*self = other;
1209			}
1210			Self::List(list) => match other {
1211				Self::Simple(file) => list.push(EnvfileFormat::Simple(file)),
1212				Self::List(files) => list.extend(files),
1213			},
1214		}
1215	}
1216}
1217
1218/// Defines an environment file(s) to use to define default values when interpolating variables in the Compose file being parsed.
1219///
1220/// It defaults to .env file in the project_directory for the Compose file being parsed.
1221///
1222/// See more: https://docs.docker.com/reference/compose-file/include/#env_file
1223#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1224#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1225#[serde(untagged)]
1226pub enum EnvfileFormat {
1227	/// Path to a file containing environment variables.
1228	Simple(String),
1229	/// Detailed configuration for an environment file.
1230	Detailed(EnvFileDetailed),
1231}
1232
1233/// Detailed configuration for an environment file.
1234#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1235#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1236#[serde(deny_unknown_fields)]
1237pub struct EnvFileDetailed {
1238	/// Path to the environment file.
1239	pub path: String,
1240
1241	/// Format attribute lets you to use an alternative file formats for env_file. When not set, env_file is parsed according to Compose rules.
1242	#[serde(skip_serializing_if = "Option::is_none")]
1243	#[serde(default)]
1244	pub format: Option<String>,
1245
1246	/// Whether the file is required. If true and the file doesn't exist, an error will be raised. (default: true)
1247	#[serde(skip_serializing_if = "Option::is_none")]
1248	#[serde(default)]
1249	pub required: Option<bool>,
1250}
1251
1252/// Defines a set of configuration options to set block I/O limits for a service.
1253///
1254/// See more: https://docs.docker.com/reference/compose-file/services/#blkio_config
1255#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
1256#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1257#[serde(default)]
1258#[serde(deny_unknown_fields)]
1259pub struct BlkioSettings {
1260	/// Limit read rate (bytes per second) from a device.
1261	#[serde(skip_serializing_if = "Option::is_none")]
1262	pub device_read_bps: Option<BTreeSet<BlkioLimit>>,
1263
1264	/// Limit read rate (IO per second) from a device.
1265	#[serde(skip_serializing_if = "Option::is_none")]
1266	pub device_read_iops: Option<BTreeSet<BlkioLimit>>,
1267
1268	/// Limit write rate (bytes per second) to a device.
1269	#[serde(skip_serializing_if = "Option::is_none")]
1270	pub device_write_bps: Option<BTreeSet<BlkioLimit>>,
1271
1272	/// Limit write rate (IO per second) to a device.
1273	#[serde(skip_serializing_if = "Option::is_none")]
1274	pub device_write_iops: Option<BTreeSet<BlkioLimit>>,
1275
1276	/// Block IO weight (relative weight) for the service, between 10 and 1000.
1277	#[serde(skip_serializing_if = "Option::is_none")]
1278	pub weight: Option<StringOrNum>,
1279
1280	/// Block IO weight (relative weight) for specific devices.
1281	#[serde(skip_serializing_if = "Option::is_none")]
1282	pub weight_device: Option<BTreeSet<BlkioWeight>>,
1283}
1284
1285/// Block IO limit for a specific device.
1286#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default, Eq)]
1287#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1288#[serde(default)]
1289#[serde(deny_unknown_fields)]
1290pub struct BlkioLimit {
1291	/// Path to the device (e.g., '/dev/sda').
1292	#[serde(skip_serializing_if = "Option::is_none")]
1293	pub path: Option<String>,
1294
1295	/// Rate limit in bytes per second or IO operations per second.
1296	#[serde(skip_serializing_if = "Option::is_none")]
1297	pub rate: Option<StringOrNum>,
1298}
1299
1300impl PartialOrd for BlkioLimit {
1301	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1302		Some(self.cmp(other))
1303	}
1304}
1305
1306impl Ord for BlkioLimit {
1307	fn cmp(&self, other: &Self) -> Ordering {
1308		self.path
1309			.cmp(&other.path)
1310			.then_with(|| self.rate.cmp(&other.rate))
1311	}
1312}
1313
1314/// Block IO weight for a specific device.
1315#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default, Eq)]
1316#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1317#[serde(default)]
1318#[serde(deny_unknown_fields)]
1319pub struct BlkioWeight {
1320	/// Path to the device (e.g., '/dev/sda').
1321	#[serde(skip_serializing_if = "Option::is_none")]
1322	pub path: Option<String>,
1323
1324	/// Relative weight for the device, between 10 and 1000.
1325	#[serde(skip_serializing_if = "Option::is_none")]
1326	pub weight: Option<StringOrNum>,
1327}
1328
1329impl PartialOrd for BlkioWeight {
1330	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1331		Some(self.cmp(other))
1332	}
1333}
1334
1335impl Ord for BlkioWeight {
1336	fn cmp(&self, other: &Self) -> Ordering {
1337		self.path
1338			.cmp(&other.path)
1339			.then_with(|| self.weight.cmp(&other.weight))
1340	}
1341}
1342
1343/// Specify the cgroup namespace to join. Use 'host' to use the host's cgroup namespace, or 'private' to use a private cgroup namespace.
1344#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1345#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1346#[serde(rename_all = "kebab-case")]
1347pub enum Cgroup {
1348	/// Use the host's cgroup namespace.
1349	Host,
1350
1351	/// Use a private cgroup namespace.
1352	Private,
1353}
1354
1355/// Configures the credential spec for a managed service account.
1356///
1357/// See more: https://docs.docker.com/reference/compose-file/services/#credential_spec
1358#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default, Eq)]
1359#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1360#[serde(default)]
1361#[serde(deny_unknown_fields)]
1362pub struct CredentialSpec {
1363	/// The name of the credential spec Config to use.
1364	#[serde(skip_serializing_if = "Option::is_none")]
1365	pub config: Option<String>,
1366
1367	/// Path to a credential spec file.
1368	#[serde(skip_serializing_if = "Option::is_none")]
1369	pub file: Option<String>,
1370
1371	/// Path to a credential spec in the Windows registry.
1372	#[serde(skip_serializing_if = "Option::is_none")]
1373	pub registry: Option<String>,
1374}
1375
1376/// Specifies the development configuration for maintaining a container in sync with source.
1377///
1378/// See more: https://docs.docker.com/reference/compose-file/develop
1379#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default, Eq)]
1380#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1381#[serde(deny_unknown_fields)]
1382pub struct DevelopmentSettings {
1383	/// The watch attribute defines a list of rules that control automatic service updates based on local file changes. watch is a sequence, each individual item in the sequence defines a rule to be applied by Compose to monitor source code for changes.
1384	#[serde(skip_serializing_if = "Option::is_none")]
1385	pub watch: Option<BTreeSet<WatchItem>>,
1386}
1387
1388impl Merge for DevelopmentSettings {
1389	fn merge(&mut self, other: Self) {
1390		merge_options(&mut self.watch, other.watch);
1391	}
1392}
1393
1394/// An element of the watch mode configuration.
1395///
1396/// See more: https://docs.docker.com/reference/compose-file/develop/#watch
1397#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1398#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1399#[serde(deny_unknown_fields)]
1400pub struct WatchItem {
1401	/// Action to take when a change is detected.
1402	///
1403	/// See more: https://docs.docker.com/reference/compose-file/develop/#action
1404	pub action: WatchAction,
1405
1406	/// Requires: Docker Compose 2.32.2 and later
1407	///
1408	/// Only relevant when action is set to sync+exec. Like service hooks, exec is used to define the command to be run inside the container once it has started.
1409	///
1410	/// See more: https://docs.docker.com/reference/compose-file/develop/#exec
1411	#[serde(skip_serializing_if = "Option::is_none")]
1412	#[serde(default)]
1413	pub exec: Option<ServiceHook>,
1414
1415	/// Patterns to exclude from watching.
1416	///
1417	/// See more: https://docs.docker.com/reference/compose-file/develop/#ignore
1418	#[serde(skip_serializing_if = "Option::is_none")]
1419	#[serde(default)]
1420	pub ignore: Option<BTreeSet<String>>,
1421
1422	/// It is sometimes easier to select files to be watched instead of declaring those that shouldn't be watched with ignore.
1423	///
1424	/// See more: https://docs.docker.com/reference/compose-file/develop/#include
1425	#[serde(skip_serializing_if = "Option::is_none")]
1426	#[serde(default)]
1427	pub include: Option<BTreeSet<String>>,
1428
1429	/// Defines the path to source code (relative to the project directory) to monitor for changes. Updates to any file inside the path, which doesn't match any ignore rule, triggers the configured action.
1430	pub path: String,
1431
1432	/// Only applies when action is configured for sync. Files within path that have changes are synchronized with the container's filesystem, so that the latter is always running with up-to-date content.
1433	#[serde(skip_serializing_if = "Option::is_none")]
1434	#[serde(default)]
1435	pub target: Option<String>,
1436}
1437
1438impl PartialOrd for WatchItem {
1439	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1440		Some(self.cmp(other))
1441	}
1442}
1443
1444impl Ord for WatchItem {
1445	fn cmp(&self, other: &Self) -> Ordering {
1446		self.action.cmp(&other.action)
1447	}
1448}
1449
1450/// Action to take when a change is detected.
1451///
1452/// See more: https://docs.docker.com/reference/compose-file/develop/#action
1453#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1454#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1455#[serde(rename_all = "kebab-case")]
1456pub enum WatchAction {
1457	Rebuild,
1458	Restart,
1459	Sync,
1460	#[serde(rename = "sync+restart")]
1461	SyncRestart,
1462	#[serde(rename = "sync+exec")]
1463	SyncExec,
1464}
1465
1466/// Configuration for service lifecycle hooks, which are commands executed at specific points in a container's lifecycle.
1467///
1468/// See more: https://docs.docker.com/compose/how-tos/lifecycle/
1469#[derive(Clone, Debug, Serialize, Default, Deserialize, PartialEq, Eq)]
1470#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1471#[serde(default)]
1472#[serde(deny_unknown_fields)]
1473pub struct ServiceHook {
1474	/// Whether to run the command with extended privileges.
1475	#[serde(skip_serializing_if = "Option::is_none")]
1476	pub privileged: Option<bool>,
1477
1478	/// User to run the command as.
1479	#[serde(skip_serializing_if = "Option::is_none")]
1480	pub user: Option<String>,
1481
1482	/// Working directory for the command.
1483	#[serde(skip_serializing_if = "Option::is_none")]
1484	pub working_dir: Option<String>,
1485
1486	/// Environment variables for the command.
1487	#[serde(skip_serializing_if = "Option::is_none")]
1488	pub environment: Option<ListOrMap>,
1489
1490	/// Command to execute as part of the hook.
1491	#[serde(skip_serializing_if = "Option::is_none")]
1492	pub command: Option<StringOrList>,
1493}
1494
1495/// A device mapping for a container.
1496#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1497#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1498#[serde(untagged)]
1499pub enum DeviceMapping {
1500	String(String),
1501	Detailed(DeviceMappingSettings),
1502}
1503
1504/// A device mapping for a container.
1505#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1506#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1507#[serde(deny_unknown_fields)]
1508pub struct DeviceMappingSettings {
1509	/// Path on the host to the device.
1510	pub source: String,
1511
1512	/// Path in the container where the device will be mapped.
1513	#[serde(skip_serializing_if = "Option::is_none")]
1514	#[serde(default)]
1515	pub target: Option<String>,
1516
1517	/// Cgroup permissions for the device (rwm).
1518	#[serde(skip_serializing_if = "Option::is_none")]
1519	#[serde(default)]
1520	pub permissions: Option<String>,
1521}
1522
1523impl PartialOrd for DeviceMappingSettings {
1524	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1525		Some(self.cmp(other))
1526	}
1527}
1528
1529impl Ord for DeviceMappingSettings {
1530	fn cmp(&self, other: &Self) -> Ordering {
1531		self.source.cmp(&other.source)
1532	}
1533}
1534
1535#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1536#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1537#[serde(untagged)]
1538pub enum ServiceVolume {
1539	Simple(String),
1540	Advanced(ServiceVolumeSettings),
1541}
1542
1543impl PartialOrd for ServiceVolume {
1544	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1545		Some(self.cmp(other))
1546	}
1547}
1548
1549impl Ord for ServiceVolume {
1550	fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1551		match self {
1552			Self::Simple(s) => match other {
1553				Self::Simple(other_s) => s.cmp(other_s),
1554				Self::Advanced(_) => Ordering::Greater,
1555			},
1556			Self::Advanced(v) => match other {
1557				Self::Simple(_) => Ordering::Less,
1558				Self::Advanced(other_v) => v.type_.cmp(&other_v.type_),
1559			},
1560		}
1561	}
1562}
1563
1564/// The mount type.
1565#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
1566#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1567#[serde(rename_all = "lowercase")]
1568pub enum VolumeType {
1569	/// For mounting host directories.
1570	Bind,
1571
1572	/// For cluster volumes.
1573	Cluster,
1574
1575	/// For named pipes.
1576	Npipe,
1577
1578	/// For mounting from an image.
1579	Image,
1580
1581	/// For temporary filesystems.
1582	Tmpfs,
1583
1584	/// For names volumes.
1585	Volume,
1586}
1587
1588/// Configuration for a service volume.
1589///
1590/// See more: https://docs.docker.com/reference/compose-file/services/#long-syntax-6
1591#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1592#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1593#[serde(deny_unknown_fields)]
1594pub struct ServiceVolumeSettings {
1595	/// The mount type.
1596	#[serde(rename = "type")]
1597	pub type_: VolumeType,
1598
1599	/// Flag to set the volume as read-only.
1600	#[serde(skip_serializing_if = "Option::is_none")]
1601	#[serde(default)]
1602	pub read_only: Option<bool>,
1603
1604	/// The source of the mount, a path on the host for a bind mount, a docker image reference for an image mount, or the name of a volume defined in the top-level volumes key. Not applicable for a tmpfs mount.
1605	#[serde(skip_serializing_if = "Option::is_none")]
1606	#[serde(default)]
1607	pub source: Option<String>,
1608
1609	/// The path in the container where the volume is mounted.
1610	pub target: String,
1611
1612	/// The consistency requirements for the mount. Available values are platform specific.
1613	#[serde(skip_serializing_if = "Option::is_none")]
1614	#[serde(default)]
1615	pub consistency: Option<String>,
1616
1617	/// Configuration specific to bind mounts.
1618	#[serde(skip_serializing_if = "Option::is_none")]
1619	#[serde(default)]
1620	pub bind: Option<Bind>,
1621
1622	/// Configuration specific to image mounts.
1623	#[serde(skip_serializing_if = "Option::is_none")]
1624	#[serde(default)]
1625	pub image: Option<ImageVolumeSettings>,
1626
1627	/// /// Configuration specific to tmpfs mounts.
1628	#[serde(skip_serializing_if = "Option::is_none")]
1629	#[serde(default)]
1630	pub tmpfs: Option<TmpfsSettings>,
1631
1632	/// Configuration specific to volume mounts.
1633	#[serde(skip_serializing_if = "Option::is_none")]
1634	#[serde(default)]
1635	pub volume: Option<VolumeSettings>,
1636}
1637
1638/// The propagation mode for the bind mount
1639#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1640#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1641#[serde(rename_all = "lowercase")]
1642pub enum Propagation {
1643	Private,
1644	Rprivate,
1645	Rshared,
1646	Rslave,
1647	Shared,
1648	Slave,
1649}
1650
1651/// Recursively mount the source directory.
1652#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1653#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1654#[serde(rename_all = "lowercase")]
1655pub enum Recursive {
1656	Disabled,
1657	Enabled,
1658	Readonly,
1659	Writable,
1660}
1661
1662#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1663#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1664pub enum SELinux {
1665	/// For shared content.
1666	#[serde(rename = "z")]
1667	Shared,
1668
1669	/// For private, unshared content.
1670	#[serde(rename = "Z")]
1671	Unshared,
1672}
1673
1674/// Configuration specific to bind mounts.
1675#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Default)]
1676#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1677#[serde(deny_unknown_fields)]
1678#[serde(default)]
1679pub struct Bind {
1680	/// Create the host path if it doesn't exist.
1681	#[serde(skip_serializing_if = "Option::is_none")]
1682	pub create_host_path: Option<bool>,
1683
1684	/// The propagation mode for the bind mount:
1685	#[serde(skip_serializing_if = "Option::is_none")]
1686	pub propagation: Option<Propagation>,
1687
1688	/// Recursively mount the source directory.
1689	#[serde(skip_serializing_if = "Option::is_none")]
1690	pub recursive: Option<Recursive>,
1691
1692	/// SELinux relabeling options: 'z' for shared content, 'Z' for private unshared content.
1693	#[serde(skip_serializing_if = "Option::is_none")]
1694	pub selinux: Option<SELinux>,
1695}
1696
1697/// Configuration specific to volume mounts.
1698#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Default)]
1699#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1700#[serde(deny_unknown_fields)]
1701#[serde(default)]
1702pub struct VolumeSettings {
1703	/// Labels to apply to the volume.
1704	#[serde(skip_serializing_if = "Option::is_none")]
1705	pub labels: Option<ListOrMap>,
1706
1707	/// Flag to disable copying of data from a container when a volume is created.
1708	#[serde(skip_serializing_if = "Option::is_none")]
1709	pub nocopy: Option<bool>,
1710
1711	/// Path within the volume to mount instead of the volume root.
1712	#[serde(skip_serializing_if = "Option::is_none")]
1713	pub subpath: Option<String>,
1714}
1715
1716#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq, Default)]
1717#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1718#[serde(deny_unknown_fields)]
1719pub struct ImageVolumeSettings {
1720	/// Path within the image to mount instead of the image root.
1721	#[serde(skip_serializing_if = "Option::is_none")]
1722	pub subpath: Option<String>,
1723}
1724
1725/// Configuration specific to tmpfs mounts.
1726#[derive(Clone, Debug, Serialize, Default, Deserialize, Eq, PartialEq)]
1727#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1728#[serde(deny_unknown_fields)]
1729#[serde(default)]
1730pub struct TmpfsSettings {
1731	/// File mode of the tmpfs in octal.
1732	#[serde(skip_serializing_if = "Option::is_none")]
1733	pub mode: Option<StringOrNum>,
1734
1735	/// Size of the tmpfs mount in bytes.
1736	#[serde(skip_serializing_if = "Option::is_none")]
1737	pub size: Option<StringOrNum>,
1738}
1739
1740#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
1741#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1742#[serde(rename_all = "lowercase")]
1743pub enum PortMode {
1744	Host,
1745	Ingress,
1746}
1747
1748#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
1749#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1750#[serde(rename_all = "lowercase")]
1751pub enum Protocol {
1752	Tcp,
1753	Udp,
1754}
1755
1756#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
1757#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1758#[serde(untagged)]
1759pub enum Port {
1760	Num(u64),
1761	String(String),
1762	Data(PortSettings),
1763}
1764
1765/// Settings for a port mapping.
1766///
1767/// See more: https://docs.docker.com/reference/compose-file/services/#long-syntax-4
1768#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Default)]
1769#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1770#[serde(default)]
1771#[serde(deny_unknown_fields)]
1772pub struct PortSettings {
1773	/// A human-readable name for this port mapping.
1774	#[serde(skip_serializing_if = "Option::is_none")]
1775	pub name: Option<String>,
1776
1777	/// The host IP to bind to.
1778	#[serde(skip_serializing_if = "Option::is_none")]
1779	pub host_ip: Option<String>,
1780
1781	/// The port inside the container.
1782	#[serde(skip_serializing_if = "Option::is_none")]
1783	pub target: Option<StringOrNum>,
1784
1785	/// The publicly exposed port.
1786	#[serde(skip_serializing_if = "Option::is_none")]
1787	pub published: Option<StringOrNum>,
1788
1789	/// The port binding mode, either 'host' for publishing a host port or 'ingress' for load balancing.
1790	#[serde(skip_serializing_if = "Option::is_none")]
1791	pub mode: Option<PortMode>,
1792
1793	/// The port protocol (tcp or udp).
1794	#[serde(skip_serializing_if = "Option::is_none")]
1795	pub protocol: Option<Protocol>,
1796
1797	/// The application protocol (TCP/IP level 4 / OSI level 7) this port is used for. This is optional and can be used as a hint for Compose to offer richer behavior for protocols that it understands.
1798	#[serde(skip_serializing_if = "Option::is_none")]
1799	pub app_protocol: Option<String>,
1800}
1801
1802/// Defines the decisions Compose makes when it starts to pull images.
1803///
1804/// See more: https://docs.docker.com/reference/compose-file/services/#pull_policy
1805#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
1806#[cfg_attr(feature = "schemars", derive(JsonSchema))]
1807#[serde(rename_all = "lowercase")]
1808pub enum PullPolicy {
1809	/// Compose always pulls the image from the registry.
1810	Always,
1811	/// Compose builds the image. Compose rebuilds the image if it's already present.
1812	Build,
1813	/// Compose checks the registry for image updates if the last pull took place more than 24 hours ago.
1814	Daily,
1815	/// Compose pulls the image only if it's not available in the platform cache. This is the default option if you are not also using the [Compose Build Specification](https://docs.docker.com/reference/compose-file/build/). if_not_present is considered an alias for this value for backward compatibility. The latest tag is always pulled even when the missing pull policy is used.
1816	#[serde(alias = "if_not_present")]
1817	Missing,
1818	/// Compose doesn't pull the image from a registry and relies on the platform cached image. If there is no cached image, a failure is reported.
1819	Never,
1820	Refresh,
1821	/// Compose checks the registry for image updates if the last pull took place more than 7 days ago.
1822	Weekly,
1823	#[serde(untagged)]
1824	Other(String),
1825}