chore: upgrade to ubuntu 26.04 (#24267)

This commit is contained in:
Kayla はな
2026-04-15 15:02:47 -06:00
committed by GitHub
parent d11849d94a
commit d23a6959fc
58 changed files with 654 additions and 42 deletions
+1 -1
View File
@@ -178,7 +178,7 @@ jobs:
- name: Get golangci-lint cache dir
run: |
linter_ver=$(grep -Eo 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/Dockerfile | cut -d '=' -f 2)
linter_ver=$(grep -Eo 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/ubuntu-26.04/Dockerfile | cut -d '=' -f 2)
./.github/scripts/retry.sh -- go install "github.com/golangci/golangci-lint/cmd/golangci-lint@v$linter_ver"
dir=$(golangci-lint cache status | awk '/Dir/ { print $2 }')
echo "LINT_CACHE_DIR=$dir" >> "$GITHUB_ENV"
+33 -4
View File
@@ -22,6 +22,11 @@ permissions:
jobs:
build_image:
strategy:
fail-fast: false
matrix:
image-version: ["22.04", "26.04", "nix"]
if: github.actor != 'dependabot[bot]' # Skip Dependabot PRs
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-4' || 'ubuntu-latest' }}
steps:
@@ -41,6 +46,7 @@ jobs:
# Pinning to 2.28 here, as Nix gets a "error: [json.exception.type_error.302] type must be array, but is string"
# on version 2.29 and above.
nix_version: "2.28.5"
if: matrix.image-version == 'nix'
- uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2
with:
@@ -60,10 +66,12 @@ jobs:
purge-created: 0
# except the version with the `primary-key`, if it exists
purge-primary-key: never
if: matrix.image-version == 'nix'
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@5250492686b253f06fa55861556d1027b067aeb5 # v9.0.2
if: matrix.image-version != 'nix'
- name: "Branch name to Docker tag name"
id: docker-tag-name
@@ -73,12 +81,15 @@ jobs:
echo "tag=${tag}" >> "$GITHUB_OUTPUT"
env:
BRANCH_NAME: ${{ steps.branch-name.outputs.current_branch }}
if: matrix.image-version != 'nix'
- name: Set up Depot CLI
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1
if: matrix.image-version != 'nix'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
if: matrix.image-version != 'nix'
- name: Login to DockerHub
if: github.ref == 'refs/heads/main'
@@ -87,23 +98,41 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build and push Non-Nix image
- name: Build and push Ubuntu 22.04 image
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
with:
project: b4q6ltmpzh
token: ${{ secrets.DEPOT_TOKEN }}
buildx-fallback: true
context: "{{defaultContext}}:dogfood/coder"
context: "{{defaultContext}}:dogfood/coder/ubuntu-22.04"
pull: true
save: true
push: ${{ github.ref == 'refs/heads/main' }}
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:latest"
# TODO: move the `latest` tag to 26.04 soon. we don't want to transition
# it immediately because that would make workspaces switch to it
# automatically without any grace period.
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:22.04,codercom/oss-dogfood:latest"
if: matrix.image-version == '22.04'
- name: Build and push Ubuntu 26.04 image
uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0
with:
project: b4q6ltmpzh
token: ${{ secrets.DEPOT_TOKEN }}
buildx-fallback: true
context: "{{defaultContext}}:dogfood/coder/ubuntu-26.04"
pull: true
save: true
push: ${{ github.ref == 'refs/heads/main' }}
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:26.04"
if: matrix.image-version == '26.04'
- name: Build Nix image
run: nix build .#dev_image
if: matrix.image-version == 'nix'
- name: Push Nix image
if: github.ref == 'refs/heads/main'
if: matrix.image-version == 'nix' && github.ref == 'refs/heads/main'
run: |
docker load -i result
-1
View File
@@ -42,7 +42,6 @@ site/.swc
.gen-golden
# Build
bin/
build/
dist/
out/
+1 -1
View File
@@ -718,7 +718,7 @@ lint/ts: site/node_modules/.installed
lint/go:
./scripts/check_enterprise_imports.sh
./scripts/check_codersdk_imports.sh
linter_ver=$$(grep -oE 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/Dockerfile | cut -d '=' -f 2)
linter_ver=$$(grep -oE 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder/ubuntu-26.04/Dockerfile | cut -d '=' -f 2)
go run github.com/golangci/golangci-lint/cmd/golangci-lint@v$$linter_ver run
go tool github.com/coder/paralleltestctx/cmd/paralleltestctx -custom-funcs="testutil.Context" ./...
.PHONY: lint/go
+33 -6
View File
@@ -1,10 +1,37 @@
.PHONY: docker-build docker-push
# Use the branch name to differentiate test builds from actual pulled images,
# replacing forward slashes with hyphens, as forward slashes are not valid in
# tag names.
build_tag ?= $(shell git rev-parse --abbrev-ref HEAD | sed "s/\\//-/")
branch=$(shell git rev-parse --abbrev-ref HEAD)
build_tag=codercom/oss-dogfood:${branch}
build: build-ubuntu-22.04 build-ubuntu-26.04
.PHONY: build
build:
DOCKER_BUILDKIT=1 docker build . -t ${build_tag}
build-ubuntu-22.04:
(cd ubuntu-22.04/ && DOCKER_BUILDKIT=1 docker build . -t "codercom/oss-dogfood:22.04-$(build_tag)")
.PHONY: build-ubuntu-22.04
push: build
build-ubuntu-26.04:
(cd ubuntu-26.04/ && DOCKER_BUILDKIT=1 docker build . -t "codercom/oss-dogfood:26.04-$(build_tag)")
.PHONY: build-ubuntu-26.04
push: push-ubuntu-22.04 push-ubuntu-26.04
.PHONY: push
push-ubuntu-22.04: build-ubuntu-22.04
docker push ${build_tag}
.PHONY: push-ubuntu-22.04
push-ubuntu-26.04: build-ubuntu-26.04
docker push ${build_tag}
.PHONY: push-ubuntu-26.04
update-keys: update-keys-ubuntu-22.04 update-keys-ubuntu-26.04
.PHONY: update-keys
update-keys-ubuntu-22.04:
./ubuntu-22.04/update-keys.sh
.PHONY: update-keys-ubuntu-22.04
update-keys-ubuntu-26.04:
./ubuntu-26.04/update-keys.sh
.PHONY: update-keys-ubuntu-26.04
+11 -5
View File
@@ -124,12 +124,17 @@ data "coder_parameter" "repo_base_dir" {
data "coder_parameter" "image_type" {
type = "string"
name = "Coder Image"
default = "codercom/oss-dogfood:latest"
description = "The Docker image used to run your workspace. Choose between nix and non-nix images."
default = "codercom/oss-dogfood:26.04"
description = "The Docker image used to run your workspace."
option {
icon = "/icon/coder.svg"
name = "Dogfood (Default)"
value = "codercom/oss-dogfood:latest"
name = "Ubuntu 26.04"
value = "codercom/oss-dogfood:26.04"
}
option {
icon = "/icon/coder.svg"
name = "Ubuntu 22.04"
value = "codercom/oss-dogfood:22.04"
}
option {
icon = "/icon/nix.svg"
@@ -770,7 +775,8 @@ resource "docker_image" "dogfood" {
pull_triggers = [
data.docker_registry_image.dogfood.sha256_digest,
sha1(join("", [for f in fileset(path.module, "files/*") : filesha1(f)])),
filesha1("Dockerfile"),
filesha1("ubuntu-22.04/Dockerfile"),
filesha1("ubuntu-26.04/Dockerfile"),
filesha1("nix.hash"),
]
keep_locally = true
@@ -15,11 +15,14 @@ gpg_flags=(
--yes
)
pushd "$PROJECT_ROOT/dogfood/coder/files/usr/share/keyrings"
pushd "$PROJECT_ROOT/dogfood/coder/ubuntu-22.04/files/usr/share/keyrings"
# Ansible PPA signing key
curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0X6125E2A8C77F2818FB7BD15B93C4A3FD7BB9C367" |
gpg "${gpg_flags[@]}" --output="ansible.gpg"
# This curl command is now resulting in a 404, causing the script to fail.
# Rather than fix, we're just upgrading to Ubuntu 26.04 which removed the
# dependency on this PPA.
# curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0X6125E2A8C77F2818FB7BD15B93C4A3FD7BB9C367" |
# gpg "${gpg_flags[@]}" --output="ansible.gpg"
# Upstream Docker signing key
curl "${curl_flags[@]}" "https://download.docker.com/linux/ubuntu/gpg" |
@@ -37,10 +40,6 @@ curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0
curl "${curl_flags[@]}" "https://cli.github.com/packages/githubcli-archive-keyring.gpg" |
gpg "${gpg_flags[@]}" --output="github-cli.gpg"
# Google Linux Software repository signing key (Chrome)
curl "${curl_flags[@]}" "https://dl.google.com/linux/linux_signing_key.pub" |
gpg "${gpg_flags[@]}" --output="google-chrome.gpg"
# Google Cloud signing key
curl "${curl_flags[@]}" "https://packages.cloud.google.com/apt/doc/apt-key.gpg" |
gpg "${gpg_flags[@]}" --output="google-cloud.gpg"
@@ -53,24 +52,12 @@ curl "${curl_flags[@]}" "https://apt.releases.hashicorp.com/gpg" |
curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x27642B9FD7F1A161FC2524E3355A4FA515D7C855" |
gpg "${gpg_flags[@]}" --output="helix.gpg"
# Microsoft repository signing key (Edge)
curl "${curl_flags[@]}" "https://packages.microsoft.com/keys/microsoft.asc" |
gpg "${gpg_flags[@]}" --output="microsoft.gpg"
# Neovim signing key
curl "${curl_flags[@]}" "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x9DBB0BE9366964F134855E2255F96FCF8231B6DD" |
gpg "${gpg_flags[@]}" --output="neovim.gpg"
# NodeSource signing key
curl "${curl_flags[@]}" "https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key" |
gpg "${gpg_flags[@]}" --output="nodesource.gpg"
# Upstream PostgreSQL signing key
curl "${curl_flags[@]}" "https://www.postgresql.org/media/keys/ACCC4CF8.asc" |
gpg "${gpg_flags[@]}" --output="postgresql.gpg"
# Yarnpkg signing key
curl "${curl_flags[@]}" "https://dl.yarnpkg.com/debian/pubkey.gpg" |
gpg "${gpg_flags[@]}" --output="yarnpkg.gpg"
popd
+368
View File
@@ -0,0 +1,368 @@
# 1.93.1
FROM rust:slim@sha256:cf09adf8c3ebaba10779e5c23ff7fe4df4cccdab8a91f199b0c142c53fef3e1a AS rust-utils
# Install rust helper programs
ENV CARGO_INSTALL_ROOT=/tmp/
# Use more reliable mirrors for Debian packages
RUN sed -i 's|http://deb.debian.org/debian|http://mirrors.edge.kernel.org/debian|g' /etc/apt/sources.list && \
apt-get update || true
RUN apt-get update && apt-get install -y libssl-dev openssl pkg-config build-essential
RUN cargo install jj-cli typos-cli watchexec-cli
FROM ubuntu:resolute@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1 AS go
# Install Go manually, so that we can control the version
ARG GO_VERSION=1.25.9
ARG GO_CHECKSUM="00859d7bd6defe8bf84d9db9e57b9a4467b2887c18cd93ae7460e713db774bc1"
# Boring Go is needed to build FIPS-compliant binaries.
RUN apt-get update && \
apt-get install --yes curl && \
curl --silent --show-error --location \
"https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
-o /usr/local/go.tar.gz && \
echo "$GO_CHECKSUM /usr/local/go.tar.gz" | sha256sum -c && \
rm -rf /var/lib/apt/lists/*
ENV PATH=$PATH:/usr/local/go/bin
ARG GOPATH="/tmp/"
# Install Go utilities.
RUN apt-get update && \
apt-get install --yes gcc && \
mkdir --parents /usr/local/go && \
tar --extract --gzip --directory=/usr/local/go --file=/usr/local/go.tar.gz --strip-components=1 && \
mkdir --parents "$GOPATH" && \
go env -w GOSUMDB=sum.golang.org && \
# swag for Swagger doc generation
go install github.com/swaggo/swag/cmd/swag@v1.16.2 && \
# goimports for updating imports
go install golang.org/x/tools/cmd/goimports@v0.41.0 && \
# protoc-gen-go is needed to build sysbox from source
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.30.0 && \
# drpc support for v2
go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.34 && \
# migrate for migration support for v2
go install github.com/golang-migrate/migrate/v4/cmd/migrate@v4.15.1 && \
# Install the latest version of gopls for editors that support
# the language server protocol (v0.21.0+ required for Go 1.25)
go install golang.org/x/tools/gopls@v0.21.0 && \
# gotestsum makes test output more readable
go install gotest.tools/gotestsum@v1.9.0 && \
# sqlc for Go code generation
# Switched to coder/sqlc fork to fix ambiguous column bug, see:
# - https://github.com/coder/sqlc/pull/1
# - https://github.com/sqlc-dev/sqlc/pull/4159
(CGO_ENABLED=1 go install github.com/coder/sqlc/cmd/sqlc@aab4e865a51df0c43e1839f81a9d349b41d14f05) && \
# ruleguard for checking custom rules, without needing to run all of
# golangci-lint. Check the go.mod in the release of golangci-lint that
# we're using for the version of go-critic that it embeds, then check
# the version of ruleguard in go-critic for that tag.
go install github.com/quasilyte/go-ruleguard/cmd/ruleguard@v0.3.13 && \
# shfmt for shell script formatting
go install mvdan.cc/sh/v3/cmd/shfmt@v3.12.0 && \
# nfpm is used with `make build` to make release packages
go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.35.1 && \
# yq v4 for processing YAML files (renamed to yq4 for scripts/lib.sh).
go install github.com/mikefarah/yq/v4@v4.44.3 && \
mv /tmp/bin/yq /tmp/bin/yq4 && \
# mockgen for generating mocks (v0.6.0+ required for Go 1.25)
go install go.uber.org/mock/mockgen@v0.6.0 && \
# Reduce image size.
apt-get remove --yes gcc && \
apt-get autoremove --yes && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /usr/local/go && \
rm -rf /tmp/go/pkg && \
rm -rf /tmp/go/src
# alpine:3.18
FROM us-docker.pkg.dev/coder-v2-images-public/public/alpine@sha256:fd032399cd767f310a1d1274e81cab9f0fd8a49b3589eba2c3420228cd45b6a7 AS proto
WORKDIR /tmp
RUN apk add curl unzip
RUN curl -L -o protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v23.4/protoc-23.4-linux-x86_64.zip && \
unzip protoc.zip && \
rm protoc.zip
FROM ubuntu:resolute@sha256:cc925e589b7543b910fea57a240468940003fbfc0515245a495dd0ad8fe7cef1
SHELL ["/bin/bash", "-c"]
# Install packages from apt repositories
ARG DEBIAN_FRONTEND="noninteractive"
# Updated certificates are necessary to use the teraswitch mirror.
# This must be ran before copying in configuration since the config replaces
# the default mirror with teraswitch.
# Also enable the en_US.UTF-8 locale so that we don't generate multiple locales
# and unminimize to include man pages.
RUN apt-get update && \
apt-get install --yes ca-certificates locales unminimize && \
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
locale-gen && \
yes | unminimize
COPY files /
# We used to copy /etc/sudoers.d/* in from files/ but this causes issues with
# permissions and layer caching. Instead, create the file directly.
RUN mkdir -p /etc/sudoers.d && \
echo 'coder ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/nopasswd && \
chmod 750 /etc/sudoers.d/ && \
chmod 640 /etc/sudoers.d/nopasswd
# Use more reliable mirrors for Ubuntu packages
RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/ubuntu/|g; s|http://security.ubuntu.com/ubuntu/|http://mirrors.edge.kernel.org/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources && \
apt-get update --quiet && apt-get install --yes \
ansible \
apt-transport-https \
apt-utils \
asciinema \
bash \
bash-completion \
bat \
bats \
bind9-dnsutils \
build-essential \
ca-certificates \
containerd.io \
crypto-policies \
curl \
docker-ce \
docker-ce-cli \
docker-compose-plugin \
eza \
fd-find \
file \
fish \
gettext-base \
git \
gnupg \
google-cloud-sdk \
hx \
htop \
httpie \
inetutils-tools \
iproute2 \
iputils-ping \
iputils-tracepath \
jq \
kubectl \
language-pack-en \
less \
libgbm-dev \
libssl-dev \
lsb-release \
lsof \
man \
meld \
ncdu \
neovim \
net-tools \
openjdk-11-jdk-headless \
openssh-server \
openssl \
pkg-config \
postgresql-18 \
python3 \
python3-pip \
ripgrep \
rsync \
screen \
shellcheck \
strace \
sudo \
tcptraceroute \
termshark \
tmux \
traceroute \
unzip \
vim \
wget \
xauth \
zip \
zsh \
zstd && \
# Delete package cache to avoid consuming space in layer
apt-get clean && \
# Configure FIPS-compliant policies
update-crypto-policies --set FIPS
# Install Google Chrome directly from Google. Ubuntu 26.04 ships
# chromium-browser as a snap-only package, which does not work in
# Docker containers.
# configure-chrome-flags.sh is automatically run after dpkg operations
# by dogfood/coder/files/etc/apt/apt.conf.d/99-chrome-flags.
RUN chmod a+x /opt/configure-chrome-flags.sh && \
wget -q https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
apt-get install --yes ./google-chrome-stable_current_amd64.deb && \
rm google-chrome-stable_current_amd64.deb
# Install Rust via rustup. Using rustup ensures we get a current stable
# toolchain.
ENV RUSTUP_HOME=/usr/local/rustup \
CARGO_HOME=/usr/local/cargo
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y --default-toolchain stable --profile minimal
ENV PATH=$CARGO_HOME/bin:$PATH
# NOTE: In scripts/Dockerfile.base we specifically install Terraform version 1.14.5.
# Installing the same version here to match.
RUN wget -O /tmp/terraform.zip "https://releases.hashicorp.com/terraform/1.14.5/terraform_1.14.5_linux_amd64.zip" && \
unzip /tmp/terraform.zip -d /usr/local/bin && \
rm -f /tmp/terraform.zip && \
chmod +x /usr/local/bin/terraform && \
terraform --version
# Install the docker buildx component.
RUN DOCKER_BUILDX_VERSION=$(curl -s "https://api.github.com/repos/docker/buildx/releases/latest" | grep '"tag_name":' | sed -E 's/.*"(v[^"]+)".*/\1/') && \
mkdir -p /usr/local/lib/docker/cli-plugins && \
curl -Lo /usr/local/lib/docker/cli-plugins/docker-buildx "https://github.com/docker/buildx/releases/download/${DOCKER_BUILDX_VERSION}/buildx-${DOCKER_BUILDX_VERSION}.linux-amd64" && \
chmod a+x /usr/local/lib/docker/cli-plugins/docker-buildx
# See https://github.com/cli/cli/issues/6175#issuecomment-1235984381 for proof
# the apt repository is unreliable
RUN GH_CLI_VERSION=$(curl -s "https://api.github.com/repos/cli/cli/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') && \
curl -L https://github.com/cli/cli/releases/download/v${GH_CLI_VERSION}/gh_${GH_CLI_VERSION}_linux_amd64.deb -o gh.deb && \
dpkg -i gh.deb && \
rm gh.deb
# Install Lazygit
# See https://github.com/jesseduffield/lazygit#ubuntu
RUN LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v*([^"]+)".*/\1/') && \
curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_x86_64.tar.gz" && \
tar xf lazygit.tar.gz -C /usr/local/bin lazygit && \
rm lazygit.tar.gz
# Install doctl
# See https://docs.digitalocean.com/reference/doctl/how-to/install
RUN DOCTL_VERSION=$(curl -s "https://api.github.com/repos/digitalocean/doctl/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') && \
curl -L https://github.com/digitalocean/doctl/releases/download/v${DOCTL_VERSION}/doctl-${DOCTL_VERSION}-linux-amd64.tar.gz -o doctl.tar.gz && \
tar xf doctl.tar.gz -C /usr/local/bin doctl && \
rm doctl.tar.gz
ARG NVM_INSTALL_SHA=bdea8c52186c4dd12657e77e7515509cda5bf9fa5a2f0046bce749e62645076d
# Install frontend utilities
ENV NVM_DIR=/usr/local/nvm
ENV NODE_VERSION=22.19.0
RUN mkdir -p $NVM_DIR
RUN curl -o nvm_install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh && \
echo "${NVM_INSTALL_SHA} nvm_install.sh" | sha256sum -c && \
bash nvm_install.sh && \
rm nvm_install.sh
RUN source $NVM_DIR/nvm.sh && \
nvm install $NODE_VERSION && \
nvm use $NODE_VERSION
ENV PATH=$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN corepack enable && \
corepack prepare npm@10.8.1 --activate && \
corepack prepare pnpm@10.14.0 --activate
RUN pnpx playwright@1.47.0 install --with-deps chromium
# Ensure PostgreSQL binaries are in the users $PATH.
RUN update-alternatives --install /usr/local/bin/initdb initdb /usr/lib/postgresql/18/bin/initdb 100 && \
update-alternatives --install /usr/local/bin/postgres postgres /usr/lib/postgresql/18/bin/postgres 100
# Create links for injected dependencies
RUN ln --symbolic /var/tmp/coder/coder-cli/coder /usr/local/bin/coder && \
ln --symbolic /var/tmp/coder/code-server/bin/code-server /usr/local/bin/code-server
# Disable the PostgreSQL systemd service.
# Coder uses a custom timescale container to test the database instead.
RUN systemctl disable \
postgresql
# Configure systemd services for CVMs
RUN systemctl enable \
docker \
ssh && \
# Workaround for envbuilder cache probing not working unless the filesystem is modified.
touch /tmp/.envbuilder-systemctl-enable-docker-ssh-workaround
# Install tools with published releases, where that is the
# preferred/recommended installation method.
ARG GOLANGCI_LINT_VERSION=1.64.8 \
HELM_VERSION=3.12.0 \
KUBECTX_VERSION=0.9.4 \
SYFT_VERSION=1.20.0 \
COSIGN_VERSION=2.4.3 \
BUN_VERSION=1.2.15
RUN \
# golangci-lint performs static code analysis for our Go code
curl --silent --show-error --location --fail "https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-linux-amd64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- --strip-components=1 "golangci-lint-${GOLANGCI_LINT_VERSION}-linux-amd64/golangci-lint" && \
# Helm is necessary for deploying Coder
curl --silent --show-error --location --fail "https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- --strip-components=1 linux-amd64/helm && \
# kubens and kubectx for managing Kubernetes namespaces and contexts
curl --silent --show-error --location --fail "https://github.com/ahmetb/kubectx/releases/download/v${KUBECTX_VERSION}/kubectx_v${KUBECTX_VERSION}_linux_x86_64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- kubectx && \
curl --silent --show-error --location --fail "https://github.com/ahmetb/kubectx/releases/download/v${KUBECTX_VERSION}/kubens_v${KUBECTX_VERSION}_linux_x86_64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- kubens && \
# Anchore Syft for SBOM generation
curl --silent --show-error --location --fail "https://github.com/anchore/syft/releases/download/v${SYFT_VERSION}/syft_${SYFT_VERSION}_linux_amd64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- syft && \
# Sigstore Cosign for artifact signing and attestation
curl --silent --show-error --location --fail --output /usr/local/bin/cosign "https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64" && \
chmod a=rx /usr/local/bin/cosign && \
# Install Bun JavaScript runtime to /usr/local/bin
curl --silent --show-error --location --fail "https://github.com/oven-sh/bun/releases/download/bun-v${BUN_VERSION}/bun-linux-x64.zip" --output /tmp/bun.zip && \
unzip -q /tmp/bun.zip -d /tmp && \
mv /tmp/bun-linux-x64/bun /usr/local/bin/ && \
chmod a=rx /usr/local/bin/bun && \
rm -rf /tmp/bun.zip /tmp/bun-linux-x64 && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# Add coder user and allow use of docker/sudo.
# Ubuntu 26.04 ships a default "ubuntu" user at UID 1000;
# remove it so we can create "coder" with that UID.
RUN userdel -r ubuntu && \
useradd coder \
--create-home \
--shell=/bin/bash \
--groups=docker \
--uid=1000 \
--user-group
# Adjust OpenSSH config
RUN echo "PermitUserEnvironment yes" >>/etc/ssh/sshd_config && \
echo "X11Forwarding yes" >>/etc/ssh/sshd_config && \
echo "X11UseLocalhost no" >>/etc/ssh/sshd_config
# We avoid copying the extracted directory since COPY slows to minutes when there
# are a lot of small files.
COPY --from=go /usr/local/go.tar.gz /usr/local/go.tar.gz
RUN mkdir /usr/local/go && \
tar --extract --gzip --directory=/usr/local/go --file=/usr/local/go.tar.gz --strip-components=1
ENV PATH=$PATH:/usr/local/go/bin
RUN update-alternatives --install /usr/local/bin/gofmt gofmt /usr/local/go/bin/gofmt 100
COPY --from=go /tmp/bin /usr/local/bin
COPY --from=rust-utils /tmp/bin /usr/local/bin
COPY --from=proto /tmp/bin /usr/local/bin
COPY --from=proto /tmp/include /usr/local/bin/include
USER coder
# Ensure go bins are in the 'coder' user's path. Note that no go bins are
# installed in this docker file, as they'd be mounted over by the persistent
# home volume.
ENV PATH="/home/coder/go/bin:${PATH}"
# Override CARGO_HOME so cargo registry/cache writes go to the coder
# user's home directory instead of the root-owned /usr/local/cargo.
# The rustup-installed binaries remain on PATH via /usr/local/cargo/bin.
ENV CARGO_HOME="/home/coder/.cargo"
# This setting prevents Go from using the public checksum database for
# our module path prefixes. It is required because these are in private
# repositories that require authentication.
#
# For details, see: https://golang.org/ref/mod#private-modules
ENV GOPRIVATE="coder.com,cdr.dev,go.coder.com,github.com/cdr,github.com/coder"
# Increase memory allocation to NodeJS
ENV NODE_OPTIONS="--max-old-space-size=8192"
@@ -0,0 +1,6 @@
// Do not install recommended packages by default
APT::Install-Recommends "0";
// Do not install suggested packages by default (this is already
// the Ubuntu default)
APT::Install-Suggests "0";
@@ -0,0 +1 @@
APT::Acquire::Retries "3";
@@ -0,0 +1,3 @@
// Re-apply Chrome desktop-file flags after any package operation so
// that a google-chrome-stable upgrade does not silently drop them.
DPkg::Post-Invoke { "/opt/configure-chrome-flags.sh 2>/dev/null || true"; };
@@ -0,0 +1,6 @@
# Ref: https://github.com/nestybox/sysbox/issues/879
# We need to pin containerd to a specific version to avoid breaking
# Docker-in-Docker.
Package: containerd.io
Pin: version 1.7.23-1
Pin-Priority: 1001
@@ -0,0 +1,23 @@
# Ignore all packages from this repository by default
Package: *
Pin: origin download.docker.com
Pin-Priority: 1
# Docker Community Edition
# We need to pin docker-ce to a specific version because containerd is pinned
# to an older version. Newer major versions of docker-ce require a version of
# containerd.io greater than our pinned version.
Package: docker-ce
Pin: origin download.docker.com
Pin: version 5:29.*
Pin-Priority: 500
# Docker command-line tool
Package: docker-ce-cli
Pin: origin download.docker.com
Pin-Priority: 500
# containerd runtime
Package: containerd.io
Pin: origin download.docker.com
Pin-Priority: 500
@@ -0,0 +1,8 @@
# Ignore all packages from this repository by default
Package: *
Pin: origin cli.github.com
Pin-Priority: 1
Package: gh
Pin: origin cli.github.com
Pin-Priority: 500
@@ -0,0 +1,19 @@
# Ignore all packages from this repository by default
Package: *
Pin: origin packages.cloud.google.com
Pin-Priority: 1
# Google Cloud SDK for gcloud and gsutil CLI tools
Package: google-cloud-sdk
Pin: origin packages.cloud.google.com
Pin-Priority: 500
# Datastore emulator for working with the licensor
Package: google-cloud-sdk-datastore-emulator
Pin: origin packages.cloud.google.com
Pin-Priority: 500
# Kubectl for working with Kubernetes (GKE)
Package: kubectl
Pin: origin packages.cloud.google.com
Pin-Priority: 500
@@ -0,0 +1,14 @@
# Ignore all packages from this repository by default
Package: *
Pin: origin apt.releases.hashicorp.com
Pin-Priority: 1
# Packer for creating virtual machine disk images
Package: packer
Pin: origin apt.releases.hashicorp.com
Pin-Priority: 500
# Terraform for managing infrastructure
Package: terraform
Pin: origin apt.releases.hashicorp.com
Pin-Priority: 500
@@ -0,0 +1 @@
deb [signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu resolute stable
@@ -0,0 +1 @@
deb [signed-by=/usr/share/keyrings/google-cloud.gpg] https://packages.cloud.google.com/apt cloud-sdk main
@@ -0,0 +1 @@
deb [signed-by=/usr/share/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com noble main
@@ -0,0 +1 @@
deb [signed-by=/usr/share/keyrings/postgresql.gpg] https://apt.postgresql.org/pub/repos/apt resolute-pgdg main
@@ -0,0 +1,3 @@
{
"registry-mirrors": ["https://mirror.gcr.io"]
}
@@ -0,0 +1,31 @@
#!/bin/bash
# Adds launch flags to all Google Chrome .desktop files so that Chrome
# works correctly in headless / GPU-less environments (e.g. Coder
# workspaces running inside Docker containers).
#
# This script is idempotent.
set -euo pipefail
CHROME_FLAGS=(
--use-gl=angle
--use-angle=swiftshader
--disable-dev-shm-usage
--no-first-run
--no-default-browser-check
--disable-background-networking
--disable-sync
--start-maximized
)
FLAGS_STR="${CHROME_FLAGS[*]}"
for desktop_file in /usr/share/applications/google-chrome*.desktop /usr/share/applications/com.google.Chrome*.desktop; do
[ -f "$desktop_file" ] || continue
# Skip if flags are already present.
if grep -q -- '--use-gl=angle' "$desktop_file"; then
continue
fi
# Insert flags after the binary path on every Exec= line.
sed -i "s|Exec=/usr/bin/google-chrome-stable|Exec=/usr/bin/google-chrome-stable ${FLAGS_STR}|" "$desktop_file"
done
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
#
# Wrapper for the GitHub CLI (`gh`) that ensures authentication via
# `coder external-auth` when no other credentials are available.
#
# Precedence:
# 1. GH_TOKEN / GITHUB_TOKEN already set in environment
# 2. Existing `gh auth` login (e.g. `gh auth login`)
# 3. Fresh token from `coder external-auth access-token github`
REAL_GH="/usr/bin/gh"
# If GH_TOKEN or GITHUB_TOKEN is already set, defer to the real gh.
if [ -n "${GH_TOKEN:-}" ] || [ -n "${GITHUB_TOKEN:-}" ]; then
exec "$REAL_GH" "$@"
fi
# If the user has manually logged in via `gh auth login`, use that.
if "$REAL_GH" auth status >/dev/null 2>&1; then
exec "$REAL_GH" "$@"
fi
# Fall back to Coder's external auth for a fresh token (only in a workspace).
if [ "${CODER:-}" = "true" ]; then
TOKEN=$(coder external-auth access-token github 2>/dev/null)
if [ -n "$TOKEN" ]; then
GITHUB_TOKEN="$TOKEN" exec "$REAL_GH" "$@"
fi
fi
# Nothing worked; run gh anyway and let it show its own auth error.
exec "$REAL_GH" "$@"
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
curl_flags=(
--silent
--show-error
--location
)
gpg_flags=(
--dearmor
--yes
)
pushd "$PROJECT_ROOT/dogfood/coder/ubuntu-26.04/files/usr/share/keyrings"
# Upstream Docker signing key
curl "${curl_flags[@]}" "https://download.docker.com/linux/ubuntu/gpg" |
gpg "${gpg_flags[@]}" --output="docker.gpg"
# GitHub CLI signing key
curl "${curl_flags[@]}" "https://cli.github.com/packages/githubcli-archive-keyring.gpg" |
gpg "${gpg_flags[@]}" --output="github-cli.gpg"
# Google Cloud signing key
curl "${curl_flags[@]}" "https://packages.cloud.google.com/apt/doc/apt-key.gpg" |
gpg "${gpg_flags[@]}" --output="google-cloud.gpg"
# Hashicorp signing key
curl "${curl_flags[@]}" "https://apt.releases.hashicorp.com/gpg" |
gpg "${gpg_flags[@]}" --output="hashicorp.gpg"
# Upstream PostgreSQL signing key
curl "${curl_flags[@]}" "https://www.postgresql.org/media/keys/ACCC4CF8.asc" |
gpg "${gpg_flags[@]}" --output="postgresql.gpg"
popd
+11 -5
View File
@@ -3,7 +3,8 @@
# This script ensures that the same version of Go is referenced in all of the
# following files:
# - go.mod
# - dogfood/coder/Dockerfile
# - dogfood/coder/ubuntu-22.04/Dockerfile
# - dogfood/coder/ubuntu-26.04/Dockerfile
# - flake.nix
# - .github/actions/setup-go/action.yml
# The version of Go in go.mod is considered the source of truth.
@@ -18,18 +19,23 @@ cdroot
IGNORE_NIX=${IGNORE_NIX:-false}
GO_VERSION_GO_MOD=$(grep -Eo 'go [0-9]+\.[0-9]+\.[0-9]+' ./go.mod | cut -d' ' -f2)
GO_VERSION_DOCKERFILE=$(grep -Eo 'ARG GO_VERSION=[0-9]+\.[0-9]+\.[0-9]+' ./dogfood/coder/Dockerfile | cut -d'=' -f2)
GO_VERSION_DOCKERFILE_2204=$(grep -Eo 'ARG GO_VERSION=[0-9]+\.[0-9]+\.[0-9]+' ./dogfood/coder/ubuntu-22.04/Dockerfile | cut -d'=' -f2)
GO_VERSION_DOCKERFILE_2604=$(grep -Eo 'ARG GO_VERSION=[0-9]+\.[0-9]+\.[0-9]+' ./dogfood/coder/ubuntu-26.04/Dockerfile | cut -d'=' -f2)
GO_VERSION_SETUP_GO=$(yq '.inputs.version.default' .github/actions/setup-go/action.yaml)
GO_VERSION_FLAKE_NIX=$(grep -Eo '\bgo_[0-9]+_[0-9]+\b' ./flake.nix)
# Convert to major.minor format.
GO_VERSION_FLAKE_NIX_MAJOR_MINOR=$(echo "$GO_VERSION_FLAKE_NIX" | cut -d '_' -f 2-3 | tr '_' '.')
log "INFO : go.mod : $GO_VERSION_GO_MOD"
log "INFO : dogfood/coder/Dockerfile : $GO_VERSION_DOCKERFILE"
log "INFO : dogfood/coder/ubuntu-22.04/Dockerfile : $GO_VERSION_DOCKERFILE_2204"
log "INFO : dogfood/coder/ubuntu-26.04/Dockerfile : $GO_VERSION_DOCKERFILE_2604"
log "INFO : setup-go/action.yaml : $GO_VERSION_SETUP_GO"
log "INFO : flake.nix : $GO_VERSION_FLAKE_NIX_MAJOR_MINOR"
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_DOCKERFILE" ]; then
error "Go version mismatch between go.mod and dogfood/coder/Dockerfile:"
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_DOCKERFILE_2204" ]; then
error "Go version mismatch between go.mod and dogfood/coder/ubuntu-22.04/Dockerfile:"
fi
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_DOCKERFILE_2604" ]; then
error "Go version mismatch between go.mod and dogfood/coder/ubuntu-26.04/Dockerfile:"
fi
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_SETUP_GO" ]; then