In my Dockerfile, I use Babashka like this:
RUN bb --config /my-project/bb.edn -x dev.livereload/inject
But I can’t find a way to set --config /my-project/bb.edn globally.
I expected something like this to work:
ENV BABASHKA_CONFIG=/my-project/bb.edn
RUN bb -x dev.livereload/injectMaybe set the working dir to the bb.edn project?
I haven’t figured out exactly how I want to do it yet,
but the idea is that bb -x ... will be called in different contexts, including in the entrypoint.
Setting the working directory, while it seems obvious, apparently isn’t suitable.
Another option. Make a babashka start script.clj and call babashka cli yourself. Then just call this script instead. It will default to the right config. You can also add this script to the PATH
Babashka also helpfully locates bb.edn files in parent directories to the current directory — so if all your stuff is in /app/..., you could do /app/bb.edn as the "global" bb.edn.
huh, that doesn't sound right to me
it doesn't do that
😅 I thought that was added a few years ago, but you're probably right, you made the thing!
never added that and I would be still against that
such a thing works with clj-kondo though and leiningen, perhaps you're confused with those
anyway so you script would be something like:
$project_root/myscript
#/!/usr/bin/env bb
(require '[babashka.cli :as cli] '[your.ns])
(def args (cli/parse-opts *command-line-args* ...))
(apply your.ns/your-fn args)
and then can call /my/project/myscript from everywhere while it respects bb.edn
I was wrong. I thought tasks could be run from subdirectories, they cannot.
$ pwd
/Users/teodorlu/tmp/temp-2025-09-19/bbstuff
$ cat bb.edn
{:tasks
{hello (println "Hello, Babashka!")}}
$ bb hello
Hello, Babashka!
$ mkdir -p some/sub/dir
$ cd some/sub/dir
$ pwd
/Users/teodorlu/tmp/temp-2025-09-19/bbstuff/some/sub/dir
$ bb hello
----- Error --------------------------------------------------------------------
Type: java.lang.Exception
Message: File does not exist: helloShould this work on the jvm?
(ns user
(:require [babashka.pods :as pods]))
(pods/load-pod 'org.babashka/fswatcher "0.0.7")
(require '[pod.babashka.fswatcher :as fw])
(def w (fw/watch "docs/"
(fn [event]
(tap> [:WATCH event]))
{:recursive true}))
The fw/watch call is hanging forever, and if I do cider-interrupt the stack trace is:
1. Caused by java.lang.InterruptedException
(No message)
AbstractQueuedSynchronizer.java: 1139 java.util.concurrent.locks.AbstractQueuedSynchronizer/acquireSharedInterruptibly
CountDownLatch.java: 230 java.util.concurrent.CountDownLatch/await
core.clj: 7257 clojure.core/promise/reify
core.clj: 2337 clojure.core/deref
core.clj: 2323 clojure.core/deref
impl.clj: 111 babashka.pods.impl/invoke
impl.clj: 93 babashka.pods.impl/invoke
impl.clj: 135 babashka.pods.impl/bencode->vars/fn/fnlet me check
do you have the deps.edn handy?
{:paths ["src"]
:deps {dev.weavejester/medley {:mvn/version "1.9.0"}
babashka/fs {:mvn/version "0.5.27"}
babashka/process {:mvn/version "0.6.23"}
hifi/error {:local/root "../hifi-error"}
org.clojure/tools.logging {:mvn/version "1.3.0"}
com.nextjournal/beholder {:mvn/version "1.0.3"}
babashka/babashka.pods {:mvn/version "0.2.0"}
hifi/util {:local/root "../hifi-util"}
hifi/html {:local/root "../hifi-html"}}}I'm on nixos fwiw, but since the pod is statically built I don't see any classic nix library problems
just a moment
the script isn't hanging, it's the classic behavior in clojure that when you use futures, it waits for them to complete. the watcher is still running and then the script won't exit
e.g. when I run this:
(def w (fw/watch "docs/"
(fn [event]
(tap> [:WATCH event]))
{:recursive true}))
(prn :dude w)
I see it being printedAdding this to the script will make it behave like clojure -X does:
(defn- set-daemon-agent-executor
"Set Clojure's send-off agent executor (also affects futures). This is almost
an exact rewrite of the Clojure's executor, but the Threads are created as
daemons."
[]
(let [thread-counter (atom 0)
thread-factory (reify java.util.concurrent.ThreadFactory
(newThread [_ runnable]
(doto (Thread. runnable)
(.setDaemon true) ;; DIFFERENT
(.setName (format "CLI-agent-send-off-pool-%d"
(first (swap-vals! thread-counter inc)))))))
executor (java.util.concurrent.Executors/newCachedThreadPool thread-factory)]
(set-agent-send-off-executor! executor)))
(set-daemon-agent-executor)hmmm, for me, in my clj repl, i eval the def w form and it never returns
haven't tried the REPL, do you mean CIDER or just the bare clj REPL?
sorry, I can see how my initial message made it seem like I was running it as a script file. CIDER
$ clj
Clojure 1.12.1
(ns user
(:require [babashka.pods :as pods]))
nil
(pods/load-pod 'org.babashka/fswatcher "0.0.7")
(require '[pod.babashka.fswatcher :as fw])
(def w (fw/watch "docs/"
(fn [event]
(tap> [:WATCH event]))
#:pod{:id "pod.babashka.fswatcher"}
user=> nil
user=> {:recursive true}))
#'user/wcan't reproduce with bare clj REPL. Will try CIDER now
works as expected:
Perhaps you're using the CIDER debugger or so?
clj working here too ...
let me restart the repl 😕
when the repl started i didn't have babashka.pods in the cp, i added it to the deps.edn later and evaled (clojure.repl.deps/sync-deps) in the repl to load it
and it's working 🤷
ok great
perhaps some sync-deps stuff, don't know
sorry for the noise 😞
no problem
nice to see that the pods are statically built now, i hadn't used pods in a long while because of the nixos situation
well, the fswatcher one is just a golang binary and those are static by nature
I try to make them static when possible