digineo / texd

texd wraps TeX in a web API
MIT License
8 stars 1 forks source link

Docker-in-Docker #6

Closed dmke closed 2 years ago

dmke commented 2 years ago

It is currently not possible to run texd in container mode, while texd itself is running containerized:

$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
    digineode/texd texlive/texlive:latest

This will start the texd container just fine, but fails to execute any jobs, because the job directory (/texd) only exists within the texd container and texd tries to mount it in a new container.

When started with a bind or volume mount:

$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
    -v $(pwd)/jobs:/texd \
    digineode/texd texlive/texlive:latest

executing jobs still fails, because texd basically tries to run the following command:

$ docker run --rm -v /texd/job-1234:/texd texlive/texlive:latest latexmk ...

Docker commands however are run on the Docker host, and the name of the job directory is $(pwd)/jobs/job-1234, not /texd/job-1234.

I believe, a simple rewrite mechanism for the job directory when starting job containers should suffice. Detecting whether texd runs Docker-in-Docker is a bit harder, but still doable. Given the container ID (found in /proc/1/cpuset), we can simply ask the docker daemon for the mounted directories:

# docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v texd-jobs:/texd alpine /bin/sh
# apk add curl jq
# cat /proc/1/cpuset 
/docker/2dd99cbcd5b0060f213f2e1cf701cf9741f40c98e0cc3bf70dfe77f8cef5634a
# curl --unix-socket /var/run/docker.sock http://localhost/containers/$(basename $(cat /proc/1/cpuset))/json | jq .Mounts
[
  {
    "Type": "bind",
    "Source": "/var/run/docker.sock",
    "Destination": "/var/run/docker.sock",
    "Mode": "",
    "RW": true,
    "Propagation": "rprivate"
  },
  {
    "Type": "volume",
    "Name": "texd-jobs",
    "Source": "/var/lib/docker/volumes/texd-jobs/_data",
    "Destination": "/texd",
    "Driver": "local",
    "Mode": "z",
    "RW": true,
    "Propagation": ""
  }
]

and perform a simple match of the --job-directory CLI argument against Mounts[i].Destination.