GitHub - emacs-lsp/lsp-docker: Scripts and configurations to leverage lsp-mode in docker environment (original) (raw)

lsp-mode uses lsp-docker to run language servers using in containers

./images/logo.png

https://melpa.org/packages/lsp-docker-badge.svg https://stable.melpa.org/packages/lsp-docker-badge.svg https://github.com/emacs-lsp/lsp-docker/workflows/CI/badge.svg

Table of Contents

Preconfigured language servers

emacslsp/lsp-docker-langservers has the following content:

Usage

There are two ways of working with containerized language servers:

emacslsp/lsp-docker-langservers

This container is used by lsp-docker to run Language Servers for lsp-mode over local sources.You must pull the container before lsp-docker can use it

Configuration

(setq lsp-docker-client-configs
'((:server-id bash-ls :docker-server-id bashls-docker :server-command "bash-language-server start")
(:server-id clangd :docker-server-id clangd-docker :server-command "clangd")
(:server-id css-ls :docker-server-id cssls-docker :server-command "css-languageserver --stdio")
(:server-id dockerfile-ls :docker-server-id dockerfilels-docker :server-command "docker-langserver --stdio")
(:server-id gopls :docker-server-id gopls-docker :server-command "gopls")
(:server-id html-ls :docker-server-id htmls-docker :server-command "html-languageserver --stdio")
(:server-id pylsp :docker-server-id pyls-docker :server-command "pylsp")
(:server-id ts-ls :docker-server-id tsls-docker :server-command "typescript-language-server --stdio")))
(require 'lsp-docker)
(lsp-docker-init-clients
:path-mappings '(("path-to-projects-you-want-to-use" . "/projects"))
:client-packages lsp-docker-client-packages
:client-configs lsp-docker-client-configs)

How it works

lsp-mode starts the image passed as :docker-image-id and mounts :path-mappings in the container. Then when the process is started lsp-mode translates the local paths to docker path and vice versa using the :path-mappings specified when calling lsp-docker-init-default-clients. You may use lsp-enabled-clients and lsp-disabled-clients to control what language server will be used to run for a particular project(refer to lsp-mode FAQ on how to configure .dir-locals).

emacslsp/lsp-docker-full

The container emacslsp/lsp-docker-full contains:

Flags

Flag Purpose Default
EMACS_D_VOLUME Emacs folder to use for /root/.emacs Emacs: (pwd)/emacs.dSpacemacs:(pwd)/emacs.d Spacemacs: (pwd)/emacs.dSpacemacs:(pwd)/spacemacs
PROJECTS_VOLUME Directory to mount at /Projects $(pwd)/demo-projects/
TZ Timezone to user in container Europe/Minsk
DOCKER_FLAGS Any additional docker flags N/A

Emacs

Spacemacs

Clone spacemacs develop

git clone -b develop https://github.com/syl20bnr/spacemacs spacemacs

Custom language server containers

You can use manually built language containers or images hosting language server(s), just follow a few simple rules (shown below). The docker images may feature an optional tag, if omitted latest will be assumed.

Building a container (or an image) manually:

You have 2 constraints:

When you have sucessfully built a language server, you have to register it with either a configuration file or a .dir-locals file.

Registering a language server using a persistent configuration file:

A configuration file is a yaml file that can be located at:

/.lsp-docker.yml /.lsp-docker.yaml /.lsp-docker/.lsp-docker.yml /.lsp-docker/.lsp-docker.yaml /.lsp-docker/lsp-docker.yml /.lsp-docker/lsp-docker.yaml /.lsp-docker/config.yml /.lsp-docker/config.yaml

It is structured in the following way:

single server configuration

lsp: server: type: docker # subtype: # - "container": attach to an already running container # - "image": when image does not exist, try to build it based on the dockerfile found in the project-scope # (see Automatic image building). An image might feature an optional tag, i.e. ':'. If a # tagless image is indicated 'latest' will be assumed. subtype: container # Image/container name to use for this language server. name: image-container-name # server id of a registered LSP server. You can find the list of registered servers evaluating: # # (ht-keys lsp-clients) # # source: # https://stackoverflow.com/questions/17066169/retrieve-keys-from-hash-table-sorted-by-the-values-efficiently server: server-id-of-the-base-server # an (optional) array of parameters (docker or podman) to launch the image with # initially intended to host the '--userns' parameter # NOTE: 'launch_parameters' are not used with 'container' subtype servers # in this case embed all required parameters when creating the server instead launch_parameters: - "--userns=nomap" # command to launch the language server in stdio mode # NOTE: 'launch_command' is not used with 'container' subtype servers as a command is embedded in a # container itself and serves as entrypoint launch_command: "launch command with arguments" mappings: # NOTE: the paths must be within the project this server is being build for - source: "/your/host/source/path" destination: "/your/path/inside/the/container"

multiple server configuration

lsp: server: - type: ... subtype: ... ... # keys as in the classic single server case, e.g. type, subtype, etc... - ... # other single server configuration(s) mappings: # shared among all servers - source: destination: ... # other mappings

Registering a language server using a .dir-locals file:

Just refer to the source code and general conventions of using .dir-locals. The variable you need is lsp-docker-persistent-default-config, its content is merged with the lsp section from a configuration file (if present).

Automatic image building:

You can also build an image automatically (currently supported only for image subtype): just drop the corresponding Dockerfile into the .lsp-docker folder in the project root (Dockerfile may be named as Dockerfile or Dockerfile.lsp). Building process is triggered by the lsp-docker-register call (you will be prompted whether you want to build the image). Image building takes place in the project root (not in the .lsp-docker subfolder)! In case of an automatic build the image will be registered automatically (based on the values from the config or .dir-locals file).

You can also troubleshoot any issues with supplemental docker calls (checking whether the required image already exists, building a new image) using the supplemental logging functionality: there are 2 variables: first you have to set lsp-docker-log-docker-supplemental-calls to true-like value (by default it is nil) and then specify the log buffer in the lsp-docker-log-docker-supplemental-calls-buffer-name variable (by default it is set to *lsp-docker-supplemental-calls*)

Docker over TRAMP (TBD)

Docker running the language servers and hosting the sources, Emacs running on the desktop machine and connecting to docker instance over TRAMP.

See also

Maintainers