haskell / docker-haskell

MIT License
63 stars 36 forks source link

Add docker image with GHCup and/or HLS for use with devcontainers #76

Closed gusbicalho closed 1 year ago

gusbicalho commented 2 years ago

The devcontainer configuration mentioned here https://github.com/haskell/docker-haskell/issues/41 no longer works out-of-the-box because the Haskell VS Code extension now depends on GHCup to automatically install HLS.

One can still install GHCup or download the relevant HLS, but the experience is not ideal. If I install GHCup, it ends up installing another GHC and cabal 🤷

gusbicalho commented 2 years ago

This is my hand rolled solution for now:

Dockerfile

FROM debian:buster-slim

ENV LANG C.UTF-8

# common haskell + stack dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        dpkg-dev \
        git \
        gcc \
        gnupg \
        g++ \
        libc6-dev \
        libffi-dev \
        libgmp-dev \
        libnuma-dev \
        libtinfo-dev \
        make \
        netbase \
        xz-utils \
        zlib1g-dev && \
    rm -rf /var/lib/apt/lists/*

# Use the [Option] comment to specify true/false arguments that should appear in VS Code UX
#
# [Option] Install zsh
ARG INSTALL_ZSH="true"
# [Option] Upgrade OS packages to their latest versions
ARG UPGRADE_PACKAGES="false"

# Install needed packages and setup non-root user. Use a separate RUN statement to add your own dependencies
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID
COPY library-scripts/*.sh /tmp/library-scripts/
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && /bin/bash /tmp/library-scripts/common-debian.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" "true" "true"\
    && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts

USER $USERNAME

RUN mkdir -p "$HOME/.ghcup/bin"
RUN curl -LJ "https://downloads.haskell.org/~ghcup/x86_64-linux-ghcup" -o "$HOME/.ghcup/bin/ghcup"
RUN chmod +x "$HOME/.ghcup/bin/ghcup"

ENV PATH="/home/$USERNAME/.cabal/bin:/home/$USERNAME/.ghcup/bin:$PATH"

ARG GHC_VERSION="9"
RUN ghcup install ghc "${GHC_VERSION}" --set
RUN ghcup install cabal recommended --set
RUN ghcup install stack recommended --set
RUN ghcup install hls recommended --set
RUN cabal update

devcontainer.json

{
  "name": "Haskell (Community)",
  // Update the 'dockerfile' property if you aren't using the standard 'Dockerfile' filename.
  "build": {
    "dockerfile": "Dockerfile",
    "args": {
      "GHC_VERSION": "9.2.2",
      "UPGRADE_PACKAGES": "false"
    }
  },
  // Set *default* container specific settings.json values on container create.
  "settings": {
    "haskell.manageHLS": "GHCup"
  },
  // Add the IDs of extensions you want installed when the container is created.
  "extensions": [
    "haskell.haskell"
  ],
  // Use 'forwardPorts' to make a list of ports inside the container available locally.
  // "forwardPorts": [],
  // Use 'postCreateCommand' to run commands after the container is created.
  // "postCreateCommand": "uname -a",
  // Comment out to connect as root instead. To add a non-root user, see: https://aka.ms/vscode-remote/containers/non-root.
  "remoteUser": "vscode"
}
adoublef commented 2 years ago

I will be giving this a try, I have been having this issue for the past few days & wasn't sure where I was going wrong as I am just starting out with Haskell

AlistairB commented 2 years ago

Hi :wave:

Avoiding going into a bit of a can of worms.. I don't think the Haskell official images is the right place to provide a HLS or ghcup image. Those projects could still publish their own images however.

Barring that happening, I think your solution looks good. Perhaps you should PR it to https://github.com/microsoft/vscode-dev-containers?

In terms of other help, we were considering using ghcup to install GHC + friends into the official images at one point. Here is an example. Might be useful? I don't imagine you want a multi-stage build though :thinking:

Hope this helps!

gusbicalho commented 2 years ago

@AlistairB alright, I'll open a PR there. I do agree that the goal of a devcontainer image is quite different from the images in this repo - in the devcontainer it makes sense to get latest versions of GHCUP and let the extension manage everything; but that means we don't have a stable, reproducible environment.

Do you mind if I leave this issue open here until we get a working Dockerfile merged in the devcontainer repo? It might help other people like myself and @topheruk discover the problem/workaround

gusbicalho commented 2 years ago

PR open: https://github.com/microsoft/vscode-dev-containers/pull/1478

adoublef commented 2 years ago

I've noticed one issue which that creating a new stack project, the lib module inside the src directory doesn't seem to be recognized in the main HS file. It does compile just VSCode gives error. A new cabal project I don't have these issues tho

AlistairB commented 1 year ago

I guess we can close this as the PR is merged.