I want to create a service in existing swarm network using python docker sdk. I have a swarm network named test_net.

Installation of library : pip3 install docker

Below is the code used for creating the service

import docker
from docker.types import RestartPolicy, Placement

def python_sdk():
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    service_created = client.services.create(
        image='python:3.7-alpine',
        command='python /home/ubuntu/python.py',
        constraints=Placement(constraints=['worker']),
        mounts='/home/ubuntu/deployment/python.py:/home/ubuntu/python.py:rw',
        networks=['test_net'],
        restart_policy=RestartPolicy(condition='none'),
        name='python_sdk'
    )
    print("Created service : ", service_created)

Below is the error which I got by executing above code :

Traceback (most recent call last):
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/api/client.py", line 268, in _raise_for_status
    response.raise_for_status()
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http+docker://localhost/v1.41/services/create

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "client.py", line 20, in <module>
    python_sdk()
  File "client.py", line 16, in python_sdk
    name='python_sdk'
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/models/services.py", line 227, in create
    service_id = self.client.api.create_service(**create_kwargs)
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/utils/decorators.py", line 34, in wrapper
    return f(self, *args, **kwargs)
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/api/service.py", line 190, in create_service
    self._post_json(url, data=data, headers=headers), True
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/api/client.py", line 274, in _result
    self._raise_for_status(response)
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/api/client.py", line 270, in _raise_for_status
    raise create_api_error_from_http_exception(e)
  File "/home/ubuntu/deployment/dags/venv/lib/python3.6/site-packages/docker/errors.py", line 31, in create_api_error_from_http_exception
    raise cls(e, response=response, explanation=explanation)
docker.errors.APIError: 400 Client Error for http+docker://localhost/v1.41/services/create: Bad Request ("json: cannot unmarshal object into Go struct field Placement.TaskTemplate.Placement.Constraints of type []string")

I am referring to this documentation.

How can I use Placement object to use constraints?

I also tried constraints = ["Placement(constraints=['worker']"]

1

There are 1 answers

0
Nisarg Shah On

I got the answer for the above issue. In the documentation, it is mentioned that the list of str needs to be passed in constraints.

The mentioned parameter is documentation : constraints (list of str) – Placement constraints.

So the final code will be,

import docker
from docker.types import RestartPolicy, Placement

def python_sdk():
    client = docker.DockerClient(base_url='unix://var/run/docker.sock')
    service_created = client.services.create(
        image='python:3.7-alpine',
        command='python /home/ubuntu/python.py',
        constraints=['node.role == worker']),
        mounts='/home/ubuntu/deployment/python.py:/home/ubuntu/python.py:rw',
        networks=['test_net'],
        restart_policy=RestartPolicy(condition='none'),
        name='python_sdk'
    )
    print("Created service : ", service_created)