0
# Swarm Management
1
2
Docker Swarm operations for container orchestration including nodes, services, secrets, and configs. Docker Swarm provides native clustering and orchestration capabilities for Docker containers across multiple hosts.
3
4
## Capabilities
5
6
### Swarm Initialization and Management
7
8
Initialize, manage, and configure Docker Swarm clusters.
9
10
```python { .api }
11
def init(
12
*,
13
advertise_addr: Optional[str] = None,
14
listen_addr: str = "0.0.0.0:2377",
15
force_new_cluster: bool = False,
16
cert_expiry: str = "2160h0m0s",
17
dispatcher_heartbeat: str = "5s",
18
task_history_limit: int = 5,
19
snapshot_interval: int = 10000,
20
log_entries_for_slow_followers: int = 500,
21
election_tick: int = 10,
22
heartbeat_tick: int = 1,
23
max_snapshots: int = 0,
24
snapshot_keep_old_snapshots: int = 0,
25
data_path_addr: Optional[str] = None,
26
data_path_port: Optional[int] = None,
27
default_addr_pool: Optional[List[str]] = None,
28
default_addr_pool_mask_length: Optional[int] = None,
29
external_ca: Optional[List[str]] = None,
30
autolock: bool = False
31
) -> str:
32
"""
33
Initialize a new swarm cluster.
34
35
Parameters:
36
- advertise_addr: Advertised address (format: <ip|interface>[:port])
37
- listen_addr: Listen address (format: <ip|interface>[:port])
38
- force_new_cluster: Force create new cluster from current state
39
- cert_expiry: Validity period for node certificates
40
- dispatcher_heartbeat: Dispatcher heartbeat period
41
- task_history_limit: Task history retention limit
42
- snapshot_interval: Number of log entries between snapshots
43
- log_entries_for_slow_followers: Number of log entries to keep for slow followers
44
- election_tick: Number of ticks between elections
45
- heartbeat_tick: Number of ticks between heartbeats
46
- max_snapshots: Number of additional snapshots to retain
47
- snapshot_keep_old_snapshots: Number of old snapshots to preserve
48
- data_path_addr: Address or interface to use for data path traffic
49
- data_path_port: Port number to use for data path traffic
50
- default_addr_pool: Default address pool in CIDR format
51
- default_addr_pool_mask_length: Default address pool subnet mask length
52
- external_ca: Specifications of one or more certificate signing endpoints
53
- autolock: Enable manager autolocking
54
55
Returns:
56
- Swarm initialization result
57
"""
58
59
def join(
60
token: str,
61
manager_addr: str,
62
*,
63
listen_addr: str = "0.0.0.0:2377",
64
advertise_addr: Optional[str] = None,
65
data_path_addr: Optional[str] = None
66
) -> None:
67
"""
68
Join an existing swarm as a node.
69
70
Parameters:
71
- token: Token for joining swarm
72
- manager_addr: Address of manager node
73
- listen_addr: Listen address for swarm traffic
74
- advertise_addr: Advertised address
75
- data_path_addr: Address for data path traffic
76
"""
77
78
def leave(force: bool = False) -> None:
79
"""
80
Leave the swarm.
81
82
Parameters:
83
- force: Force leave swarm (use on manager nodes)
84
"""
85
86
def update(
87
*,
88
cert_expiry: Optional[str] = None,
89
dispatcher_heartbeat: Optional[str] = None,
90
task_history_limit: Optional[int] = None,
91
snapshot_interval: Optional[int] = None,
92
log_entries_for_slow_followers: Optional[int] = None,
93
election_tick: Optional[int] = None,
94
heartbeat_tick: Optional[int] = None,
95
max_snapshots: Optional[int] = None,
96
snapshot_keep_old_snapshots: Optional[int] = None,
97
autolock: Optional[bool] = None
98
) -> None:
99
"""
100
Update swarm configuration.
101
102
Parameters: Same as init() but all optional for updating existing settings
103
"""
104
```
105
106
### Token Management
107
108
Manage join tokens for worker and manager nodes.
109
110
```python { .api }
111
def join_token(
112
role: str,
113
*,
114
rotate: bool = False,
115
quiet: bool = False
116
) -> str:
117
"""
118
Manage join tokens for swarm.
119
120
Parameters:
121
- role: Node role (worker, manager)
122
- rotate: Rotate the join token
123
- quiet: Only display token
124
125
Returns:
126
- Join token string
127
"""
128
```
129
130
### Swarm Security
131
132
Manage swarm encryption and security features.
133
134
```python { .api }
135
def unlock() -> None:
136
"""
137
Unlock swarm with unlock key.
138
"""
139
140
def unlock_key(
141
*,
142
rotate: bool = False,
143
quiet: bool = False
144
) -> str:
145
"""
146
Manage unlock key for locked swarm.
147
148
Parameters:
149
- rotate: Rotate unlock key
150
- quiet: Only display key
151
152
Returns:
153
- Unlock key string
154
"""
155
```
156
157
### Node Management
158
159
Manage swarm nodes including promotion, demotion, and removal.
160
161
```python { .api }
162
class NodeCLI:
163
def demote(self, nodes: Union[str, List[str]]) -> None:
164
"""
165
Demote manager nodes to worker nodes.
166
167
Parameters:
168
- nodes: Node ID(s) or name(s) to demote
169
"""
170
171
def inspect(self, nodes: Union[str, List[str]]) -> List[Node]:
172
"""
173
Get detailed information about nodes.
174
175
Parameters:
176
- nodes: Node ID(s) or name(s) to inspect
177
178
Returns:
179
- List of Node objects with full details
180
"""
181
182
def list(
183
self,
184
*,
185
filters: Optional[Dict[str, str]] = None,
186
quiet: bool = False,
187
format: Optional[str] = None
188
) -> List[Node]:
189
"""
190
List swarm nodes.
191
192
Parameters:
193
- filters: Filters to apply (id, label, membership, name, role)
194
- quiet: Only show node IDs
195
- format: Output format
196
197
Returns:
198
- List of Node objects
199
"""
200
201
def promote(self, nodes: Union[str, List[str]]) -> None:
202
"""
203
Promote worker nodes to manager nodes.
204
205
Parameters:
206
- nodes: Node ID(s) or name(s) to promote
207
"""
208
209
def remove(
210
self,
211
nodes: Union[str, List[str]],
212
*,
213
force: bool = False
214
) -> None:
215
"""
216
Remove nodes from swarm.
217
218
Parameters:
219
- nodes: Node ID(s) or name(s) to remove
220
- force: Force remove node from swarm
221
"""
222
223
def update(
224
self,
225
node: str,
226
*,
227
availability: Optional[str] = None,
228
labels_add: Optional[Dict[str, str]] = None,
229
labels_remove: Optional[List[str]] = None,
230
role: Optional[str] = None
231
) -> None:
232
"""
233
Update node configuration.
234
235
Parameters:
236
- node: Node ID or name
237
- availability: Node availability (active, pause, drain)
238
- labels_add: Labels to add
239
- labels_remove: Labels to remove
240
- role: Node role (worker, manager)
241
"""
242
```
243
244
### Service Management
245
246
Create and manage swarm services for container orchestration.
247
248
```python { .api }
249
class ServiceCLI:
250
def create(
251
self,
252
image: str,
253
*,
254
name: Optional[str] = None,
255
command: Optional[List[str]] = None,
256
replicas: Optional[int] = None,
257
mode: str = "replicated",
258
update_config: Optional[Dict[str, Any]] = None,
259
rollback_config: Optional[Dict[str, Any]] = None,
260
networks: Optional[List[str]] = None,
261
ports: Optional[List[str]] = None,
262
mounts: Optional[List[str]] = None,
263
secrets: Optional[List[str]] = None,
264
configs: Optional[List[str]] = None,
265
env: Optional[Dict[str, str]] = None,
266
labels: Optional[Dict[str, str]] = None,
267
constraints: Optional[List[str]] = None,
268
placement_prefs: Optional[List[str]] = None,
269
resources: Optional[Dict[str, Any]] = None,
270
restart_condition: Optional[str] = None,
271
restart_delay: Optional[str] = None,
272
restart_max_attempts: Optional[int] = None,
273
restart_window: Optional[str] = None,
274
stop_grace_period: Optional[str] = None,
275
health_cmd: Optional[str] = None,
276
health_interval: Optional[str] = None,
277
health_retries: Optional[int] = None,
278
health_start_period: Optional[str] = None,
279
health_timeout: Optional[str] = None,
280
hostname: Optional[str] = None,
281
isolation: Optional[str] = None,
282
limit_cpu: Optional[str] = None,
283
limit_memory: Optional[str] = None,
284
log_driver: Optional[str] = None,
285
log_opts: Optional[Dict[str, str]] = None,
286
reserve_cpu: Optional[str] = None,
287
reserve_memory: Optional[str] = None,
288
user: Optional[str] = None,
289
workdir: Optional[str] = None,
290
tty: bool = False,
291
replicas_max_per_node: Optional[int] = None,
292
stop_signal: Optional[str] = None,
293
read_only: bool = False
294
) -> Service:
295
"""
296
Create a new service.
297
298
Parameters:
299
- image: Service image
300
- name: Service name
301
- command: Command to run
302
- replicas: Number of replicas
303
- mode: Service mode (replicated, global)
304
- update_config: Update configuration
305
- rollback_config: Rollback configuration
306
- networks: Networks to attach
307
- ports: Port mappings
308
- mounts: Volume/bind mounts
309
- secrets: Secrets to attach
310
- configs: Configs to attach
311
- env: Environment variables
312
- labels: Service labels
313
- constraints: Placement constraints
314
- placement_prefs: Placement preferences
315
- resources: Resource requirements
316
- restart_condition: Restart condition (none, on-failure, any)
317
- restart_delay: Restart delay
318
- restart_max_attempts: Maximum restart attempts
319
- restart_window: Restart window
320
- stop_grace_period: Grace period before force kill
321
- health_cmd: Health check command
322
- health_interval: Health check interval
323
- health_retries: Health check retries
324
- health_start_period: Health check start period
325
- health_timeout: Health check timeout
326
- hostname: Container hostname
327
- isolation: Container isolation technology
328
- limit_cpu: CPU limit
329
- limit_memory: Memory limit
330
- log_driver: Logging driver
331
- log_opts: Logging driver options
332
- reserve_cpu: CPU reservation
333
- reserve_memory: Memory reservation
334
- user: User to run as
335
- workdir: Working directory
336
- tty: Allocate pseudo-TTY
337
- replicas_max_per_node: Maximum replicas per node
338
- stop_signal: Signal to stop container
339
- read_only: Mount root filesystem as read-only
340
341
Returns:
342
- Service object
343
"""
344
345
def update(
346
self,
347
service: str,
348
*,
349
image: Optional[str] = None,
350
command: Optional[List[str]] = None,
351
replicas: Optional[int] = None,
352
force: bool = False,
353
**kwargs
354
) -> None:
355
"""
356
Update service configuration.
357
358
Parameters:
359
- service: Service name or ID
360
- image: New service image
361
- command: New command
362
- replicas: New replica count
363
- force: Force update even if no changes
364
- **kwargs: Same options as create()
365
"""
366
367
def scale(self, services: Dict[str, int]) -> None:
368
"""
369
Scale services to specified replica counts.
370
371
Parameters:
372
- services: Dictionary mapping service names to replica counts
373
"""
374
375
def rollback(self, service: str) -> None:
376
"""
377
Rollback service to previous version.
378
379
Parameters:
380
- service: Service name or ID
381
"""
382
```
383
384
## Usage Examples
385
386
### Swarm Cluster Setup
387
388
```python
389
from python_on_whales import docker
390
391
# Initialize swarm on manager node
392
init_result = docker.swarm.init(
393
advertise_addr="192.168.1.10:2377",
394
listen_addr="0.0.0.0:2377"
395
)
396
print(f"Swarm initialized: {init_result}")
397
398
# Get join tokens
399
worker_token = docker.swarm.join_token("worker", quiet=True)
400
manager_token = docker.swarm.join_token("manager", quiet=True)
401
402
print(f"Worker join token: {worker_token}")
403
print(f"Manager join token: {manager_token}")
404
405
# On worker nodes, join the swarm
406
# docker.swarm.join(worker_token, "192.168.1.10:2377")
407
```
408
409
### Service Deployment
410
411
```python
412
# Create a web service
413
web_service = docker.service.create(
414
"nginx:alpine",
415
name="web",
416
replicas=3,
417
ports=["80:80"],
418
labels={"service": "web"},
419
update_config={
420
"parallelism": 1,
421
"delay": "10s"
422
},
423
restart_condition="on-failure"
424
)
425
426
# Scale the service
427
docker.service.scale({"web": 5})
428
429
# Update service with new image
430
docker.service.update(
431
"web",
432
image="nginx:1.21-alpine",
433
force=True
434
)
435
436
# List all services
437
services = docker.service.list()
438
for service in services:
439
print(f"Service: {service.name} - Replicas: {service.replicas}")
440
```
441
442
### Node Management
443
444
```python
445
# List all nodes
446
nodes = docker.node.list()
447
for node in nodes:
448
print(f"Node: {node.hostname} - Role: {node.role} - Status: {node.status}")
449
450
# Promote worker to manager
451
docker.node.promote("worker-node-1")
452
453
# Drain node for maintenance
454
docker.node.update(
455
"worker-node-2",
456
availability="drain"
457
)
458
459
# Add labels to node
460
docker.node.update(
461
"worker-node-2",
462
labels_add={"environment": "production", "zone": "us-west-1a"}
463
)
464
```
465
466
### High Availability Setup
467
468
```python
469
# Initialize swarm with advanced settings
470
docker.swarm.init(
471
advertise_addr="192.168.1.10:2377",
472
cert_expiry="8760h", # 1 year
473
task_history_limit=10,
474
autolock=True # Enable autolock for security
475
)
476
477
# Get unlock key for secure cluster
478
unlock_key = docker.swarm.unlock_key(quiet=True)
479
print(f"Store this unlock key securely: {unlock_key}")
480
481
# Create production service with placement constraints
482
prod_service = docker.service.create(
483
"myapp:production",
484
name="production-api",
485
replicas=5,
486
constraints=["node.labels.environment==production"],
487
placement_prefs=["spread=node.labels.zone"],
488
resources={
489
"limits": {"cpu": "1.0", "memory": "512M"},
490
"reservations": {"cpu": "0.5", "memory": "256M"}
491
},
492
update_config={
493
"parallelism": 2,
494
"delay": "30s",
495
"failure_action": "rollback",
496
"monitor": "60s"
497
},
498
rollback_config={
499
"parallelism": 1,
500
"delay": "30s",
501
"monitor": "60s"
502
}
503
)
504
```
505
506
## Types
507
508
```python { .api }
509
class Node:
510
id: str
511
version: Dict[str, Any]
512
created_at: str
513
updated_at: str
514
spec: Dict[str, Any]
515
description: Dict[str, Any]
516
status: Dict[str, Any]
517
manager_status: Optional[Dict[str, Any]]
518
519
hostname: str
520
role: str
521
availability: str
522
addr: str
523
engine_version: str
524
525
def demote(self) -> None: ...
526
def promote(self) -> None: ...
527
def remove(self, force: bool = False) -> None: ...
528
def update(self, **kwargs) -> None: ...
529
530
class Service:
531
id: str
532
version: Dict[str, Any]
533
created_at: str
534
updated_at: str
535
spec: Dict[str, Any]
536
endpoint: Dict[str, Any]
537
update_status: Optional[Dict[str, Any]]
538
539
name: str
540
image: str
541
replicas: int
542
mode: str
543
544
def remove(self) -> None: ...
545
def update(self, **kwargs) -> None: ...
546
def scale(self, replicas: int) -> None: ...
547
def rollback(self) -> None: ...
548
def logs(self, **kwargs) -> str: ...
549
def ps(self) -> List[Task]: ...
550
551
class Task:
552
id: str
553
version: Dict[str, Any]
554
created_at: str
555
updated_at: str
556
name: str
557
labels: Dict[str, str]
558
spec: Dict[str, Any]
559
service_id: str
560
slot: Optional[int]
561
node_id: str
562
assigned_generic_resources: List[Dict[str, Any]]
563
status: Dict[str, Any]
564
desired_state: str
565
```