haskell / docker-haskell

MIT License
63 stars 37 forks source link

Create an official devcontainer docker image with haskell-language-server #41

Closed jneira closed 2 years ago

jneira commented 3 years ago

//cc @ndmitchell @emilypi @hmemcpy

AlistairB commented 3 years ago

So I think if this were to live in an official Haskell image, it would be separate from the core image that is provided. Ie. it might live under haskell:8.10.4-hls. This way the core image is not bloated for users that don't need HLS embedded in it.

The next question is should the image live in this repo and be an official Haskell image variant, or should it live in HLS repo?

Personally, I'm inclined to think it should live with HLS and be published to a separate docker image ie. haskell-langauge-server/haskell-language-server:8.10.4. (But perhaps use the official Haskell image as a base image)

The reason is that such an image is tightly coupled to HLS itself. As HLS is developed, I would imagine that would impact what goes in this image. So you might adjust HLS code and update the image in a single PR (that CI can verify).

Having said that, I know little about how HLS works :sweat_smile: I'm curious why it might be good for an HLS image to be an official Haskell image variant?

Another question, would you want to embed the HLS executable in the image? Or would you just have it auto download? If it is the former, that would further tie it to the HLS release process.

//cc @psftw

jneira commented 3 years ago

it might live under haskell:8.10.4-hls. This way the core image is not bloated for users that don't need HLS embedded in it.

totally agree

Having said that, I know little about how HLS works sweat_smile I'm curious why it might be good for an HLS image to be an official Haskell image variant?

Well, host the hls image could have some interesting advantages:

Another question, would you want to embed the HLS executable in the image? Or would you just have it auto download? If it is the former, that would further tie it to the HLS release process.

jneira commented 3 years ago

Usually we are taking a look on what rust is doing and it seems they dont have a devcontainer in their docker official account: https://hub.docker.com/_/rust That image is hosted directly by microsoft instead: https://github.com/microsoft/vscode-remote-try-rust That alternative is not bad either :smile: but dont know how we could suggest ms add a vscode-remote-try-haskell here: https://github.com/microsoft?q=vscode-try&type=&language=&sort=

jneira commented 3 years ago

That alternative is not bad either :smile: but dont know how we could suggest ms add a vscode-remote-try-haskell here:

Maybe @Chuxel could help us with that? :slightly_smiling_face:

AlistairB commented 3 years ago

it would be easily discoverable and would have the official haskell.org™ stamp

Yes, this seems like the biggest benefit to me.

The vscode extension downloads automatically the last available hls version suited for the ghc version of the project at hand so only the extension would be enough (and save space as we will not download all hls * ghc version matrix)

I think this doesn't work so well with the way the current images work. Each image tag is a specific version ie. haskell:8.10.4 and is configured to use the system ghc and not download new versions.

I think for this to work you would want an image that just installs stack / ghcup, then ghc + hls versions can be installed as needed. I guess the downside of this approach is the user needs to install new ghc versions? Or perhaps ghc doesn't need to be in the container, just the hls executable?

For https://github.com/vzarytovskii/haskell-dev-env/blob/master/.devcontainer/Dockerfile the image is hardcoded to a specific version.

Alternatively it might be easier to just have hls docker image variants for different GHC versions and the user can switch between them as they change projects.

BTW, I'm just a newbie maintainer on this repo, @psftw is the long time maintainer.

EDIT: vscode-remote-try-haskell could be cool!

jneira commented 3 years ago

I think for this to work you would want an image that just installs stack / ghcup, then ghc + hls versions can be installed as needed. I guess the downside of this approach is the user needs to install new ghc versions? Or perhaps ghc doesn't need to be in the container, just the hls executable?

Mmm i see, thanks for noting it. What about to have hls over the image with the lastest ghc version full supported by hls itself (currently 8.10.5), put the hls-8.10.5 executable in PATH and let users download other ghc's on demand using ghcup? (btw ghcup could be used to download hls too but users could choose use it or the automatic download provide by the vscode extension)

AlistairB commented 3 years ago

What about to have hls over the image with the lastest ghc version full supported by hls itself (currently 8.10.5), put the hls-8.10.5 executable in PATH and let users download other ghc's on demand using ghcup? (btw ghcup could be used to download hls too but users could choose use it or the automatic download provide by the vscode extension)

The challenge with not baking everything you need into the container is you want to avoid re-downloading / installing additional stuff. Naively if you don't do anything, when the container shuts down it loses any changes that are not baked into the image. So you would need to reinstall other ghc versions / hls executables you had downloaded after starting the container.

The way docker solves this is with volumes that persist data between container runs, but they can be finicky. So I'm not sure if this is a good option.

I'd probably instead have something like:

jneira commented 3 years ago

Oh, yeah, i forgot containers dont persist anything by default, thanks for noting it

I'd probably instead have something like:

that sound sensible

Chuxel commented 3 years ago

As a FYI, someone did contribute a PR on Haskel here: https://github.com/microsoft/vscode-dev-containers/pull/685

If this is good, we could merge it and it would be in the "Add Dev Container Configuration Files" UX in VS Code and Codespaces. Or if you'd prefer a different image is used, we could add that. We bundle up everything in this repository once a month (if not more often) and publish it in the products and community contributions are welcome.

There's also a "common-debian.sh" script we typically run that makes terminal a bit more user friendly since the typical production focused Docker image is intentionally thin. Any of this could be pre-built into an image. We do have a pre-built base image with this already done as well as a drop-in replacement for base debian or ubuntu. mcr.microsoft.com/vscode/devcontainers/base:buster (or stretch, focal, bionic and soon bullseye).

Generally we host images at mcr.microsoft.com if they're ones the VS Code and Codespaces teams are managing, but there's no requirement that it has to be here as long as the image comes from "official sources" rather than personal accounts.

The way these work is that a bind mount or volume is used to map in source code so it survives an image build.

jneira commented 3 years ago

@Chuxel many thanks for take care and your insights I am taking a look to the pr you mentioned but i am not a docker expert, @AlistairB could you take a look to check if it is fine?

stuartpike commented 3 years ago

@jneira and @AlistairB the PR microsoft/vscode-dev-containers#685 I raised is based on the docker hub image '8.10.4' using tag '8'. Also I've adopted the "common-debian.sh" which @Chuxel mentioned to improve the terminal.

Chuxel commented 3 years ago

Reviewed microsoft/vscode-dev-containers#685 and made some comments. I should also say that the discussion of pre-building some of this into an image is also a good one. That won't happen automatically for the vscode-dev-containers repo. That said, a Dockerfile build will happen automatically - it just is usually faster if an image is pulled instead.

psftw commented 3 years ago

The PR above was merged, and based on a quick look, it seems reasonable to me. As mentioned above, VSCode handles the HLS install at runtime, so the diff between the official image and a "devcontainer" is a thin layer of common packages/configuration. This seems to be working as expected with the devcontainer being an independently maintained downstream image. Finding the right balance of what to publish under the haskell image name can be tricky. Is there a good use-case or demand for releasing a haskell:8-hls that bundled the appropriate GHC-matched release? Wouldn't VSCode still want to install the latest using the logic built into the extension? My understanding is that HLS is a generic backend designed to pair up with IDEs and other tools, but does it make sense to bundle on its own?

jneira commented 3 years ago

@psftw thanks for take a look to the merged devcontainer.

This seems to be working as expected with the devcontainer being an independently maintained downstream image.

Yeah and that downstream image already exists after the mentioned pr. I still see some value in host that downstream image in an place clearly associated with haskell like this and not only microsoft, to help its discovery. Needed changes in the image will be easier to do if it lives here (i hope so! 😄), as all tools and dev teams involved live under the haskell github/haskell.org umbrella.

Is there a good use-case or demand for releasing a haskell:8-hls that bundled the appropriate GHC-matched release? Wouldn't VSCode still want to install the latest using the logic built into the extension? My understanding is that HLS is a generic backend designed to pair up with IDEs and other tools, but does it make sense to bundle on its own?

Well, the idea was include ghc, hls matching version on PATH and vscode (or vscodium) with the extensions already installed. The extension honours the hls executable in PATH as first option and anyways, as there is only one ghc in the system, it would not need another hls version. That devcontainer could be used to start a project really fast, as all pieces will be preinstalled.