Using Helix Editor with a Dockerized Python LSP
Running a LSP in a docker container definitely keeps your operating system clean from all dependencies required to run LSPs. Additionally that allows you to run and configure different LSPs in different containers for different projects.
The next section lists all files that you can set up to run a dockerized Python LSP that helix will connect to when editing Python files in your current project. All mentioned file paths are relative to your project’s root directory.
Set up these files in your project directory
pylsp/Dockerfile
FROM python:3.11-slim-bookworm
RUN pip install python-lsp-server[all]
CMD ["pylsp"]
docker-compose.yaml
services:
pylsp:
build:
context: ./pylsp
profiles:
- pylsp
volumes:
- ./:${ROOT_DIR}/
Assigning a profile
ensures that the pylsp
service doesn’t auto-start together with your project’s regular docker stack. Instead the pylsp
service is started and stopped by helix whenever you open helix inside your project directory.
Run docker compose build pylsp
to initially create the LSP service container.
Makefile
/ .env
.env:
echo "ROOT_DIR=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))" | tee .env
The language server container needs your local project root directory mapped to the very same path inside the container, independently of the project’s (sub-)directory from which you start the helix editor. Otherwise you run into directory mapping problems such as described in this helix github issue.
To address this we will keep a .env
file around which we populate with your project’s root directory. This file is best created once from above Makefile
by running make .env
in your project’s root dir. By adjusting the volume mapping to the actual project path every developer can now check out your project at a different location in their file system.
In case you’ve moved your project elsewhere later, simply delete .env
and rerun make .env
.
Do not commit .env
and instead add .env
to the project’s .gitignore
as this file is developer machine specific.
.helix/languages.toml
[[language]]
language-servers = ["pylsp"]
name = "python"
[language-server.pylsp]
args = ["compose", "run", "--build", "--rm", "pylsp"]
command = "docker"
Now the LSP container is started whenever you open helix in your project directory. The container will also nicely stop whenever you quit helix.
You could also configure LSP plugins such as flake8
via above .helix/languages.toml
but that should rather be done inside pyproject.toml
.
Choose different LSP plugins
Above setup installs the default plugins. You may however opt to use different plugins such as the great ruff
plugin. Therefore add pip install python-lsp-ruff
to the above Dockerfile
and replace python-lsp-server[all]
with python-lsp-server
.
To install the mypy plugin add pip install pylsp-mypy
to the Dockerfile
.
Subscribe to my newsletter
Read articles from Lars Blumberg directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Lars Blumberg
Lars Blumberg
Full stack developer, CTO and CEO of tech startups.