DEV Community

Theodor Heiselberg
Theodor Heiselberg

Posted on • Edited 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 \ xclip \ 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 (3)

Collapse
 
sukkergris profile image
Info Comment hidden by post author - thread only accessible via permalink
Theodor Heiselberg

Hi great question ☺️
The answer is tooling. Every project I work on also involves databases and various other services. Using vs code and devcontainers with all the necessary extensions ties my entire dev environment together with my ide of choice. One ide to rule the entire project 👍
(Hence the usage of docker compose)
Personally I’m not that mush a cli expert to be using the cli exclusively.
What’s your opinion?

Collapse
 
daniel_hamngren_9ca73b73b profile image
Daniel Hamngren

Intesting post! But I don’t really understand how you use your devcontainer. Are you using both lunarvim and vs code in your devcontainer? How do you interact with lunarvim when you have your devcontainer running on e.g. codespaces?

What do you see is the best thing with the setup in your post?

Collapse
 
sukkergris profile image
Theodor Heiselberg • Edited

question ☺️
The answer is tooling. Every project I work on also involves databases and various other services. Using vs code and devcontainers with all the necessary extensions ties my entire dev environment together with my ide of choice. One ide to rule the entire project 👍
(Hence the usage of docker compose)
Personally I’m not that mush a cli expert to be using the cli exclusively.
What’s your opinion?

Some comments have been hidden by the post's author - find out more