DEV Community

Theodor Heiselberg
Theodor Heiselberg

Posted on

Run Elm and lunarvim in a devcontainer

Let's use docker-compose

As your project grows you'll need eg. sql, nginx etc.
This setup will prepare your project for this.
Image description

This dev-environment is using elm-watch.

.devcontainer/d-c-lunarvim.yml

name: d-c-lunarvim-x

services:
  lvim:
    build:
      context: .
      dockerfile: Dockerfile.lunarvim
    networks:
      - internal  # Ensure DevContainer connects to the same network
    volumes:
      - lvim-cs-dependency-cache:/home/lunaruser/.elm
      - ..:/workspace
    command: ["sleep", "infinity"]

volumes:
  lvim-cs-dependency-cache:

networks:
  internal:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode

.devcontainer/devcontainer.json

{
    "name": "lunarvim-devcontainer",
    "service": "lvim",
    "dockerComposeFile": "d-c-lunarvim.yml",
    "mounts": [
        "source=${localEnv:HOME}/.bashrc,target=/home/lunaruser/.bashrc,type=bind",
        "source=lvim-cs-dependency-cache,target=/home/lunaruser/.elm,type=volume"

      ],
    "workspaceFolder": "/workspace",
    // 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",
                "elmTooling.elm-ls-vscode",
                "kisstkondoros.vscode-gutter-preview",
                "mongodb.mongodb-vscode"
            ]
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

.devcontainer/Dockerfile.lunarvim

# Use a stable version of Alpine as the base image
FROM alpine:3.20.3

# Set up the working directory
WORKDIR /tmp

# Set environment variables
ENV HOME_DIR="/home/lunaruser"
ENV LV_BRANCH="release-1.4/neovim-0.9"
ENV PATH="$PATH:$HOME_DIR/.local/bin"

# Install dependencies
RUN apk update && \
    apk add --no-cache \
        yarn \
        git \
        python3 \
        cargo \
        neovim \
        ripgrep \
        alpine-sdk \
        bash \
        curl \
        nodejs \
        npm \
        sudo \
        libc6-compat  # Install if needed for compatibility with Elm binaries

# 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.
ARG USERNAME=lunaruser
ARG USER_UID=1000
ARG USER_GID=$USER_UID

# Add a non-root user and group
RUN addgroup -S $USERNAME && \
    adduser -S $USERNAME -G $USERNAME --shell /bin/sh

# 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
    npm install --global \
        elm-test@${ELM_TEST_VERSION} \
        elm-format@${ELM_FORMAT_VERSION} \
        elm-watch@beta && \
    # [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

# Switch to the non-root user
USER $USERNAME

# Run LunarVim installation as the non-root user
RUN curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/$LV_BRANCH/utils/installer/install.sh | \
    bash -s -- --no-install-dependencies

# Define the volume for the .bashrc file
VOLUME /home/lunaruser/

# Set default command to open LunarVim - when running directly in a docker container
# CMD ["/home/lunaruser/.local/bin/lvim"]
Enter fullscreen mode Exit fullscreen mode

Personal preferences:
.vscode/settings.json

{
    "liveServer.settings.root": "/wwwroot",
    "editor.formatOnSave": true,
    "files.autoSave": "onFocusChange",
    "editor.defaultFormatter": "elmTooling.elm-ls-vscode"
}
Enter fullscreen mode Exit fullscreen mode

Run elm-format on save

Open the config.

Image description

~/.config/lvim/config.lua

lvim.format_on_save.enabled = true
lvim.format_on_save.allow_filetypes = { "elm" }

local formatters = require ("lvim.lsp.null-ls.formatters")
formatters.setup({
    {
        exe = "elm-format",
        filetypes = { "elm" },
    }
})
Enter fullscreen mode Exit fullscreen mode

I'm stil to find out how to load your own personal configurations (*.lua files)

Top comments (0)