Home > Blockchain >  Interact with podman docker via socket in Redhat 9
Interact with podman docker via socket in Redhat 9

Time:06-21

I'm trying to migrate one of my dev boxes over from centos 8 to RHEL9. I rely heavily on docker and noticed when I tried to run a docker command on the RHEL box it installed podman-docker. This seemed to go smoothly; I was able to pull an image, launch, build, commit a new version without problem using the docker commands I knew already.

The problem I have encountered though is I can't seem to interact with it via the docker socket (which seems to be a link to the podman one).

If I run the docker command:

[@rhel9 ~]$ docker images
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
REPOSITORY             TAG              IMAGE ID      CREATED      SIZE
docker.io/redhat/ubi9  dev_image        de371523ca26  6 hours ago  805 MB
docker.io/redhat/ubi9  latest           9ad46cd10362  6 days ago   230 MB

it has my images listed as expected. I should be able to also run:

[@rhel9 ~]$ curl --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' http://localhost/images/json | jq .
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100     3  100     3    0     0     55      0 --:--:-- --:--:-- --:--:--    55
[]

but as you can see, nothing is coming back. The socket is up and running as I can ping it without issue:

[@rhel9 ~]$ curl -H "Content-Type: application/json" --unix-socket /var/run/docker.sock http://localhost/_ping
OK

I also tried the curl commands using the podman socket directly but it had the same results. Is there something I am missing or a trick to getting it to work so that I can interact with docker/podman via the socket?

CodePudding user response:

Podman isn't implemented using a client/server model like Docker. By default there is no socket, because there's no equivalent to the docker daemon. Podman does provide a compatibility interface that you can use by enabling the podman.socket unit:

$ systemctl enable --now podman.socket

This exposes a Unix socket at /run/podman/podman.sock that responds to Docker API commands. But!

The socket connects you to podman running as root, whereas you've been running podman as a non-root user: so you won't see the same list of images, containers, networks, etc.


Some random notes:

  • Podman by default runs "rootless": you can run it as an unprivileged user, and all of its storage, metadata, etc, is stored in your home directory.
  • You can also run Podman as root, in which case the behavior is more like Docker.
  • If you enable the podman socket, you can replace podman-docker with the actual Docker client (and use things like docker-compose), although I have run into occasional issues with this. Mostly I just use podman, and run docker engine in a VM). You will need to configure Docker to look at the podman socket in /run/podman/podman.sock.

I have podman.socket enabled on my system, so this works:

$ curl --unix-socket /run/podman/podman.sock -H 'content-type: application/json' http://localhost/_ping
OK

Or:

$ curl --unix-socket /run/podman/podman.sock -H 'content-type: application/json' -sf http://localhost/containers/json | jq
[
  {
    "Id": "f0d9a880c45bb5857b24f46bcb6eeeca162eb68d574c8ba16c4a03703c2d60f4",
    "Names": [
      "/sleeper"
    ],
    "Image": "docker.io/library/alpine:latest",
    "ImageID": "14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab",
    "Command": "sleep inf",
    "Created": 1655418914,
    "Ports": [],
    "Labels": {},
    "State": "running",
    "Status": "Up 3 days",
    "NetworkSettings": {
      "Networks": {
        "podman": {
          "IPAMConfig": null,
          "Links": null,
          "Aliases": null,
          "NetworkID": "podman",
          "EndpointID": "",
          "Gateway": "10.88.0.1",
          "IPAddress": "10.88.0.2",
          "IPPrefixLen": 16,
          "IPv6Gateway": "",
          "GlobalIPv6Address": "",
          "GlobalIPv6PrefixLen": 0,
          "MacAddress": "06:55:82:1b:1a:41",
          "DriverOpts": null
        }
      }
    },
    "Mounts": null,
    "Name": "",
    "Config": null,
    "NetworkingConfig": null,
    "Platform": null,
    "AdjustCPUShares": false
  }
]

CodePudding user response:

I managed to solve my problem although I'm not entirely sure how the scenario came about. I was looking through the output of docker info and podman info and noticed that they both had the remote socket set as:

remoteSocket:
    exists: true
    path: /run/user/1000/podman/podman.sock

rather than /run/podman/podman.sock which is where I thought it was (this socket does actually exist on my machine). Looking at the systemd file for podman.socket I can see that the socket was specified as %t/podman/podman.sock and checking the man page for podman-system-service it specified the rootless socket as unix://$XDG_RUNTIME_DIR/podman/podman.sock (where my $XDG_RUNTIME_DIR=/run/user/1000.

To get it all working with my software I just needed to make sure the DOCKER_HOST env variable was correctly set e.g. export DOCKER_HOST=unix:///run/user/1000/podman/podman.sock

  • Related