DEV Community

Theodor Heiselberg
Theodor Heiselberg

Posted on

Run Elm in a devcontainer on apple silicon

The problem:
Your precious devcontainer - meant to run on every conceivable OS - won't run on your new MacBook!

Let's fix this!
Use this dockerfile:

FROM mcr.microsoft.com/devcontainers/javascript-node:20

# Configuring Elm version
ARG ELM_VERSION=latest-0.19.1
ARG ELM_TEST_VERSION=latest-0.19.1
ARG ELM_FORMAT_VERSION=latest-0.19.1

# This Dockerfile adds a non-root user with sudo access. Update the “remoteUser” property in
# devcontainer.json to use it. More info: https://aka.ms/vscode-remote/containers/non-root-user.
ARG USERNAME=node
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Install elm using the provided method, elm-test and elm-format via npm
RUN export DEBIAN_FRONTEND=noninteractive \
    # Install Elm binary
    && curl -L -o elm.gz https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz \
    && gunzip elm.gz \
    && chmod +x elm \
    && mv elm /usr/local/bin/elm \
    #
    # Install elm-test and elm-format via npm
    && sudo -u ${USERNAME} npm install --global \
    elm-test@${ELM_TEST_VERSION} \
    elm-format@${ELM_FORMAT_VERSION} \
    #
    # [Optional] Update UID/GID if needed
    && if [ "$USER_GID" != "1000" ] || [ "$USER_UID" != "1000" ]; then \
        groupmod --gid $USER_GID $USERNAME \
        && usermod --uid $USER_UID --gid $USER_GID $USERNAME \
        && chown -R $USER_UID:$USER_GID /home/$USERNAME; \
    fi \
    # Create the elm cache directory where we can mount a volume
    && mkdir /home/$USERNAME/.elm \
    && chown $USERNAME:$USERNAME /home/$USERNAME/.elm

# Install elm-test, elm-format, elm-watch, and git globally via npm
RUN npm install -g elm-test elm-format elm-watch elm-live git
Enter fullscreen mode Exit fullscreen mode

You can still use the community provided devcontainer.json

{
    "name": "Elm (Community)",
    "dockerFile": "Dockerfile",
    // In order to make elm-watch pick up changes
    "containerEnv": {
        "CHOKIDAR_USEPOLLING": "true"
    },
    // Configure tool-specific properties.
    "customizations": {
        // Configure properties specific to VS Code.
        "vscode": {
            // Add the IDs of extensions you want installed when the container is created.
            "extensions": [
                "Elmtooling.elm-ls-vscode",
                "ritwickdey.LiveServer",
                "streetsidesoftware.code-spell-checker",
                "GitHub.copilot-chat",
                "GitHub.copilot",
                "eamodio.gitlens"
            ]
        }
    },
    "forwardPorts": [
    ],
    "remoteUser": "node",
    "mounts": [
        "source=vscode-devcontainer-elm-dependency-cache,target=/home/node/.elm,type=volume"
    ]
}
Enter fullscreen mode Exit fullscreen mode

Getting stuff done

(>> means run in the terminal)

  1. Run devcontainer
  2. >>elm init
  3. crate a folder named 'wwwroot' in the root of the project
    • This folder contains the sites dependencies and must be deployed to the server
  4. Add this line to .vscode/settings.json: "liveServer.settings.root": "/wwwroot"
    • This will make elm serve the wwwroot folder as root of the server
  5. Add a file named 'index.html' in wwwroot and add the following code:
<body>
    <h1>elm-the-complete-guide-navigation</h1>
    <div class="content"></div>
    <!--#todo: Fix cache busting by making the version update with each deploy-->
    <script src="elm.js?v=1.0.0.2"></script>
    <script>
        Elm.Main.init({ node: document.querySelector('.content') });
    </script>
</body>
Enter fullscreen mode Exit fullscreen mode
  1. Run >>npm install elm-live
  2. Run >>elm-watch hot
  3. Open 'wwwroot/index.html' using the live server

Image description

Top comments (0)