Skip to content

Commit c5efd5e

Browse files
authored
Merge pull request #220 from docker/slim/0.0.15
Slim/0.0.15
2 parents 08528e6 + ea460d0 commit c5efd5e

File tree

12 files changed

+123
-68
lines changed

12 files changed

+123
-68
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@
2626
.idea
2727
/catalog.updated.yaml
2828
claude_desktop_config.json
29+
/set-secrets.sh

dev/containers.clj

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(ns containers
2+
(:require [docker]))
3+
4+
(->> (docker/containers {})
5+
(map #(select-keys % [:Names :Status :State :Id :Image])))
6+
7+
'(:Ports
8+
:Image
9+
:Labels
10+
:Id
11+
:Mounts
12+
:HostConfig
13+
:Command
14+
:ImageID
15+
:Names
16+
:State
17+
:Created
18+
:NetworkSettings
19+
:Status)

dev/stdio_client.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131

3232
(def server (process/process
3333
{:out :stream :in :stream}
34-
"docker" "run" "-i" "--rm" "--workdir=/app"
35-
"mcp/discord:latest"))
34+
"docker" "run" "-i" "--workdir=/app"
35+
"--label=x-secret:stripe.secret_key=/secret/stripe.secret_key"
36+
"--entrypoint" "/bin/sh -c \"export STRIPE_SECRET_KEY=$(cat /secret/stripe.secret_key); node /app/dist/index.js --tools=all;\""
37+
"mcp/stripe:latest")))
3638

3739
(async/thread
3840
(loop []
46.3 KB
Loading

runbook.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ docker pull mcp/docker:prerelease
2020

2121
```sh
2222
# docker:command=build-release
23-
VERSION="0.0.14"
23+
VERSION="0.0.15"
2424
docker buildx build \
2525
--builder hydrobuild \
2626
--platform linux/amd64,linux/arm64 \
@@ -45,11 +45,12 @@ clj -M:main-repl serve --mcp --port 8811
4545
```sh
4646
docker run --rm -i --pull always -q --init \
4747
-v /var/run/docker.sock:/var/run/docker.sock \
48+
-v /run/host-services/backend.sock:/backend.sock \
4849
--mount type=volume,source=docker-prompts,target=/prompts \
4950
-p 8811:8811 \
50-
mcp/docker:0.0.1 \
51-
serve --mcp --port 8811 \
52-
--register "github:docker/labs-ai-tools-for-devs?path=prompts/bootstrap.md"
51+
-e "GATEWAY_CONTAINER_RM=false" \
52+
mcp/docker:0.0.15 \
53+
serve --mcp --port 8811
5354
```
5455

5556
```sh

src/docker.clj

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@
7777
(format "%s/Library/Containers/com.docker.docker/Data/backend.sock" (System/getenv "HOME"))]]
7878
(some unix-socket-file coll)))
7979

80+
(defn- get-jfs-socket []
81+
(let [coll [(or (System/getenv "JFS_SOCKET_PATH") "/jfs.sock")
82+
(format "%s/Library/Containers/com.docker.docker/Data/jfs.sock" (System/getenv "HOME"))]]
83+
(some unix-socket-file coll)))
84+
85+
(defn jfs-get-secret [s]
86+
(curl/get
87+
(format "http://localhost/secrets/%s" s)
88+
{:raw-args ["--unix-socket" (get-jfs-socket)]
89+
:throw false}))
90+
8091
(defn backend-is-logged-in? [_]
8192
(curl/get
8293
"http://localhost/registry/is-logged-in"
@@ -228,7 +239,7 @@
228239

229240
(defn inspect-image [{:keys [Name Id]}]
230241
(curl/get
231-
(format "http://localhost/images/%s/json" (or Name Id))
242+
(format "http://localhost/images/%s/json" (or Name Id))
232243
{:raw-args ["--unix-socket" "/var/run/docker.sock"]
233244
:throw false}))
234245

@@ -310,6 +321,7 @@
310321
(def pull (comp (status? 200 "pull-image") pull-image))
311322
(def images (comp ->json list-images))
312323
(def containers (comp ->json (status? 200 "list-containers") list-containers))
324+
(def secrets-get (comp ->json (status? 200 "secrets-get") jfs-get-secret))
313325

314326
(defn add-latest [image]
315327
(let [[_ tag] (re-find #".*(:.*)$" image)]
@@ -367,25 +379,34 @@
367379
[s])
368380
(string/join " ; ")))
369381

382+
(defn get-secrets [{:keys [secrets]}]
383+
(->> secrets
384+
(map (fn [[k v]]
385+
[v (:value (secrets-get (name k)))]))
386+
(into {})))
387+
370388
(defn inject-secret-transform [container-definition]
371389
(check-then-pull container-definition)
372-
(let [{:keys [Entrypoint Cmd Env]}
390+
(let [{:keys [Entrypoint Cmd Env User]}
373391
(->
374392
(image-inspect {:Name (:image container-definition)})
375393
:Config)
376394
real-entrypoint (string/join " " (concat
377395
(or (:entrypoint container-definition) Entrypoint)
378396
(or (:command container-definition) Cmd)))]
379-
(-> container-definition
380-
(assoc :entrypoint ["/bin/sh" "-c" (injected-entrypoint
381-
(:secrets container-definition)
382-
(concat
383-
Env
384-
(->> (:environment container-definition)
385-
(map (fn [[k v]] (format "%s=%s" (if (keyword? k) (name k) k) v)))
386-
(into [])))
387-
real-entrypoint)])
388-
(dissoc :command))))
397+
(if (#{"" "root"} User)
398+
(-> container-definition
399+
(assoc :entrypoint ["/bin/sh" "-c" (injected-entrypoint
400+
(:secrets container-definition)
401+
(concat
402+
Env
403+
(->> (:environment container-definition)
404+
(map (fn [[k v]] (format "%s=%s" (if (keyword? k) (name k) k) v)))
405+
(into [])))
406+
real-entrypoint)])
407+
(dissoc :command))
408+
(-> container-definition
409+
(update :environment (fnil merge {}) (get-secrets container-definition))))))
389410

390411
(defn run-streaming-function-with-no-stdin
391412
"run container function with no stdin, and no timeout, but streaming stdout"
@@ -402,18 +423,22 @@
402423
finished-channel (async/promise-chan)]
403424
(start x)
404425

405-
(async/go
406-
(try
407-
(let [s (:body (attach-container-stream-stdout x))]
408-
(doseq [line (line-seq (java.io.BufferedReader. (java.io.InputStreamReader. s)))]
409-
(cb line)))
410-
(catch Throwable e
411-
(println e))))
426+
(.start ^Thread
427+
(Thread.
428+
(fn []
429+
(try
430+
(let [s (:body (attach-container-stream-stdout x))]
431+
(doseq [line (line-seq (java.io.BufferedReader. (java.io.InputStreamReader. s)))]
432+
(cb line)))
433+
(catch Throwable e
434+
(logger/error "run-streaming-function" e))))))
412435

413436
;; watch the container
414-
(async/go
415-
(wait x)
416-
(async/>! finished-channel {:done :exited}))
437+
(.start ^Thread
438+
(Thread.
439+
(fn []
440+
(wait x)
441+
(async/put! finished-channel {:done :exited}))))
417442

418443
{:container x
419444
;; stopped channel
@@ -547,10 +572,13 @@
547572
(let [header-buf (ByteBuffer/allocate 8)
548573
stdout (PipedOutputStream.)
549574
stdout-reader (io/reader (PipedInputStream. stdout))]
550-
(async/go-loop []
551-
(when-let [line (.readLine stdout-reader)]
552-
(async/put! c {:stdout line})
553-
(recur)))
575+
(.start ^Thread
576+
(Thread.
577+
(fn []
578+
(loop []
579+
(when-let [line (.readLine stdout-reader)]
580+
(async/put! c {:stdout line})
581+
(recur))))))
554582
(loop [offset 0]
555583
(let [result (.read ^SocketChannel in header-buf)]
556584
(cond
@@ -656,7 +684,10 @@
656684
c (async/chan)
657685
output-channel (async/chan)]
658686
(start x)
659-
(async/thread (read-loop socket-channel c))
687+
(.start ^Thread
688+
(Thread.
689+
(fn []
690+
(read-loop socket-channel c))))
660691
(async/go
661692
(docker/wait x)
662693
(async/>! c :stopped)

src/extension/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# IMAGE?=docker/labs-ai-tools-for-devs
22
IMAGE?=docker/labs-ai-tools-for-devs
3-
TAG?=0.2.56
3+
TAG?=0.2.60
44

55
BUILDER=buildx-multi-arch
66

src/extension/docker-compose.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
services:
22
mcp_docker:
3-
image: mcp/docker:0.0.14
3+
image: mcp/docker:0.0.15
44
ports:
55
- 8811:8811
66
volumes:
77
- "/var/run/docker.sock:/var/run/docker.sock"
88
- "/run/host-services/backend.sock:/backend.sock"
9+
- "/run/guest-services/jfs.sock:/jfs.sock"
910
- "docker-prompts:/prompts"
1011
command:
1112
- serve

src/jsonrpc.clj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
:error (binding [*out* *err*]
134134
(println (:content params)))
135135
:prompts nil
136+
:start nil
136137
(binding [*out* *err*] (println (format "%s\n%s\n" method params)))))
137138

138139
(defn create-stdout-notifier [{:keys [debug]}]

src/jsonrpc/prompt_change_events.clj

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,28 @@
6060
:unknown)
6161
(recur (async/<! debounced)))
6262
;; watch filesystem
63-
(async/thread
64-
(let [{x :container}
65-
(docker/run-streaming-function-with-no-stdin
66-
{:image "vonwig/inotifywait:latest"
67-
:labels {"com.docker.desktop.service" "true"}
68-
:volumes ["docker-prompts:/prompts"]
69-
:command ["-e" "create" "-e" "modify" "-e" "delete" "-q" "-m" "/prompts"]}
70-
(fn [line]
71-
(let [[_dir _event f] (string/split line #"\s+")]
72-
(async/>!!
73-
change-events-channel
74-
(cond
75-
(= f "registry.yaml")
76-
{:opts opts :f f :type :registry}
77-
(string/ends-with? f ".md")
78-
{:opts opts :f f :type :markdown}
79-
:else
80-
{})))))]
81-
(shutdown/schedule-container-shutdown
82-
(fn []
83-
(logger/info "inotifywait shutting down")
84-
(docker/kill-container x)
85-
(docker/delete x)))))))
63+
(let [{x :container}
64+
(docker/run-streaming-function-with-no-stdin
65+
{:image "vonwig/inotifywait:latest"
66+
:labels {"com.docker.desktop.service" "true"}
67+
:volumes ["docker-prompts:/prompts"]
68+
:command ["-e" "create" "-e" "modify" "-e" "delete" "-q" "-m" "/prompts"]}
69+
(fn [line]
70+
(let [[_dir _event f] (string/split line #"\s+")]
71+
(async/put!
72+
change-events-channel
73+
(cond
74+
(= f "registry.yaml")
75+
{:opts opts :f f :type :registry}
76+
(string/ends-with? f ".md")
77+
{:opts opts :f f :type :markdown}
78+
:else
79+
{})))))]
80+
(shutdown/schedule-container-shutdown
81+
(fn []
82+
(logger/info "inotifywait shutting down")
83+
(docker/kill-container x)
84+
(docker/delete x))))))
8685

8786
(comment
8887
(repl/setup-stdout-logger)

0 commit comments

Comments
 (0)