0

So, I was trying to get some stats for the docker containers running on a server. I tried multiple approaches:

  • Docker SDK for python
  • Making curl request using subprocess module
  • Socket

The first two worked quite well but I could not employ the socket method. I want to compare these ways to figure out which one is faster and better for my usage. Basically, I am trying to convert the curl command into python request. Here's the curl command I have used: curl -H --unix-socket /var/run/docker.sock http://localhost/containers/CONTAINER_ID/stats?stream=false

Can someone help me with this?

Mayank
  • 3
  • 3

1 Answers1

1
  1. ensure process that you want to run Python SDK on has access to /var/run/docker.sock. In example I mount it as a volume into container
  2. python code is then using sockets anyway so no need to spawn additional subprocesses to do curl. You have full access to all status information. Where more detailed into is required use
  htpc:
    container_name: htpc
    build:
      context: .
      dockerfile: flask-Dockerfile
    ports: 
      - "5000:5000"
    restart: unless-stopped
    volumes: 
      - /var/run/docker.sock:/var/run/docker.sock  # map through socket
def docker_api():
    client = docker.from_env()
    if request.args["action"] == "list":
        l = []
        for c in client.containers.list(all=True):
            # string conversion only works for 6 digit ms,  strip back to 26 chars
            if c.status == "running":
                utc_time = datetime.strptime(client.api.inspect_container(c.short_id)["State"]["StartedAt"][:26]+"Z", "%Y-%m-%dT%H:%M:%S.%fZ")
            else:
                utc_time = datetime.utcnow()
            l.append({"id":c.short_id, "name":c.name, "image":c.image.tags[0] if len(c.image.tags)>0 else "unknown", 
                      "status":c.status, "logs":True, "inspect":True,
                      "stats":c.status=="running", "restart":c.status=="running", "stop":c.status=="running", "start":c.status!="running", "delete":True,
                      "uptime":(utc_time - datetime(1970, 1, 1)).total_seconds(),
                      })
        return Response(json.dumps(l), mimetype="text/json")
    elif request.args["action"] == "logs":
        return Response(client.containers.get(request.args["id"]).logs().decode(), mimetype="text/plain")
    elif request.args["action"] == "stats":
        return Response(json.dumps(client.containers.get(request.args["id"]).stats(stream=False)), mimetype="text/json")
    elif request.args["action"] == "inspect":
        js = client.api.inspect_container(request.args["id"])
        m = {"StartedAt":js["State"]["StartedAt"], "Mounts":js["Mounts"]}
        for i, mp in enumerate(m["Mounts"]):
            m["Mounts"][i] = {k: mp[k] for k in ('Source', 'Destination')}
        e = {"Env":js["Config"]["Env"], 'RestartPolicy':js['HostConfig']['RestartPolicy']}
        p = {"Ports":js["NetworkSettings"]["Ports"]}
        js = {**m, **e, **p} #, **js}
        return Response(json.dumps(js), mimetype="text/json")

Rob Raymond
  • 29,118
  • 3
  • 14
  • 30