#!/bin/bash set -euo pipefail DEBIAN_FRONTEND=noninteractive # System deps (already installed via cloud-init but idempotent) apt-get update -qq apt-get install -y -qq build-essential curl git \ libgmp-dev libffi-dev zlib1g-dev libncurses-dev libtinfo-dev pkg-config # GHCup — non-interactive bootstrap # Primary version (9.8.4) is the default; secondary (9.6.6) covers LTS 22/23. # Skip Stack (cabal covers 95% of projects) and HLS (saves ~2 GB image size). GHC_PRIMARY="${GHC_PRIMARY_VERSION:-9.8.4}" GHC_SECONDARY="${GHC_SECONDARY_VERSION:-9.6.6}" CABAL_VERSION="${CABAL_VERSION:-3.12.1.0}" export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_PRIMARY" export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION" export BOOTSTRAP_HASKELL_INSTALL_STACK=0 # not needed; cabal suffices export BOOTSTRAP_HASKELL_INSTALL_HLS=0 # ~2 GB — skip for build-only image curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org \ | runuser -l build -c 'sh -s -- --no-modify-path' # Add ghcup env to build user profile echo '. "$HOME/.ghcup/env"' >> /home/build/.bashrc echo '. "$HOME/.ghcup/env"' >> /home/build/.profile # Install secondary GHC version (~500 MB, shared GHCup base — worth it) runuser -l build -c "source ~/.ghcup/env && ghcup install ghc $GHC_SECONDARY" # Ensure primary is the default runuser -l build -c "source ~/.ghcup/env && ghcup set ghc $GHC_PRIMARY" # Pre-warm cabal package db (saves 2-3 min on first real build) runuser -l build -c 'source ~/.ghcup/env && cabal update' # Verify both versions present runuser -l build -c "source ~/.ghcup/env && ghc --version && cabal --version" runuser -l build -c "source ~/.ghcup/env && ghcup run --ghc $GHC_SECONDARY -- ghc --version"