A ready-to-use Docker image for Haskell development, built on top of the VS Code Dev Containers base image. Pull it, attach VS Code, and get a fully configured Haskell environment in seconds — no local toolchain required.
| Tool | Version |
|---|---|
| GHC | 9.10.3 |
| Cabal | 3.12.1.0 |
| Stack | latest |
| GHCup | latest |
- HLS — Haskell Language Server for IDE features (completions, type hints, go-to-definition)
- Hoogle — Local Haskell API search database, pre-generated at build time
- Ormolu — Opinionated, deterministic code formatter
- fast-tags — Fast tag file generator for Haskell source
- cabal-gild — Formatter and linter for
.cabalfiles - direnv — Per-directory environment variable loading, hooked into both
bashandzsh - Node.js & npm — Available for general development and for installing npm-based tools via
postCreateCommand
Full Debug Adapter Protocol support via:
haskell-dapghci-daphaskell-debug-adapter
Images are built for both linux/amd64 (Intel/AMD) and linux/arm64 (Apple Silicon).
The image is automatically built and published to Docker Hub on every version tag (v*.*.*) and on manual workflow dispatch, via GitHub Actions. Versioned tags follow semver: pushing v1.2.3 publishes :1.2.3, :1.2, :1, and :latest.
Before publishing, the CI pipeline runs two Trivy gates:
- Dockerfile misconfiguration scan — fails on CRITICAL/HIGH misconfigurations
- Image vulnerability scan — builds the
amd64image first, scans it with Trivy, uploads the SARIF report to the GitHub Security tab, and blocks the multi-platform push if any fixable CRITICAL/HIGH CVEs are found
The image is designed to run without host privileges. The runArgs in the Quick Start snippet enforce this:
| Flag | What it prevents |
|---|---|
--cap-drop=ALL |
Removes all Linux capabilities (filesystem ownership changes, raw sockets, kernel module loading, etc.) |
--security-opt=no-new-privileges:true |
Prevents any process inside the container from gaining elevated privileges via setuid/setgid binaries |
--pids-limit=2048 |
Limits the number of processes to prevent fork bombs; high enough for parallel GHC compilation |
Never add "privileged": true or mount /var/run/docker.sock into the container. Either grants any process running inside (including AI coding assistants) full control over the Docker daemon on your host machine — a trivial container escape.
direnv is compiled from source inside a golang:1.26.3-bookworm builder stage rather than downloaded as a prebuilt binary. Prebuilt binaries bundle the Go stdlib version used at release time and cannot be updated independently; building from source ensures the embedded stdlib is the patched version.
- Cabal jobs are set to
$ncpusfor parallel builds. - Documentation generation is disabled in Cabal to speed up package installs.
- The image runs as the non-root
vscodeuser, as expected by the Dev Containers spec.