Files
baseimage/build.sh
T
sneak dc45c1774e fixup! Add tzdata (closes #4)
Model: deepseek-v4-pro
2026-11-05 15:01:19 +00:00

172 lines
6.4 KiB
Bash
Executable File

#!/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 \
shellcheck \
tzdata \
zstd sqlite3 \
libvips-dev libvips-tools libheif-dev libheif-plugin-aomenc \
imagemagick ghostscript \
ruby ruby-dev bundler \
valkey-server valkey-tools postgresql \
nginx
# --- 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"
# --- govulncheck (Go tool) ---------------------------------------------------
GOBIN=/usr/local/bin go install golang.org/x/vuln/cmd/govulncheck@latest
# --- 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 prettier playwright
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
# --- browsers for tests: Firefox, geckodriver, Playwright --------------------
# Ubuntu's firefox is a snap that does not run in a container, so use
# Mozilla's own apt repository for the real binary.
install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://packages.mozilla.org/apt/repo-signing-key.gpg \
-o /etc/apt/keyrings/packages.mozilla.org.asc
echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" \
> /etc/apt/sources.list.d/mozilla.list
apt-get update
apt-get -y install --no-install-recommends -t mozilla firefox
# geckodriver, matched to Firefox at its current release.
gd="$(latest_tag mozilla/geckodriver)"
case "$arch" in
arm64) gd_arch=linux-aarch64 ;;
*) gd_arch=linux64 ;;
esac
curl -fsSL "https://github.com/mozilla/geckodriver/releases/download/${gd}/geckodriver-${gd}-${gd_arch}.tar.gz" |
tar -C /usr/local/bin -xz geckodriver
# Playwright's Chromium and Firefox. WebKit has no linux-arm64 build, so it
# is skipped. Playwright's Chromium is also the headless Chrome for
# chromedp-style clients, exposed as `chromium` on PATH.
playwright install --with-deps chromium firefox
ln -s "$(ls -d "$PLAYWRIGHT_BROWSERS_PATH"/chromium-*/chrome-linux*/chrome | head -n1)" \
/usr/local/bin/chromium
# --- 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
govulncheck -version
golangci-lint version
shellcheck --version
test -e /usr/share/zoneinfo/America/New_York
zstd --version
sqlite3 --version
vips --version
vips -l | grep -i heif > /dev/null
magick --version
gs --version
ruby --version
bundle --version
valkey-server --version
valkey-cli --version
psql --version
nginx -v
hugo version
node --version
npm --version
COREPACK_ENABLE_NETWORK=0 yarn --version
COREPACK_ENABLE_NETWORK=0 pnpm --version
wrangler --version
prettier --version
playwright --version
firefox --version
geckodriver --version
chromium --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"