#!/bin/bash # Image build script. Run once by the Dockerfile; removes itself when done. # Everything that is not pinned by an environment variable resolves to its # current release at build time. set -euxo pipefail export DEBIAN_FRONTEND=noninteractive arch="$(dpkg --print-architecture)" latest_tag() { curl -fsSLI -o /dev/null -w '%{url_effective}' \ "https://github.com/$1/releases/latest" | sed 's,.*/tag/,,' } # --- distro packages ------------------------------------------------------- apt-get update apt-get -y full-upgrade apt-get -y install --no-install-recommends \ bzip2 ca-certificates curl git gnupg jq less openssh-client rsync \ unzip wget xz-utils zip \ build-essential make pkg-config \ runit \ golang-go \ nodejs npm \ python3 python3-dev python3-pip python3-venv virtualenv \ libbz2-dev libffi-dev libgdbm-dev liblzma-dev libncurses-dev \ libreadline-dev libsqlite3-dev libssl-dev libxml2-dev libxmlsec1-dev \ tk-dev uuid-dev zlib1g-dev # --- Go (latest) ------------------------------------------------------------- gover="$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -n1)" curl -fsSL "https://go.dev/dl/${gover}.linux-${arch}.tar.gz" | tar -C /usr/local -xz rm -rf /usr/local/go/test # --- runsvinit (PID 1: reaps zombies, stops services on SIGTERM) ------------- git clone -q https://github.com/peterbourgon/runsvinit /tmp/runsvinit git -C /tmp/runsvinit checkout -q "$RUNSVINIT_COMMIT" ( cd /tmp/runsvinit go mod init runsvinit >/dev/null 2>&1 CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /usr/local/sbin/runsvinit . ) # --- golangci-lint ----------------------------------------------------------- gl="$(latest_tag golangci/golangci-lint)" curl -fsSL "https://github.com/golangci/golangci-lint/releases/download/${gl}/golangci-lint-${gl#v}-linux-${arch}.tar.gz" | tar -C /usr/local/bin -xz --strip-components=1 "golangci-lint-${gl#v}-linux-${arch}/golangci-lint" # --- Hugo (extended) --------------------------------------------------------- hv="$(latest_tag gohugoio/hugo)" curl -fsSL -o /tmp/hugo.deb \ "https://github.com/gohugoio/hugo/releases/download/${hv}/hugo_extended_${hv#v}_linux-${arch}.deb" apt-get -y install /tmp/hugo.deb # --- nvm, Node LTS, yarn, wrangler ------------------------------------------ git clone -q --depth 1 --branch "$NVM_GIT_TAG" https://github.com/nvm-sh/nvm.git "$NVM_DIR" rm -rf "$NVM_DIR/.git" set +ux # nvm.sh is not clean under set -u / too noisy under set -x . "$NVM_DIR/nvm.sh" nvm install --lts nvm alias default "lts/*" nvm use default set -ux npm install -g npm@latest corepack wrangler corepack enable # Pre-populate the corepack cache so projects that pin a package manager # do not download at run time. The last yarn installed becomes the default. corepack install -g pnpm@latest corepack install -g yarn@1 corepack install -g yarn@stable # pnpm 10+ fetches a standalone binary on first run; trigger that now so # it lands in COREPACK_HOME. pnpm --version yarn --version nvm cache clear # --- pyenv, Python (latest), pip, virtualenv --------------------------------- git clone -q --depth 1 --branch "$PYENV_GIT_TAG" https://github.com/pyenv/pyenv.git "$PYENV_ROOT" rm -rf "$PYENV_ROOT/.git" pyver="$(pyenv latest --known 3)" pyenv install "$pyver" pyenv global "$pyver" rm -rf "$PYENV_ROOT"/versions/*/lib/python3*/test python3 -m pip install --no-cache-dir --upgrade pip setuptools wheel virtualenv pyenv rehash # --- cleanup ----------------------------------------------------------------- go clean -cache -modcache -testcache apt-get -y autoremove --purge apt-get clean rm -rf /var/lib/apt/lists/* /var/cache/apt/* /var/cache/debconf/*-old /var/log/* rm -rf /usr/share/doc /usr/share/man /usr/share/info /usr/share/lintian find /usr/share/locale -mindepth 1 -maxdepth 1 ! -name 'en*' ! -name 'locale.alias' -exec rm -rf {} + rm -rf /root/.cache /root/.npm /root/.config /root/go /tmp/* /var/tmp/* # --- sanity ------------------------------------------------------------------ go version golangci-lint version hugo version node --version npm --version COREPACK_ENABLE_NETWORK=0 yarn --version COREPACK_ENABLE_NETWORK=0 pnpm --version wrangler --version python3 --version pip --version virtualenv --version test -x /usr/local/sbin/runsvinit test -d /etc/service # The checks above leave caches behind (node compile cache etc). rm -rf /tmp/* /var/tmp/* /root/.cache /root/.npm /root/.config rm -f "$0"