@@ -191,7 +191,7 @@ contains some combination of project.clj, build.boot and deps.edn and you want
191191to launch a REPL for one or the other.
192192
193193NOTE: The examples use only `cider-jack-in`, but this behavior is consistent
194- for all `cider-jack-in-*` commands.
194+ for all `cider-jack-in-\ *` commands.
195195
196196You can further customize the command line CIDER uses for `cider-jack-in` by
197197modifying the some options. Those differ a bit between the various tools,
@@ -321,7 +321,7 @@ reads for the host and port prompts when you invoke
321321== Working with Remote Hosts
322322
323323While most of the time you'd be connecting to a locally running nREPL
324- server, that was started manually or via `cider-jack-in-*`, there's
324+ server, that was started manually or via `cider-jack-in-\ *`, there's
325325also the option to connect to remote nREPL hosts. For the sake of security
326326CIDER has the ability to tunnel a connection over SSH in such cases.
327327This behavior is controlled by
@@ -336,7 +336,7 @@ WARNING: As nREPL connections are insecure by default you're encouraged to use o
336336tunneling when connecting to servers running outside of your network.
337337
338338There's a another case in which CIDER may optionally leverage the `ssh` command - when
339- trying to figure out potential target hosts and ports when you're doing `cider-connect-*`.
339+ trying to figure out potential target hosts and ports when you're doing `cider-connect-\ *`.
340340If `cider-infer-remote-nrepl-ports` is true, CIDER will use ssh to try to infer
341341nREPL ports on remote hosts (for a direct connection). That option is also set to `nil`
342342by default.
@@ -346,11 +346,91 @@ https://www.gnu.org/software/tramp/[TRAMP] for some SSH operations, which parses
346346config files such as `~/.ssh/config` and `~/.ssh/known_hosts`. This is known to
347347cause problems with complex or nonstandard ssh configs.
348348
349- You can safely run `cider-jack-in-*` while working with remote files over TRAMP. CIDER
350- will reuse existing SSH connection's parameters (like port and username) for establishing SSH tunnel.
351- The same will happen if you try to `cider-connect-*` to a host that matches the one you're currently
349+ You can run `cider-jack-in-\ *` while working with remote files over TRAMP. CIDER
350+ will reuse existing SSH connection's parameters (like port and username) for establishing a SSH tunnel.
351+ The same will happen if you try to `cider-connect-\ *` to a host that matches the one you're currently
352352connected to.
353353
354+ NOTE: For Docker containers, running `cider-jack-in-\*` over TRAMP may technically work but it may give mixed results.
355+ Please check out the following section for the recommended approaches.
356+
357+ == Working with Containers (Docker or others)
358+
359+ By 'containers' we mean Docker containers, or similar technologies, for running the JVM that will host our nREPL server.
360+ The files which we edit may / may not be edited using TRAMP. They could as well be mounted inside the container, so they appear as local.
361+
362+ Because CIDER can't always detect if it's dealing with remote files, it's advisable to not rely on `cider-jack-in`
363+ and its remote support described above, but to
364+ start the nREPL server via command line from inside the container, and `cider-connect` to it.
365+
366+ This requires to first get a shell inside the running container and then start a nREPL server manually,
367+ or configure the container to start an nREPL automatically when the container starts.
368+
369+ In order to connect Emacs to nREPL, we need to make sure that the port of nREPL is reachable to our local Emacs,
370+ so that we can `cider-connect` to it.
371+ There are several solutions for this depending on the concrete scenario.
372+
373+ === Working with Containers running on localhost
374+
375+ The nREPL port should be set to a fixed value as we need to give this during the `docker start` command in order to forward the port from
376+ container to host. This requires as well that nREPL server listens to "0.0.0.0" and not only to "localhost".
377+
378+ === Working with Containers running on remote hosts
379+
380+ In case we have the container running on a remote machine, we need to do the same setup as above and additionally use `ssh`
381+ to forward the already-forwarded port again to our local machine.
382+
383+ This can be done using a command such as "ssh -L 12345:localhost:12345 remote-server",
384+ assuming that 12345 was the nREPL port exposed by the container.
385+
386+ === Working with devcontainers locally or remotely
387+
388+ https://containers.dev[Development Containers] is a standard to describe container-based development environments. It includes a CLI.
389+ It uses Docker/Podman behind the scenes. So the principles of making sure that the nREPL port becomes available stay the same,
390+ but there are slightly different ways to configure this (given by the devcontainer standard).
391+
392+ There are several CLI tools to manage devcontainers, as there are several container technologies. The following example uses
393+ link:https://github.com/devcontainers/cli[the devcontainers cli], but there are others (devpod, gitpod...).
394+
395+ ==== Example: Working with containers (using `devcontainer`) on a remote server
396+
397+ In this scenario and assuming a folder `/home/me/my-clj-code` containing the relevant `devcontainer` related config files
398+ (devcontainer.json) we can first start remotely a devcontainer via:
399+
400+ [source,sh]
401+ ----
402+ # executed on MY_REMOTE_SERVER
403+ devcontainer up --workspace-folder /home/me/my-clj-code
404+ ----
405+
406+ Then we can start a nREPL server inside the container on the remote host as shown below (executed from from your local machine).
407+ The command tunnels as well the remote port 12345 to local machine on port 12345:
408+
409+ [source,sh]
410+ ----
411+ ssh -t -L 12345:localhost:12345 MY_REMOTE_SERVER \
412+ devcontainer exec --workspace-folder /home/me/my-clj-code \
413+ "clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version \"0.8.3\"} cider/cider-nrepl {:mvn/version \"0.25.5\"}}}' -m nrepl.cmdline -p 12345 -b 0.0.0.0 --middleware '[\"cider.nrepl/cider-middleware\"]' "
414+ ----
415+
416+ For this to work, we need as well to configure `devcontainer.json` with a snippet that exposes port `12345` from the container to the (remote) host:
417+
418+ [source,json]
419+ ----
420+ "appPort": [
421+ // will make container port 12345 available as 12345 on remote host
422+ // (which will be further tunneled to 12345 on local machine)
423+ "12345:12345"
424+ ],
425+ ----
426+
427+ This results then in having port 12345 available locally and we can `cider-connect` to it, using `localhost:12345`.
428+ Editing of the files can then happen via TRAMP. As the files are "on the remote machine"
429+ and also mounted inside the container on the remote machine, we have two possible TRAMP file syntaxes to edit them - either of:
430+
431+ * `/ssh:MY_REMOTE_SERVER:/home/me/my-clj-code/...`
432+ * `/ssh:MY_REMOTE_SERVER|docker:DOCKER_CONTAINER_ID:/workspaces/my-clj-code/...`
433+
354434== Connecting via unix domain file socket
355435
356436NOTE: Unix socket support was introduced in nREPL 0.9. Currently
0 commit comments