Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Unable to access docker daemon #30

Closed
halostatue opened this issue Jul 19, 2023 · 10 comments
Closed

[BUG] Unable to access docker daemon #30

halostatue opened this issue Jul 19, 2023 · 10 comments
Labels
bug Something isn't working

Comments

@halostatue
Copy link

Describe the bug

Oxker will not start.

To Reproduce

  1. oxker
  2. See the screen with the message and auto exit.

Trying to run oxker with no-gui for debugging results in a permanent hang with no messages printed after

2023-07-19T15:35:29.173577Z  INFO oxker: in debug mode

Expected behavior

A screen similar to that which is in the README screenshot. Essentially oxker should be aware of docker contexts, but must be aware of $DOCKER_HOST if set.

Screenshots

CleanShot 2023-07-19 at 11 36 13@2x

Desktop (please complete the following information):

  • OS: macOS
  • Virtualization Solution: OrbStack without the symlinked socket

My socket is in ~/.orbstack/run/docker.sock.

Additional context

Setting $DOCKER_HOST does not help.

$ docker context ls
NAME          DESCRIPTION                               DOCKER ENDPOINT                                  ERROR
colima-vz-8   colima [profile=vz-8]                     unix:///Users/austin/.colima/vz-8/docker.sock
default       Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
orbstack *    OrbStack                                  unix:///Users/austin/.orbstack/run/docker.sock
@halostatue halostatue added the bug Something isn't working label Jul 19, 2023
@mrjackwills
Copy link
Owner

mrjackwills commented Jul 19, 2023

Yeah, oxker should definitely correctly read and handle the $DOCKER_HOST env.

As for the debug mode, again, yes it should force quit(?) if a docker connection cannot be achieved.

In the mean time, I think you should be able to use the DockerHub/ghcr image, but mount your custom socket instead of the default:

docker run --rm -it -v ~/.orbstack/run/docker.sock:/var/run/docker.sock:ro --pull=always mrjackwills/oxker

Although obviously this isn't a good long term solution.

Unfortunately I am away from my computer for at least another week, so I can't test, or implement, any fixes at the moment. Rust 1.71.0 has just been released, and I usually try to follow the same six week release schedule with oxker.

@mrjackwills
Copy link
Owner

@halostatue I've just pushed a branch fix/host, which I think should solve the issue. A new cli arg is available, --host, to set the docker host path. However, it'll also check for a $DOCKER_HOST env, at the moment the cli arg takes priority over the env - do you think this is the correct order?

Secondly, when in debug mode, it should exit with code 1 if there are any errors - amazed that this hasn't come up before and that I missed this.

If you are unable, or unwilling, to build from source, let me know and I can upload a binary here.

@halostatue
Copy link
Author

I’ll need to come back to this in a couple of days, but I can try it from source.

@halostatue
Copy link
Author

Sorry for the long delay, but the fix/host branch works when setting $DOCKER_HOST. Ideally, oxker should work such that it can query the Docker contexts to find the current list and get the socket directly:

$ docker context ls --format '{{ . | json }}' | jq -s '.[] | select(.Current == true) | .DockerEndpoint'
"unix:///Users/austin/.orbstack/run/docker.sock"

But this can be considered closed because it now works with $DOCKER_HOST.

@mrjackwills
Copy link
Owner

mrjackwills commented Aug 16, 2023

@halostatue Thank you for taking the time to check that it works. I wasn't really aware of the Docker context before you submitted the issue. I should probably read the docs further to make sure I fully understand it, to make oxker find the context automatically and correctly as you suggest.

One final note, did you manage to test the --host cli arg, and if so did that work correctly?

Thanks again

@halostatue
Copy link
Author

It does:

$ oxker --host (docker context ls --format '{{ . | json }}' | jq -r -s '.[] | select(.Current == true) | .DockerEndpoint')

(I use fish, so that’s why the lack of $.)

@mrjackwills
Copy link
Owner

Perfect thanks, I'll merge the branch, and probably wait til rust 1.72.0 on August 24th before publishing a new version. Will do some testing about auto context finding that can be terminal agnostic.

@halostatue
Copy link
Author

I’ve done a bit more research, and I think that there’s an opportunity for a crate here to improve Docker context support across Rust projects. I suspect that there’s explicit code that could be translated from Go in the docker command-line itself, but here’s what I have seen:

  • contexts are external to the Docker API, managed entirely in ~/.docker.
  • the current context is found via [~/.docker/config.json].currentContexst
  • contexts themselves are defined in ~/.docker/contexts/meta/*/meta.json; the directory between meta/ and meta.json appears to be some sort of UUID-ish value (it might be a hashed value of the context name)
  • the contents of meta.json is incomplete compared to docker context inspect --format json CONTEXT

meta.json:

{
  "Name": "orbstack",
  "Metadata": {
    "Description": "OrbStack"
  },
  "Endpoints": {
    "docker": {
      "Host": "unix:///Users/austin/.orbstack/run/docker.sock",
      "SkipTLSVerify": false
    }
  }
}

docker context inspect --format json orbstack

[
  {
    "Name": "orbstack",
    "Metadata": {
      "Description": "OrbStack"
    },
    "Endpoints": {
      "docker": {
        "Host": "unix:///Users/austin/.orbstack/run/docker.sock",
        "SkipTLSVerify": false
      }
    },
    "TLSMaterial": {},
    "Storage": {
      "MetadataPath": "/Users/austin/.docker/contexts/meta/2d89b732b01a00a2d1675ed3cee9fd0f965daadf90603c989dd3afd4569c6896",
      "TLSPath": "/Users/austin/.docker/contexts/tls/2d89b732b01a00a2d1675ed3cee9fd0f965daadf90603c989dd3afd4569c6896"
    }
  }
]

Ignoring the fact that docker context inspect --format json returns an array, there are two additional keys TLSMaterial (unknown contents, empty in my context) and Storage (which is constructed from the discovered file paths themselves).

I’m not good enough with Rust to build such a crate, nor do I really have an interest in maintaining such a crate (my interest in Docker and related tools is as a user, not someone who wants to build tools for Docker), but this is what I have found.

@mrjackwills
Copy link
Owner

Thank you, highly informative and helpful.

oxker uses a crate called bollard to communicate with Docker. They actually have an open issue at the moment that I think might be related (I still haven't read enough into the Docker context, it's on my todo list) fussybeaver/bollard#310

@halostatue
Copy link
Author

The issue isn’t related to contexts, but is related to automatic resolution of $DOCKER_HOST if it isn’t pointing to a Unix socket, if I’m reading it correctly. That said, bollard is probably the right place to add this functionality, since it’s where connections are resolved.

If I were to weigh in on that, I would suggest:

  • Docker::connect_with_context_defaults() - follows the Docker CLI behaviour ($DOCKER_HOST overrides any context, checks the currentContext value and resolves that if not default, falls back to Docker::connect_with_socket_defaults() otherwise)
  • Docker::connect_with_context() - parameterized context start, which I believe would ignore $DOCKER_HOST, but I’m not sure.

Those could also be simplified as Docker::connect_with_defaults() or Docker::connect(), but I’m not sure that the creator of bollard would want that, based on the comments there.

If you decide to implement this independently of bollard, you would basically be getting the EndPoints.docker.Host value and using Docker::connect_with_socket() if it does not start with tcp:// and Docker::connect_with_ssl() if it starts with tcp:// and SkipTLSVerify is false (the default).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants