Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

containers.py 45KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173
  1. import copy
  2. import ntpath
  3. from collections import namedtuple
  4. from ..api import APIClient
  5. from ..constants import DEFAULT_DATA_CHUNK_SIZE
  6. from ..errors import (
  7. ContainerError, DockerException, ImageNotFound,
  8. NotFound, create_unexpected_kwargs_error
  9. )
  10. from ..types import HostConfig
  11. from ..utils import version_gte
  12. from .images import Image
  13. from .resource import Collection, Model
  14. class Container(Model):
  15. """ Local representation of a container object. Detailed configuration may
  16. be accessed through the :py:attr:`attrs` attribute. Note that local
  17. attributes are cached; users may call :py:meth:`reload` to
  18. query the Docker daemon for the current properties, causing
  19. :py:attr:`attrs` to be refreshed.
  20. """
  21. @property
  22. def name(self):
  23. """
  24. The name of the container.
  25. """
  26. if self.attrs.get('Name') is not None:
  27. return self.attrs['Name'].lstrip('/')
  28. @property
  29. def image(self):
  30. """
  31. The image of the container.
  32. """
  33. image_id = self.attrs.get('ImageID', self.attrs['Image'])
  34. if image_id is None:
  35. return None
  36. return self.client.images.get(image_id.split(':')[1])
  37. @property
  38. def labels(self):
  39. """
  40. The labels of a container as dictionary.
  41. """
  42. try:
  43. result = self.attrs['Config'].get('Labels')
  44. return result or {}
  45. except KeyError:
  46. raise DockerException(
  47. 'Label data is not available for sparse objects. Call reload()'
  48. ' to retrieve all information'
  49. )
  50. @property
  51. def status(self):
  52. """
  53. The status of the container. For example, ``running``, or ``exited``.
  54. """
  55. if isinstance(self.attrs['State'], dict):
  56. return self.attrs['State']['Status']
  57. return self.attrs['State']
  58. @property
  59. def ports(self):
  60. """
  61. The ports that the container exposes as a dictionary.
  62. """
  63. return self.attrs.get('NetworkSettings', {}).get('Ports', {})
  64. def attach(self, **kwargs):
  65. """
  66. Attach to this container.
  67. :py:meth:`logs` is a wrapper around this method, which you can
  68. use instead if you want to fetch/stream container output without first
  69. retrieving the entire backlog.
  70. Args:
  71. stdout (bool): Include stdout.
  72. stderr (bool): Include stderr.
  73. stream (bool): Return container output progressively as an iterator
  74. of strings, rather than a single string.
  75. logs (bool): Include the container's previous output.
  76. Returns:
  77. By default, the container's output as a single string.
  78. If ``stream=True``, an iterator of output strings.
  79. Raises:
  80. :py:class:`docker.errors.APIError`
  81. If the server returns an error.
  82. """
  83. return self.client.api.attach(self.id, **kwargs)
  84. def attach_socket(self, **kwargs):
  85. """
  86. Like :py:meth:`attach`, but returns the underlying socket-like object
  87. for the HTTP request.
  88. Args:
  89. params (dict): Dictionary of request parameters (e.g. ``stdout``,
  90. ``stderr``, ``stream``).
  91. ws (bool): Use websockets instead of raw HTTP.
  92. Raises:
  93. :py:class:`docker.errors.APIError`
  94. If the server returns an error.
  95. """
  96. return self.client.api.attach_socket(self.id, **kwargs)
  97. def commit(self, repository=None, tag=None, **kwargs):
  98. """
  99. Commit a container to an image. Similar to the ``docker commit``
  100. command.
  101. Args:
  102. repository (str): The repository to push the image to
  103. tag (str): The tag to push
  104. message (str): A commit message
  105. author (str): The name of the author
  106. changes (str): Dockerfile instructions to apply while committing
  107. conf (dict): The configuration for the container. See the
  108. `Engine API documentation
  109. <https://docs.docker.com/reference/api/docker_remote_api/>`_
  110. for full details.
  111. Raises:
  112. :py:class:`docker.errors.APIError`
  113. If the server returns an error.
  114. """
  115. resp = self.client.api.commit(self.id, repository=repository, tag=tag,
  116. **kwargs)
  117. return self.client.images.get(resp['Id'])
  118. def diff(self):
  119. """
  120. Inspect changes on a container's filesystem.
  121. Returns:
  122. (list) A list of dictionaries containing the attributes `Path`
  123. and `Kind`.
  124. Raises:
  125. :py:class:`docker.errors.APIError`
  126. If the server returns an error.
  127. """
  128. return self.client.api.diff(self.id)
  129. def exec_run(self, cmd, stdout=True, stderr=True, stdin=False, tty=False,
  130. privileged=False, user='', detach=False, stream=False,
  131. socket=False, environment=None, workdir=None, demux=False):
  132. """
  133. Run a command inside this container. Similar to
  134. ``docker exec``.
  135. Args:
  136. cmd (str or list): Command to be executed
  137. stdout (bool): Attach to stdout. Default: ``True``
  138. stderr (bool): Attach to stderr. Default: ``True``
  139. stdin (bool): Attach to stdin. Default: ``False``
  140. tty (bool): Allocate a pseudo-TTY. Default: False
  141. privileged (bool): Run as privileged.
  142. user (str): User to execute command as. Default: root
  143. detach (bool): If true, detach from the exec command.
  144. Default: False
  145. stream (bool): Stream response data. Default: False
  146. socket (bool): Return the connection socket to allow custom
  147. read/write operations. Default: False
  148. environment (dict or list): A dictionary or a list of strings in
  149. the following format ``["PASSWORD=xxx"]`` or
  150. ``{"PASSWORD": "xxx"}``.
  151. workdir (str): Path to working directory for this exec session
  152. demux (bool): Return stdout and stderr separately
  153. Returns:
  154. (ExecResult): A tuple of (exit_code, output)
  155. exit_code: (int):
  156. Exit code for the executed command or ``None`` if
  157. either ``stream`` or ``socket`` is ``True``.
  158. output: (generator, bytes, or tuple):
  159. If ``stream=True``, a generator yielding response chunks.
  160. If ``socket=True``, a socket object for the connection.
  161. If ``demux=True``, a tuple of two bytes: stdout and stderr.
  162. A bytestring containing response data otherwise.
  163. Raises:
  164. :py:class:`docker.errors.APIError`
  165. If the server returns an error.
  166. """
  167. resp = self.client.api.exec_create(
  168. self.id, cmd, stdout=stdout, stderr=stderr, stdin=stdin, tty=tty,
  169. privileged=privileged, user=user, environment=environment,
  170. workdir=workdir,
  171. )
  172. exec_output = self.client.api.exec_start(
  173. resp['Id'], detach=detach, tty=tty, stream=stream, socket=socket,
  174. demux=demux
  175. )
  176. if socket or stream:
  177. return ExecResult(None, exec_output)
  178. return ExecResult(
  179. self.client.api.exec_inspect(resp['Id'])['ExitCode'],
  180. exec_output
  181. )
  182. def export(self, chunk_size=DEFAULT_DATA_CHUNK_SIZE):
  183. """
  184. Export the contents of the container's filesystem as a tar archive.
  185. Args:
  186. chunk_size (int): The number of bytes returned by each iteration
  187. of the generator. If ``None``, data will be streamed as it is
  188. received. Default: 2 MB
  189. Returns:
  190. (str): The filesystem tar archive
  191. Raises:
  192. :py:class:`docker.errors.APIError`
  193. If the server returns an error.
  194. """
  195. return self.client.api.export(self.id, chunk_size)
  196. def get_archive(self, path, chunk_size=DEFAULT_DATA_CHUNK_SIZE,
  197. encode_stream=False):
  198. """
  199. Retrieve a file or folder from the container in the form of a tar
  200. archive.
  201. Args:
  202. path (str): Path to the file or folder to retrieve
  203. chunk_size (int): The number of bytes returned by each iteration
  204. of the generator. If ``None``, data will be streamed as it is
  205. received. Default: 2 MB
  206. encode_stream (bool): Determines if data should be encoded
  207. (gzip-compressed) during transmission. Default: False
  208. Returns:
  209. (tuple): First element is a raw tar data stream. Second element is
  210. a dict containing ``stat`` information on the specified ``path``.
  211. Raises:
  212. :py:class:`docker.errors.APIError`
  213. If the server returns an error.
  214. Example:
  215. >>> f = open('./sh_bin.tar', 'wb')
  216. >>> bits, stat = container.get_archive('/bin/sh')
  217. >>> print(stat)
  218. {'name': 'sh', 'size': 1075464, 'mode': 493,
  219. 'mtime': '2018-10-01T15:37:48-07:00', 'linkTarget': ''}
  220. >>> for chunk in bits:
  221. ... f.write(chunk)
  222. >>> f.close()
  223. """
  224. return self.client.api.get_archive(self.id, path,
  225. chunk_size, encode_stream)
  226. def kill(self, signal=None):
  227. """
  228. Kill or send a signal to the container.
  229. Args:
  230. signal (str or int): The signal to send. Defaults to ``SIGKILL``
  231. Raises:
  232. :py:class:`docker.errors.APIError`
  233. If the server returns an error.
  234. """
  235. return self.client.api.kill(self.id, signal=signal)
  236. def logs(self, **kwargs):
  237. """
  238. Get logs from this container. Similar to the ``docker logs`` command.
  239. The ``stream`` parameter makes the ``logs`` function return a blocking
  240. generator you can iterate over to retrieve log output as it happens.
  241. Args:
  242. stdout (bool): Get ``STDOUT``. Default ``True``
  243. stderr (bool): Get ``STDERR``. Default ``True``
  244. stream (bool): Stream the response. Default ``False``
  245. timestamps (bool): Show timestamps. Default ``False``
  246. tail (str or int): Output specified number of lines at the end of
  247. logs. Either an integer of number of lines or the string
  248. ``all``. Default ``all``
  249. since (datetime, int, or float): Show logs since a given datetime,
  250. integer epoch (in seconds) or float (in nanoseconds)
  251. follow (bool): Follow log output. Default ``False``
  252. until (datetime, int, or float): Show logs that occurred before
  253. the given datetime, integer epoch (in seconds), or
  254. float (in nanoseconds)
  255. Returns:
  256. (generator or str): Logs from the container.
  257. Raises:
  258. :py:class:`docker.errors.APIError`
  259. If the server returns an error.
  260. """
  261. return self.client.api.logs(self.id, **kwargs)
  262. def pause(self):
  263. """
  264. Pauses all processes within this container.
  265. Raises:
  266. :py:class:`docker.errors.APIError`
  267. If the server returns an error.
  268. """
  269. return self.client.api.pause(self.id)
  270. def put_archive(self, path, data):
  271. """
  272. Insert a file or folder in this container using a tar archive as
  273. source.
  274. Args:
  275. path (str): Path inside the container where the file(s) will be
  276. extracted. Must exist.
  277. data (bytes or stream): tar data to be extracted
  278. Returns:
  279. (bool): True if the call succeeds.
  280. Raises:
  281. :py:class:`~docker.errors.APIError` If an error occurs.
  282. """
  283. return self.client.api.put_archive(self.id, path, data)
  284. def remove(self, **kwargs):
  285. """
  286. Remove this container. Similar to the ``docker rm`` command.
  287. Args:
  288. v (bool): Remove the volumes associated with the container
  289. link (bool): Remove the specified link and not the underlying
  290. container
  291. force (bool): Force the removal of a running container (uses
  292. ``SIGKILL``)
  293. Raises:
  294. :py:class:`docker.errors.APIError`
  295. If the server returns an error.
  296. """
  297. return self.client.api.remove_container(self.id, **kwargs)
  298. def rename(self, name):
  299. """
  300. Rename this container. Similar to the ``docker rename`` command.
  301. Args:
  302. name (str): New name for the container
  303. Raises:
  304. :py:class:`docker.errors.APIError`
  305. If the server returns an error.
  306. """
  307. return self.client.api.rename(self.id, name)
  308. def resize(self, height, width):
  309. """
  310. Resize the tty session.
  311. Args:
  312. height (int): Height of tty session
  313. width (int): Width of tty session
  314. Raises:
  315. :py:class:`docker.errors.APIError`
  316. If the server returns an error.
  317. """
  318. return self.client.api.resize(self.id, height, width)
  319. def restart(self, **kwargs):
  320. """
  321. Restart this container. Similar to the ``docker restart`` command.
  322. Args:
  323. timeout (int): Number of seconds to try to stop for before killing
  324. the container. Once killed it will then be restarted. Default
  325. is 10 seconds.
  326. Raises:
  327. :py:class:`docker.errors.APIError`
  328. If the server returns an error.
  329. """
  330. return self.client.api.restart(self.id, **kwargs)
  331. def start(self, **kwargs):
  332. """
  333. Start this container. Similar to the ``docker start`` command, but
  334. doesn't support attach options.
  335. Raises:
  336. :py:class:`docker.errors.APIError`
  337. If the server returns an error.
  338. """
  339. return self.client.api.start(self.id, **kwargs)
  340. def stats(self, **kwargs):
  341. """
  342. Stream statistics for this container. Similar to the
  343. ``docker stats`` command.
  344. Args:
  345. decode (bool): If set to true, stream will be decoded into dicts
  346. on the fly. Only applicable if ``stream`` is True.
  347. False by default.
  348. stream (bool): If set to false, only the current stats will be
  349. returned instead of a stream. True by default.
  350. Raises:
  351. :py:class:`docker.errors.APIError`
  352. If the server returns an error.
  353. """
  354. return self.client.api.stats(self.id, **kwargs)
  355. def stop(self, **kwargs):
  356. """
  357. Stops a container. Similar to the ``docker stop`` command.
  358. Args:
  359. timeout (int): Timeout in seconds to wait for the container to
  360. stop before sending a ``SIGKILL``. Default: 10
  361. Raises:
  362. :py:class:`docker.errors.APIError`
  363. If the server returns an error.
  364. """
  365. return self.client.api.stop(self.id, **kwargs)
  366. def top(self, **kwargs):
  367. """
  368. Display the running processes of the container.
  369. Args:
  370. ps_args (str): An optional arguments passed to ps (e.g. ``aux``)
  371. Returns:
  372. (str): The output of the top
  373. Raises:
  374. :py:class:`docker.errors.APIError`
  375. If the server returns an error.
  376. """
  377. return self.client.api.top(self.id, **kwargs)
  378. def unpause(self):
  379. """
  380. Unpause all processes within the container.
  381. Raises:
  382. :py:class:`docker.errors.APIError`
  383. If the server returns an error.
  384. """
  385. return self.client.api.unpause(self.id)
  386. def update(self, **kwargs):
  387. """
  388. Update resource configuration of the containers.
  389. Args:
  390. blkio_weight (int): Block IO (relative weight), between 10 and 1000
  391. cpu_period (int): Limit CPU CFS (Completely Fair Scheduler) period
  392. cpu_quota (int): Limit CPU CFS (Completely Fair Scheduler) quota
  393. cpu_shares (int): CPU shares (relative weight)
  394. cpuset_cpus (str): CPUs in which to allow execution
  395. cpuset_mems (str): MEMs in which to allow execution
  396. mem_limit (int or str): Memory limit
  397. mem_reservation (int or str): Memory soft limit
  398. memswap_limit (int or str): Total memory (memory + swap), -1 to
  399. disable swap
  400. kernel_memory (int or str): Kernel memory limit
  401. restart_policy (dict): Restart policy dictionary
  402. Returns:
  403. (dict): Dictionary containing a ``Warnings`` key.
  404. Raises:
  405. :py:class:`docker.errors.APIError`
  406. If the server returns an error.
  407. """
  408. return self.client.api.update_container(self.id, **kwargs)
  409. def wait(self, **kwargs):
  410. """
  411. Block until the container stops, then return its exit code. Similar to
  412. the ``docker wait`` command.
  413. Args:
  414. timeout (int): Request timeout
  415. condition (str): Wait until a container state reaches the given
  416. condition, either ``not-running`` (default), ``next-exit``,
  417. or ``removed``
  418. Returns:
  419. (dict): The API's response as a Python dictionary, including
  420. the container's exit code under the ``StatusCode`` attribute.
  421. Raises:
  422. :py:class:`requests.exceptions.ReadTimeout`
  423. If the timeout is exceeded.
  424. :py:class:`docker.errors.APIError`
  425. If the server returns an error.
  426. """
  427. return self.client.api.wait(self.id, **kwargs)
  428. class ContainerCollection(Collection):
  429. model = Container
  430. def run(self, image, command=None, stdout=True, stderr=False,
  431. remove=False, **kwargs):
  432. """
  433. Run a container. By default, it will wait for the container to finish
  434. and return its logs, similar to ``docker run``.
  435. If the ``detach`` argument is ``True``, it will start the container
  436. and immediately return a :py:class:`Container` object, similar to
  437. ``docker run -d``.
  438. Example:
  439. Run a container and get its output:
  440. >>> import docker
  441. >>> client = docker.from_env()
  442. >>> client.containers.run('alpine', 'echo hello world')
  443. b'hello world\\n'
  444. Run a container and detach:
  445. >>> container = client.containers.run('bfirsh/reticulate-splines',
  446. detach=True)
  447. >>> container.logs()
  448. 'Reticulating spline 1...\\nReticulating spline 2...\\n'
  449. Args:
  450. image (str): The image to run.
  451. command (str or list): The command to run in the container.
  452. auto_remove (bool): enable auto-removal of the container on daemon
  453. side when the container's process exits.
  454. blkio_weight_device: Block IO weight (relative device weight) in
  455. the form of: ``[{"Path": "device_path", "Weight": weight}]``.
  456. blkio_weight: Block IO weight (relative weight), accepts a weight
  457. value between 10 and 1000.
  458. cap_add (list of str): Add kernel capabilities. For example,
  459. ``["SYS_ADMIN", "MKNOD"]``.
  460. cap_drop (list of str): Drop kernel capabilities.
  461. cgroup_parent (str): Override the default parent cgroup.
  462. cgroupns (str): Override the default cgroup namespace mode for the
  463. container. One of:
  464. - ``private`` the container runs in its own private cgroup
  465. namespace.
  466. - ``host`` use the host system's cgroup namespace.
  467. cpu_count (int): Number of usable CPUs (Windows only).
  468. cpu_percent (int): Usable percentage of the available CPUs
  469. (Windows only).
  470. cpu_period (int): The length of a CPU period in microseconds.
  471. cpu_quota (int): Microseconds of CPU time that the container can
  472. get in a CPU period.
  473. cpu_rt_period (int): Limit CPU real-time period in microseconds.
  474. cpu_rt_runtime (int): Limit CPU real-time runtime in microseconds.
  475. cpu_shares (int): CPU shares (relative weight).
  476. cpuset_cpus (str): CPUs in which to allow execution (``0-3``,
  477. ``0,1``).
  478. cpuset_mems (str): Memory nodes (MEMs) in which to allow execution
  479. (``0-3``, ``0,1``). Only effective on NUMA systems.
  480. detach (bool): Run container in the background and return a
  481. :py:class:`Container` object.
  482. device_cgroup_rules (:py:class:`list`): A list of cgroup rules to
  483. apply to the container.
  484. device_read_bps: Limit read rate (bytes per second) from a device
  485. in the form of: `[{"Path": "device_path", "Rate": rate}]`
  486. device_read_iops: Limit read rate (IO per second) from a device.
  487. device_write_bps: Limit write rate (bytes per second) from a
  488. device.
  489. device_write_iops: Limit write rate (IO per second) from a device.
  490. devices (:py:class:`list`): Expose host devices to the container,
  491. as a list of strings in the form
  492. ``<path_on_host>:<path_in_container>:<cgroup_permissions>``.
  493. For example, ``/dev/sda:/dev/xvda:rwm`` allows the container
  494. to have read-write access to the host's ``/dev/sda`` via a
  495. node named ``/dev/xvda`` inside the container.
  496. device_requests (:py:class:`list`): Expose host resources such as
  497. GPUs to the container, as a list of
  498. :py:class:`docker.types.DeviceRequest` instances.
  499. dns (:py:class:`list`): Set custom DNS servers.
  500. dns_opt (:py:class:`list`): Additional options to be added to the
  501. container's ``resolv.conf`` file.
  502. dns_search (:py:class:`list`): DNS search domains.
  503. domainname (str or list): Set custom DNS search domains.
  504. entrypoint (str or list): The entrypoint for the container.
  505. environment (dict or list): Environment variables to set inside
  506. the container, as a dictionary or a list of strings in the
  507. format ``["SOMEVARIABLE=xxx"]``.
  508. extra_hosts (dict): Additional hostnames to resolve inside the
  509. container, as a mapping of hostname to IP address.
  510. group_add (:py:class:`list`): List of additional group names and/or
  511. IDs that the container process will run as.
  512. healthcheck (dict): Specify a test to perform to check that the
  513. container is healthy. The dict takes the following keys:
  514. - test (:py:class:`list` or str): Test to perform to determine
  515. container health. Possible values:
  516. - Empty list: Inherit healthcheck from parent image
  517. - ``["NONE"]``: Disable healthcheck
  518. - ``["CMD", args...]``: exec arguments directly.
  519. - ``["CMD-SHELL", command]``: Run command in the system's
  520. default shell.
  521. If a string is provided, it will be used as a ``CMD-SHELL``
  522. command.
  523. - interval (int): The time to wait between checks in
  524. nanoseconds. It should be 0 or at least 1000000 (1 ms).
  525. - timeout (int): The time to wait before considering the check
  526. to have hung. It should be 0 or at least 1000000 (1 ms).
  527. - retries (int): The number of consecutive failures needed to
  528. consider a container as unhealthy.
  529. - start_period (int): Start period for the container to
  530. initialize before starting health-retries countdown in
  531. nanoseconds. It should be 0 or at least 1000000 (1 ms).
  532. hostname (str): Optional hostname for the container.
  533. init (bool): Run an init inside the container that forwards
  534. signals and reaps processes
  535. init_path (str): Path to the docker-init binary
  536. ipc_mode (str): Set the IPC mode for the container.
  537. isolation (str): Isolation technology to use. Default: `None`.
  538. kernel_memory (int or str): Kernel memory limit
  539. labels (dict or list): A dictionary of name-value labels (e.g.
  540. ``{"label1": "value1", "label2": "value2"}``) or a list of
  541. names of labels to set with empty values (e.g.
  542. ``["label1", "label2"]``)
  543. links (dict): Mapping of links using the
  544. ``{'container': 'alias'}`` format. The alias is optional.
  545. Containers declared in this dict will be linked to the new
  546. container using the provided alias. Default: ``None``.
  547. log_config (LogConfig): Logging configuration.
  548. lxc_conf (dict): LXC config.
  549. mac_address (str): MAC address to assign to the container.
  550. mem_limit (int or str): Memory limit. Accepts float values
  551. (which represent the memory limit of the created container in
  552. bytes) or a string with a units identification char
  553. (``100000b``, ``1000k``, ``128m``, ``1g``). If a string is
  554. specified without a units character, bytes are assumed as an
  555. intended unit.
  556. mem_reservation (int or str): Memory soft limit.
  557. mem_swappiness (int): Tune a container's memory swappiness
  558. behavior. Accepts number between 0 and 100.
  559. memswap_limit (str or int): Maximum amount of memory + swap a
  560. container is allowed to consume.
  561. mounts (:py:class:`list`): Specification for mounts to be added to
  562. the container. More powerful alternative to ``volumes``. Each
  563. item in the list is expected to be a
  564. :py:class:`docker.types.Mount` object.
  565. name (str): The name for this container.
  566. nano_cpus (int): CPU quota in units of 1e-9 CPUs.
  567. network (str): Name of the network this container will be connected
  568. to at creation time. You can connect to additional networks
  569. using :py:meth:`Network.connect`. Incompatible with
  570. ``network_mode``.
  571. network_disabled (bool): Disable networking.
  572. network_mode (str): One of:
  573. - ``bridge`` Create a new network stack for the container on
  574. the bridge network.
  575. - ``none`` No networking for this container.
  576. - ``container:<name|id>`` Reuse another container's network
  577. stack.
  578. - ``host`` Use the host network stack.
  579. This mode is incompatible with ``ports``.
  580. Incompatible with ``network``.
  581. network_driver_opt (dict): A dictionary of options to provide
  582. to the network driver. Defaults to ``None``. Used in
  583. conjuction with ``network``. Incompatible
  584. with ``network_mode``.
  585. oom_kill_disable (bool): Whether to disable OOM killer.
  586. oom_score_adj (int): An integer value containing the score given
  587. to the container in order to tune OOM killer preferences.
  588. pid_mode (str): If set to ``host``, use the host PID namespace
  589. inside the container.
  590. pids_limit (int): Tune a container's pids limit. Set ``-1`` for
  591. unlimited.
  592. platform (str): Platform in the format ``os[/arch[/variant]]``.
  593. Only used if the method needs to pull the requested image.
  594. ports (dict): Ports to bind inside the container.
  595. The keys of the dictionary are the ports to bind inside the
  596. container, either as an integer or a string in the form
  597. ``port/protocol``, where the protocol is either ``tcp``,
  598. ``udp``, or ``sctp``.
  599. The values of the dictionary are the corresponding ports to
  600. open on the host, which can be either:
  601. - The port number, as an integer. For example,
  602. ``{'2222/tcp': 3333}`` will expose port 2222 inside the
  603. container as port 3333 on the host.
  604. - ``None``, to assign a random host port. For example,
  605. ``{'2222/tcp': None}``.
  606. - A tuple of ``(address, port)`` if you want to specify the
  607. host interface. For example,
  608. ``{'1111/tcp': ('127.0.0.1', 1111)}``.
  609. - A list of integers, if you want to bind multiple host ports
  610. to a single container port. For example,
  611. ``{'1111/tcp': [1234, 4567]}``.
  612. Incompatible with ``host`` network mode.
  613. privileged (bool): Give extended privileges to this container.
  614. publish_all_ports (bool): Publish all ports to the host.
  615. read_only (bool): Mount the container's root filesystem as read
  616. only.
  617. remove (bool): Remove the container when it has finished running.
  618. Default: ``False``.
  619. restart_policy (dict): Restart the container when it exits.
  620. Configured as a dictionary with keys:
  621. - ``Name`` One of ``on-failure``, or ``always``.
  622. - ``MaximumRetryCount`` Number of times to restart the
  623. container on failure.
  624. For example:
  625. ``{"Name": "on-failure", "MaximumRetryCount": 5}``
  626. runtime (str): Runtime to use with this container.
  627. security_opt (:py:class:`list`): A list of string values to
  628. customize labels for MLS systems, such as SELinux.
  629. shm_size (str or int): Size of /dev/shm (e.g. ``1G``).
  630. stdin_open (bool): Keep ``STDIN`` open even if not attached.
  631. stdout (bool): Return logs from ``STDOUT`` when ``detach=False``.
  632. Default: ``True``.
  633. stderr (bool): Return logs from ``STDERR`` when ``detach=False``.
  634. Default: ``False``.
  635. stop_signal (str): The stop signal to use to stop the container
  636. (e.g. ``SIGINT``).
  637. storage_opt (dict): Storage driver options per container as a
  638. key-value mapping.
  639. stream (bool): If true and ``detach`` is false, return a log
  640. generator instead of a string. Ignored if ``detach`` is true.
  641. Default: ``False``.
  642. sysctls (dict): Kernel parameters to set in the container.
  643. tmpfs (dict): Temporary filesystems to mount, as a dictionary
  644. mapping a path inside the container to options for that path.
  645. For example:
  646. .. code-block:: python
  647. {
  648. '/mnt/vol2': '',
  649. '/mnt/vol1': 'size=3G,uid=1000'
  650. }
  651. tty (bool): Allocate a pseudo-TTY.
  652. ulimits (:py:class:`list`): Ulimits to set inside the container,
  653. as a list of :py:class:`docker.types.Ulimit` instances.
  654. use_config_proxy (bool): If ``True``, and if the docker client
  655. configuration file (``~/.docker/config.json`` by default)
  656. contains a proxy configuration, the corresponding environment
  657. variables will be set in the container being built.
  658. user (str or int): Username or UID to run commands as inside the
  659. container.
  660. userns_mode (str): Sets the user namespace mode for the container
  661. when user namespace remapping option is enabled. Supported
  662. values are: ``host``
  663. uts_mode (str): Sets the UTS namespace mode for the container.
  664. Supported values are: ``host``
  665. version (str): The version of the API to use. Set to ``auto`` to
  666. automatically detect the server's version. Default: ``1.35``
  667. volume_driver (str): The name of a volume driver/plugin.
  668. volumes (dict or list): A dictionary to configure volumes mounted
  669. inside the container. The key is either the host path or a
  670. volume name, and the value is a dictionary with the keys:
  671. - ``bind`` The path to mount the volume inside the container
  672. - ``mode`` Either ``rw`` to mount the volume read/write, or
  673. ``ro`` to mount it read-only.
  674. For example:
  675. .. code-block:: python
  676. {'/home/user1/': {'bind': '/mnt/vol2', 'mode': 'rw'},
  677. '/var/www': {'bind': '/mnt/vol1', 'mode': 'ro'}}
  678. Or a list of strings which each one of its elements specifies a
  679. mount volume.
  680. For example:
  681. .. code-block:: python
  682. ['/home/user1/:/mnt/vol2','/var/www:/mnt/vol1']
  683. volumes_from (:py:class:`list`): List of container names or IDs to
  684. get volumes from.
  685. working_dir (str): Path to the working directory.
  686. Returns:
  687. The container logs, either ``STDOUT``, ``STDERR``, or both,
  688. depending on the value of the ``stdout`` and ``stderr`` arguments.
  689. ``STDOUT`` and ``STDERR`` may be read only if either ``json-file``
  690. or ``journald`` logging driver used. Thus, if you are using none of
  691. these drivers, a ``None`` object is returned instead. See the
  692. `Engine API documentation
  693. <https://docs.docker.com/engine/api/v1.30/#operation/ContainerLogs/>`_
  694. for full details.
  695. If ``detach`` is ``True``, a :py:class:`Container` object is
  696. returned instead.
  697. Raises:
  698. :py:class:`docker.errors.ContainerError`
  699. If the container exits with a non-zero exit code and
  700. ``detach`` is ``False``.
  701. :py:class:`docker.errors.ImageNotFound`
  702. If the specified image does not exist.
  703. :py:class:`docker.errors.APIError`
  704. If the server returns an error.
  705. """
  706. if isinstance(image, Image):
  707. image = image.id
  708. stream = kwargs.pop('stream', False)
  709. detach = kwargs.pop('detach', False)
  710. platform = kwargs.get('platform', None)
  711. if detach and remove:
  712. if version_gte(self.client.api._version, '1.25'):
  713. kwargs["auto_remove"] = True
  714. else:
  715. raise RuntimeError("The options 'detach' and 'remove' cannot "
  716. "be used together in api versions < 1.25.")
  717. if kwargs.get('network') and kwargs.get('network_mode'):
  718. raise RuntimeError(
  719. 'The options "network" and "network_mode" can not be used '
  720. 'together.'
  721. )
  722. if kwargs.get('network_driver_opt') and not kwargs.get('network'):
  723. raise RuntimeError(
  724. 'The options "network_driver_opt" can not be used '
  725. 'without "network".'
  726. )
  727. try:
  728. container = self.create(image=image, command=command,
  729. detach=detach, **kwargs)
  730. except ImageNotFound:
  731. self.client.images.pull(image, platform=platform)
  732. container = self.create(image=image, command=command,
  733. detach=detach, **kwargs)
  734. container.start()
  735. if detach:
  736. return container
  737. logging_driver = container.attrs['HostConfig']['LogConfig']['Type']
  738. out = None
  739. if logging_driver == 'json-file' or logging_driver == 'journald':
  740. out = container.logs(
  741. stdout=stdout, stderr=stderr, stream=True, follow=True
  742. )
  743. exit_status = container.wait()['StatusCode']
  744. if exit_status != 0:
  745. out = None
  746. if not kwargs.get('auto_remove'):
  747. out = container.logs(stdout=False, stderr=True)
  748. if remove:
  749. container.remove()
  750. if exit_status != 0:
  751. raise ContainerError(
  752. container, exit_status, command, image, out
  753. )
  754. return out if stream or out is None else b''.join(
  755. [line for line in out]
  756. )
  757. def create(self, image, command=None, **kwargs):
  758. """
  759. Create a container without starting it. Similar to ``docker create``.
  760. Takes the same arguments as :py:meth:`run`, except for ``stdout``,
  761. ``stderr``, and ``remove``.
  762. Returns:
  763. A :py:class:`Container` object.
  764. Raises:
  765. :py:class:`docker.errors.ImageNotFound`
  766. If the specified image does not exist.
  767. :py:class:`docker.errors.APIError`
  768. If the server returns an error.
  769. """
  770. if isinstance(image, Image):
  771. image = image.id
  772. kwargs['image'] = image
  773. kwargs['command'] = command
  774. kwargs['version'] = self.client.api._version
  775. create_kwargs = _create_container_args(kwargs)
  776. resp = self.client.api.create_container(**create_kwargs)
  777. return self.get(resp['Id'])
  778. def get(self, container_id):
  779. """
  780. Get a container by name or ID.
  781. Args:
  782. container_id (str): Container name or ID.
  783. Returns:
  784. A :py:class:`Container` object.
  785. Raises:
  786. :py:class:`docker.errors.NotFound`
  787. If the container does not exist.
  788. :py:class:`docker.errors.APIError`
  789. If the server returns an error.
  790. """
  791. resp = self.client.api.inspect_container(container_id)
  792. return self.prepare_model(resp)
  793. def list(self, all=False, before=None, filters=None, limit=-1, since=None,
  794. sparse=False, ignore_removed=False):
  795. """
  796. List containers. Similar to the ``docker ps`` command.
  797. Args:
  798. all (bool): Show all containers. Only running containers are shown
  799. by default
  800. since (str): Show only containers created since Id or Name, include
  801. non-running ones
  802. before (str): Show only container created before Id or Name,
  803. include non-running ones
  804. limit (int): Show `limit` last created containers, include
  805. non-running ones
  806. filters (dict): Filters to be processed on the image list.
  807. Available filters:
  808. - `exited` (int): Only containers with specified exit code
  809. - `status` (str): One of ``restarting``, ``running``,
  810. ``paused``, ``exited``
  811. - `label` (str|list): format either ``"key"``, ``"key=value"``
  812. or a list of such.
  813. - `id` (str): The id of the container.
  814. - `name` (str): The name of the container.
  815. - `ancestor` (str): Filter by container ancestor. Format of
  816. ``<image-name>[:tag]``, ``<image-id>``, or
  817. ``<image@digest>``.
  818. - `before` (str): Only containers created before a particular
  819. container. Give the container name or id.
  820. - `since` (str): Only containers created after a particular
  821. container. Give container name or id.
  822. A comprehensive list can be found in the documentation for
  823. `docker ps
  824. <https://docs.docker.com/engine/reference/commandline/ps>`_.
  825. sparse (bool): Do not inspect containers. Returns partial
  826. information, but guaranteed not to block. Use
  827. :py:meth:`Container.reload` on resulting objects to retrieve
  828. all attributes. Default: ``False``
  829. ignore_removed (bool): Ignore failures due to missing containers
  830. when attempting to inspect containers from the original list.
  831. Set to ``True`` if race conditions are likely. Has no effect
  832. if ``sparse=True``. Default: ``False``
  833. Returns:
  834. (list of :py:class:`Container`)
  835. Raises:
  836. :py:class:`docker.errors.APIError`
  837. If the server returns an error.
  838. """
  839. resp = self.client.api.containers(all=all, before=before,
  840. filters=filters, limit=limit,
  841. since=since)
  842. if sparse:
  843. return [self.prepare_model(r) for r in resp]
  844. else:
  845. containers = []
  846. for r in resp:
  847. try:
  848. containers.append(self.get(r['Id']))
  849. # a container may have been removed while iterating
  850. except NotFound:
  851. if not ignore_removed:
  852. raise
  853. return containers
  854. def prune(self, filters=None):
  855. return self.client.api.prune_containers(filters=filters)
  856. prune.__doc__ = APIClient.prune_containers.__doc__
  857. # kwargs to copy straight from run to create
  858. RUN_CREATE_KWARGS = [
  859. 'command',
  860. 'detach',
  861. 'domainname',
  862. 'entrypoint',
  863. 'environment',
  864. 'healthcheck',
  865. 'hostname',
  866. 'image',
  867. 'labels',
  868. 'mac_address',
  869. 'name',
  870. 'network_disabled',
  871. 'platform',
  872. 'stdin_open',
  873. 'stop_signal',
  874. 'tty',
  875. 'use_config_proxy',
  876. 'user',
  877. 'working_dir',
  878. ]
  879. # kwargs to copy straight from run to host_config
  880. RUN_HOST_CONFIG_KWARGS = [
  881. 'auto_remove',
  882. 'blkio_weight_device',
  883. 'blkio_weight',
  884. 'cap_add',
  885. 'cap_drop',
  886. 'cgroup_parent',
  887. 'cgroupns',
  888. 'cpu_count',
  889. 'cpu_percent',
  890. 'cpu_period',
  891. 'cpu_quota',
  892. 'cpu_shares',
  893. 'cpuset_cpus',
  894. 'cpuset_mems',
  895. 'cpu_rt_period',
  896. 'cpu_rt_runtime',
  897. 'device_cgroup_rules',
  898. 'device_read_bps',
  899. 'device_read_iops',
  900. 'device_write_bps',
  901. 'device_write_iops',
  902. 'devices',
  903. 'device_requests',
  904. 'dns_opt',
  905. 'dns_search',
  906. 'dns',
  907. 'extra_hosts',
  908. 'group_add',
  909. 'init',
  910. 'init_path',
  911. 'ipc_mode',
  912. 'isolation',
  913. 'kernel_memory',
  914. 'links',
  915. 'log_config',
  916. 'lxc_conf',
  917. 'mem_limit',
  918. 'mem_reservation',
  919. 'mem_swappiness',
  920. 'memswap_limit',
  921. 'mounts',
  922. 'nano_cpus',
  923. 'network_mode',
  924. 'oom_kill_disable',
  925. 'oom_score_adj',
  926. 'pid_mode',
  927. 'pids_limit',
  928. 'privileged',
  929. 'publish_all_ports',
  930. 'read_only',
  931. 'restart_policy',
  932. 'security_opt',
  933. 'shm_size',
  934. 'storage_opt',
  935. 'sysctls',
  936. 'tmpfs',
  937. 'ulimits',
  938. 'userns_mode',
  939. 'uts_mode',
  940. 'version',
  941. 'volume_driver',
  942. 'volumes_from',
  943. 'runtime'
  944. ]
  945. def _create_container_args(kwargs):
  946. """
  947. Convert arguments to create() to arguments to create_container().
  948. """
  949. # Copy over kwargs which can be copied directly
  950. create_kwargs = {}
  951. for key in copy.copy(kwargs):
  952. if key in RUN_CREATE_KWARGS:
  953. create_kwargs[key] = kwargs.pop(key)
  954. host_config_kwargs = {}
  955. for key in copy.copy(kwargs):
  956. if key in RUN_HOST_CONFIG_KWARGS:
  957. host_config_kwargs[key] = kwargs.pop(key)
  958. # Process kwargs which are split over both create and host_config
  959. ports = kwargs.pop('ports', {})
  960. if ports:
  961. host_config_kwargs['port_bindings'] = ports
  962. volumes = kwargs.pop('volumes', {})
  963. if volumes:
  964. host_config_kwargs['binds'] = volumes
  965. network = kwargs.pop('network', None)
  966. network_driver_opt = kwargs.pop('network_driver_opt', None)
  967. if network:
  968. network_configuration = {'driver_opt': network_driver_opt} \
  969. if network_driver_opt else None
  970. create_kwargs['networking_config'] = {network: network_configuration}
  971. host_config_kwargs['network_mode'] = network
  972. # All kwargs should have been consumed by this point, so raise
  973. # error if any are left
  974. if kwargs:
  975. raise create_unexpected_kwargs_error('run', kwargs)
  976. create_kwargs['host_config'] = HostConfig(**host_config_kwargs)
  977. # Fill in any kwargs which need processing by create_host_config first
  978. port_bindings = create_kwargs['host_config'].get('PortBindings')
  979. if port_bindings:
  980. # sort to make consistent for tests
  981. create_kwargs['ports'] = [tuple(p.split('/', 1))
  982. for p in sorted(port_bindings.keys())]
  983. if volumes:
  984. if isinstance(volumes, dict):
  985. create_kwargs['volumes'] = [
  986. v.get('bind') for v in volumes.values()
  987. ]
  988. else:
  989. create_kwargs['volumes'] = [
  990. _host_volume_from_bind(v) for v in volumes
  991. ]
  992. return create_kwargs
  993. def _host_volume_from_bind(bind):
  994. drive, rest = ntpath.splitdrive(bind)
  995. bits = rest.split(':', 1)
  996. if len(bits) == 1 or bits[1] in ('ro', 'rw'):
  997. return drive + bits[0]
  998. elif bits[1].endswith(':ro') or bits[1].endswith(':rw'):
  999. return bits[1][:-3]
  1000. else:
  1001. return bits[1]
  1002. ExecResult = namedtuple('ExecResult', 'exit_code,output')
  1003. """ A result of Container.exec_run with the properties ``exit_code`` and
  1004. ``output``. """