#Attaching a Unix Socket to a container built with .build(directory)?

1 messages · Page 1 of 1 (latest)

barren sentinel
#

Hi,

I was wondering if it was possible to forward/bind a Unix Socket to a container built with .build(directory) i.e. a pre-existing Dockerfile.

I've got a situation in a current project where we have several different Dockerfiles that we want to use w/ a dagger setup, but I'd like to forward the SSH_AUTH_SOCKET to those containers. Is this possible? I tried following some other threads on this discord ("Issues with private go modules", "SSH agent forwarding"), but those are building from scratch, it seems. I haven't had any luck forwarding the socket to the container for git to use, so far.

Thanks!

barren sentinel
#

To be clear this is OSX; wondering if that's the issue

gloomy sigil
barren sentinel
#

yeah; i ran into something though. i saw that in order to mount your SSH_AUTH_SOCK on OSX, you have to pass the container a "magic" socket /run/host-services/ssh-auth.sock. this works with docker run, but it doesn't seem to work with dagger because when I run client.host.file() or client.host.unixSocket(), it gives me an lstat error (presumably because dagger is checking to see if the file is there). is there any way to do this currently?

#

otherwise we will have to fall back to passing the container a ssh key or github token as an argument

glossy barn
barren sentinel
#

during would be nice, similar to how the github repositories work, since in many cases the github repository itself doesn't include the private dependencies and the build would happen during the dockerfile itself. in many cases you are either passing an ssh key to the dockerfile or you use a intermediate image w/ a mounted volume that processes the build before it ships it to a delivery image while it's a running container.

I understand mounting a volume/socket isn't traditionally possible with Dockerfiles (although it would be nice if Dagger could support it), really what i'm looking for is:

  1. The ability to mount the "magic" OSX socket to a container ('/run/host-services/ssh-auth.sock') - right now you get an lstat error when trying to do that. OSX won't allow you to mount UNIX sockets traditionally to the ssh-agent, you have to use that magic socket.
  2. The ability to add env vars to an existing Dockerfile before that Dockerfile is run, right now the way to do this is build args but it would be nice to have a way to do this without modifying the Dockerfile itself
#
  1. being the most important
glossy barn
#

Dagger supports mounting a unix socket from the host into a container, that shouldn’t be a problem. but it can’t inject it into a dockerfile build

barren sentinel
#

yeah that makes sense. the magic socket for OSX isn't a file though, so i think there would need to be some kind of exception for that

glossy barn
#

ssh agent socket? or something else?

#

does docker run have the same problem?

barren sentinel
#

docker run doesn't have the same problem, it's a "magic socket" used for Docker Desktop on OSX

#

it's used like this

#

-v '/run/host-services/ssh-auth.sock':'/run/host-services/ssh-auth.sock' -e SSH_AUTH_SOCK='/run/host-services/ssh-auth.sock'

#

yeah, it's the ssh agent socket

glossy barn
#

cc @empty dust @edgy gust @gleaming latch does this ring a bell? I guess we can either recreate or piggyback on whatever magic the docker desktop app relies on (maybe they proxy then mount from the linuxkit vm?)

#

@barren sentinel even though I don’t have the full technical picture yet, this feels very solvable. Thanks for being patient with us.

barren sentinel
#

np

#

thanks for listening/helping out 😄

glossy barn
#

@barren sentinel I am traveling so didn’t get a chance to test this yet, but… I think the solution is much simpler than we thought!

  • The magic socket is a workaround for a limitation of docker for mac: namely that it runs the engine in a linux vm, and the docker engine does not support forwarding a unix socket to the container across machines…
  • …but dagger does not have this limitation 🙂
  • So you can ignore the magic socket workaround and instead do the simplest thing: grab $SSH_AUTH_SOCK, open the file with host.unixSocket() and mount it with container.withUnixSocket
  • Dagger will take care of magically forwarding the unix socket across machines, no workarounds needed

I will check this as soon as I’m back at a computer (probably monday)

barren sentinel
#

I'm pretty sure I tried this and it doesn't work

#

That was the first thing I tried before trying the magic socket

#

I don't think it's just a limitation of Docker on Mac, I think it's a security restriction placed by Apple re: sockets are handled

#

I basically had a very similar setup to run git authentication w/ a private repo (which worked; no problems there) but when I applied the same strategy to a container, a script using git to SSH into a private crate (rust crate) failed

#

I was able to save the container before it pulled the rust crate and attach the magic socket w/ -v & -e and pulling the crate worked

gloomy sigil
#

cc @empty hatch can you recall if SSH socket forwarding works on a mac? I was assuming it does

empty hatch
gloomy sigil
empty hatch
gloomy sigil
barren sentinel
#

it works with private git repositories via the dagger cli, but last I checked, it didn't work with using the socket traditionally i.e. with rust cargo/crates pulling private git repositories as a part of dependency resolution.

that uses libgit under the hood and looks for the auth socket to authenticate (it's not something you could add a git repo with dagger to fix). git repositories via the dagger cli do work

#

i can try again, to confirm

barren sentinel
#

(in my experience)

#

@empty hatch how did you test?

gloomy sigil
#

that uses libgit under the hood and looks for the auth socket to authenticate (it's not something you could add a git repo with dagger to fix). git repositories via the dagger cli do work

if libgit uses the socket to authenticate, then it should work the same way as the dagger Git operation if you're doing a regular WithExec

#

it won't work for build as mentioned previously since that's not implemented.

#

but it should work if you're willing to migrate your Dockerfile to pure Dagger code as Solomon mentioned

gloomy sigil
#

hey @barren sentinel just checking if you could make progress here.

barren sentinel
#

i think ill have a chance today or tomorrow right now busy with a different end of the project

barren sentinel
#

still busy but i will get back to this soon i promise hah

glossy barn
barren sentinel
#

hey sorry this took so long. back at the other end.

so i tried migrating everything to pure dagger; i'm still running into issues forwarding the auth socket to the container. the solution linked works for git repositories (when you are pulling a private repo and mounting it as a directory), but i'm trying to install a private dependency. here's a snippet of what i'm doing:

   // ssh socket
    const sshAuthSockPath = process.env.SSH_AUTH_SOCK?.toString() || '';
    const socket = client.host().unixSocket(sshAuthSockPath);

    let container = client
      .container()
      .withRegistryAuth(registry, userName, password)
      .from(rustBase)
      .withUnixSocket(sshAuthSockPath, socket)
      .withWorkdir("/app")
      .withFile("/app/Cargo.toml", client.host().file(cargoPath))
      .withFile("/app/.env", client.host().file(envPath))
      .withServiceBinding(dbHost, dbContainer)
      .withDirectory("/app/src", client.host().directory(srcFolder))
      .withDirectory(
        "/app/testing",
        client
          .host()
          .directory(testingFolder)
          .withoutDirectory("node_modules")
      )
      .withExec("bash", "-c", "npm install")

^ the above fails because it can't find the private dependency (it doesn't have access). passing the ssh key to the container and then setting it up manually, or copying node modules, does work but i was kinda hoping to avoid that, and copying dependencies like node modules isn't possible in all languages (like rust)

gloomy sigil
#

@barren sentinel that'd be a private dependecy for the npm install, correct?

gloomy sigil
#

I'm asking since I see your snippet uses a rustBase image but performs an npm install so I'm a bit lost there

barren sentinel
#

yeah, that's correct

#

it's basically an integration suite that's executing against the rust binary

#

i've also run into the same issue when the rust binary has a private dependency; this one does not.

#

so here, rust is OK, npm fails

gloomy sigil
#

can you share what's your dependecy URL format you have in your package.json?

#

since I'd assume you're not using the npm registry but directly cloning from git ?

barren sentinel
#

yes, that is what i'm doing

#

github:Calibrate-Health/pulumi

#
  "calibrate-pulumi": "github:Calibrate-Health/pulumi",
gloomy sigil
#

got it. Let me check really quick

#

do you know if github:// is supposed to use the gihub package registry? or it clones the dependecy from the source git repo directly?

#

trying to find more info about how that works to set Dagger correctly. cc @empty hatch

#

IIUC it "should" use the raw git clone approach, correct?

gloomy sigil
#

@barren sentinel this worked in my case

    sshSockPath := os.Getenv("SSH_AUTH_SOCK")

    client.Container().From("node:20").
        WithUnixSocket(sshSockPath, client.Host().UnixSocket(sshSockPath)).
        WithEnvVariable("SSH_AUTH_SOCK", sshSockPath).
        WithWorkdir("/app").
        WithExec([]string{"npm", "install", "github:marcosnils/testmodule"}).Sync(ctx)
#

marcosnils/testmodule is a private github repo

empty hatch
#

is it just that WithEnvVariable("SSH_AUTH_SOCK", sshSockPath). was missing?

gloomy sigil
barren sentinel
#

i actually had that before

#

let me try again

#

are you on OSX @gloomy sigil ?

gloomy sigil
barren sentinel
#

i'm only having this issue on OSX. if you look earlier in the thread i was discussing a magic socket; OSX seems to be particular about forwarding the ssh socket to another container. using the SSH_AUTH_SOCK method and just using ssh-agent presents me with a situation in Dagger and docker run in which i can't get the private repo, but if i run docker run with those "magic" SSH_AUTH_SOCK values it works; OSX forwards the credentials

#

it's bizarre

#

let me try one more time w/ the SSH_AUTH_SOCK and ssh-agent, i just reached a stopping point over here w/ work