Skip to content
This repository has been archived by the owner on Apr 25, 2022. It is now read-only.

How do you use these? #1

Closed
xendk opened this issue May 13, 2021 · 12 comments
Closed

How do you use these? #1

xendk opened this issue May 13, 2021 · 12 comments

Comments

@xendk
Copy link
Contributor

xendk commented May 13, 2021

So how do you use these? As I mentioned in emacs-lsp/lsp-docker#34 I've created a script that does a docker run that mounts in a root directory at the same location in the image, sets the effective user/group to the same as the current user (to avoid file permission issues, passes select env vars ($HOME, $USER, $USERNAME and $LOGNAME so far), sets the working directory to the same as the script was run in and ensures the entrypoint is the same command.

This means that lsp-mode, flycheck and for that matter the command line thinks they're just running the usual binary. Though, I've implemented a bit of hackery in order to support commands that open a TCP port.

This has been working well for me, with some fiddling with some oddballs.

@aidalgol
Copy link
Owner

So I've been using this by first building the elixir-ls image by running

$ docker build -t elixir-ls:1.10 -f Dockerfile.elixir-ls-1.10 .

and then I put this in my Emacs init:

;; Set up LSP Docker
(add-to-list 'load-path "~/src/elisp/lsp-docker")
(load-library "lsp-docker")

(with-eval-after-load "lsp-elixir"
  (lsp-docker-init-clients
   :path-mappings '(("/home/aidan/src" . "/projects"))
   :client-configs '((:server-id elixir-ls
                      :docker-server-id elixirls-docker:1-10
                      :docker-image-id "elixir-ls:1.10"
                      :docker-container-name "lsp-elixir-container"
                      :server-command "language_server.sh"))))

;; Specify which projects should use which LSP clients.
(dir-locals-set-class-variables 'elixirls-docker:1-10
  '((nil . ((lsp-enabled-clients . (elixirls-docker:1-10))
            (eval . (add-hook 'elixir-mode-hook #'lsp))))))

(dir-locals-set-directory-class
 "/home/aidan/src/blah" 'elixirls-docker:1-10)

I didn't get as far as setting the effective UID and GID to avoid permission issues, so the .elixir_ls directory in my project directory is owned by root:root, but that should be easy to fix.

@xendk
Copy link
Contributor Author

xendk commented May 22, 2021

Ah, right, defining a new server. Seems an awful lot of boilerplate to me. My script only needs two lines in the simplest case:

  docker-langserver:
    image: rcjsuen/docker-langserver:latest

But there's some overlap in the Dockerfiles used. Take this I made for css-language-server as an example:

FROM node:current-alpine

RUN npm install -g vscode-css-languageserver-bin

ENTRYPOINT ["/usr/local/bin/css-languageserver"]

The noteworthy part is that i set the entrypoint to be the server in question, so doing a docker run on the image runs the server. So basically it's a "plug in replacement" for the original command. I hope that lsp-docker could benefit from that pattern to?

I discovered a challenge: Language servers that listens on a port. Default lsp expects to be able to connect to localhost to connect to the port, but unless you tell docker otherwise it wont map the ports per default. I have some hackery to deal with this, but I don't know how lsp-docker deals with it?

@aidalgol
Copy link
Owner

I ran into trouble with elixir-ls, with stdio breaking when run under docker. (This language server uses stdio instead of a socket.) When I asked about this in the Emacs LSP discord server, lsp-docker was recommended to me instead of trying to get the language server working with just plain lsp.el. I would much rather be able to use language servers transparently, by somehow making the dockerised language servers completely completely transparent to the client, which would also allow the effort put into this repo to be reused by other clients.

@aidalgol
Copy link
Owner

aidalgol commented May 25, 2021

As of commit 5169c63, you can just point lsp at the wrapper script for whichever version of the server you want by setting lsp-elixir-server-command. Here is how I am now setting up lsp with a dockerised elixir-ls on a per-project basis.

(dir-locals-set-class-variables 'elixirls-1-10
  '((elixir-mode .
      ((lsp-elixir-server-command . "/home/aidan/src/dockered-language-servers/elixir-ls-1.10.sh")
       (eval . (lsp))))))

(dir-locals-set-directory-class
 "/path/to/elixir-1.10-project" 'elixirls-1-10)

So I am no longer using lsp-docker.

@aidalgol
Copy link
Owner

This morning I just added a Makefile for building the images. I will try to write up a README soon, and then hopefully this repo will look more inviting to potential contributors.

@xendk
Copy link
Contributor Author

xendk commented May 25, 2021

So I am no longer using lsp-docker.

Maybe you'd be interested in my script then. I've just pushed it to https://github.com/xendk/rid. The README is sparse at the moment (as there's only been one user), and I still have some things planned (automatic building of images for instance), but I'm using it on a daily basis.

I have some images I should stick somewhere.

@aidalgol
Copy link
Owner

Cool! I've added a README and mentioned rid in it. You're welcome to submit a PR with your images if you think they're generic enough to use with any LSP client.

@xendk
Copy link
Contributor Author

xendk commented May 26, 2021

Oh, thanks.

I have a few images i could add (bash, css and typescript language servers), but how do you feel about versioning? My images just builds the latest version. I think for most language servers that makes sense.

@aidalgol
Copy link
Owner

I think just build the latest version unless there is a reason to build older versions is fine. The elixir-ls images actually fetch the latest version of the language server, but with for two different versions of Elixir, because I have a project that's tied to Elixir 1.10 (the previous release), because of some dependencies that have not updated for Elixir 1.11. I can't imagine this being an issue with either Bash or CSS, for example.

@xendk
Copy link
Contributor Author

xendk commented May 26, 2021

Sounds like an excellent plan.

How about moving the elixir related files into a elixir directory and renaming the dockerfiles Dockerfile.1.10 etc? I'd do a PR, but I don't think my Makefile-fu is strong enough for fixing the Makefile.

@xendk
Copy link
Contributor Author

xendk commented May 26, 2021

I've openend #4 to get the ball rolling, I have a few more language
servers lying around, but I need to get to bed early today (far too
long since that happenend).

Off topic: And so nice opening PRs entirely from inside Emacs.

@aidalgol
Copy link
Owner

Great! I think further discussion can move there (and to new tickets).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants