Skip to content

Add dogfood image #3350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Aug 2, 2022
43 changes: 43 additions & 0 deletions .github/workflows/dogfood.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: dogfood

on:
push:
branches:
- main
tags:
- "*"
paths:
- "dogfood/**"
pull_request:
paths:
- "dogfood/**"
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Get branch name
id: branch-name
uses: tj-actions/branch-names@v5.4

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}

- name: Build and push
uses: docker/build-push-action@v3
with:
context: "{{defaultContext}}:dogfood"
push: true
tags: "codercom/oss-dogfood:${{ steps.branch-name.outputs.current_branch }},codercom/oss-dogfood:latest"
cache-from: type=registry,ref=codercom/oss-dogfood:latest
cache-to: type=inline
310 changes: 310 additions & 0 deletions dogfood/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
FROM rust:slim AS rust-utils
# Install rust helper programs
# ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
env CARGO_INSTALL_ROOT=/tmp/
RUN cargo install exa bat ripgrep typos-cli

FROM ubuntu AS go

RUN apt-get update && apt-get install --yes curl gcc
# Install Go manually, so that we can control the version
ARG GOBORING_VERSION=1.18b7
RUN mkdir --parents /usr/local/go /usr/local/goboring

# Boring Go is needed to build FIPS-compliant binaries.
RUN curl --silent --show-error --location \
"https://storage.googleapis.com/go-boringcrypto/go${GOBORING_VERSION}.linux-amd64.tar.gz" \
-o /usr/local/goboring.tar.gz

RUN tar --extract --gzip --directory=/usr/local/goboring --file=/usr/local/goboring.tar.gz --strip-components=1 && \
ln -s /usr/local/goboring/bin/go /usr/local/bin/go

# Install Go utilities.
ARG GOPATH="/tmp/"
RUN mkdir --parents "$GOPATH" && \
# moq for Go tests.
go install github.com/matryer/moq@v0.2.3 && \
# swag for Swagger doc generation
go install github.com/swaggo/swag/cmd/swag@v1.7.4 && \
# go-swagger tool to generate the go coder api client
go install github.com/go-swagger/go-swagger/cmd/swagger@v0.28.0 && \
# goimports for updating imports
go install golang.org/x/tools/cmd/goimports@v0.1.7 && \
# protoc-gen-go is needed to build sysbox from source
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26 && \
# drpc support for v2
go install storj.io/drpc/cmd/protoc-gen-go-drpc@v0.0.26 && \
# migrate for migration support for v2
go install github.com/golang-migrate/migrate/v4/cmd/migrate@v4.15.1 && \
# goreleaser for compiling v2 binaries
go install github.com/goreleaser/goreleaser@v1.6.1 && \
# Install the latest version of gopls for editors that support
# the language server protocol
go install golang.org/x/tools/gopls@latest && \
# gotestsum makes test output more readable
go install gotest.tools/gotestsum@v1.7.0 && \
# goveralls collects code coverage metrics from tests
# and sends to Coveralls
go install github.com/mattn/goveralls@v0.0.11 && \
# kind for running Kubernetes-in-Docker, needed for tests
go install sigs.k8s.io/kind@v0.10.0 && \
# helm-docs generates our Helm README based on a template and the
# charts and values files
go install github.com/norwoodj/helm-docs/cmd/helm-docs@v1.5.0 && \
# sqlc for Go code generation
go install github.com/kyleconroy/sqlc/cmd/sqlc@v1.10.0 && \
# gcr-cleaner-cli used by CI to prune unused images
go install github.com/sethvargo/gcr-cleaner/cmd/gcr-cleaner-cli@v0.5.1 && \
# 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 && \
# go-fuzz for fuzzy testing. they don't publish releases so we rely on latest.
go install github.com/dvyukov/go-fuzz/go-fuzz@latest && \
go install github.com/dvyukov/go-fuzz/go-fuzz-build@latest && \
# go-releaser for building 'fat binaries' that work cross-platform
go install github.com/goreleaser/goreleaser@v1.6.1

# Ubuntu 20.04 LTS (Focal Fossa)
FROM ubuntu:focal

SHELL ["/bin/bash", "-c"]

# 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.
RUN apt-get update && apt-get install --yes ca-certificates

COPY files /

# Install packages from apt repositories
ARG DEBIAN_FRONTEND="noninteractive"

RUN apt-get update --quiet && apt-get install --yes \
apt-transport-https \
apt-utils \
bash \
bash-completion \
bats \
bind9-dnsutils \
build-essential \
ca-certificates \
crypto-policies \
curl \
fd-find \
file \
git \
gnupg \
graphviz \
htop \
httpie \
inetutils-tools \
iproute2 \
iputils-ping \
iputils-tracepath \
jq \
language-pack-en \
less \
lsb-release \
man \
meld \
net-tools \
openjdk-11-jdk-headless \
openssh-server \
openssl \
pkg-config \
protobuf-compiler \
python3 \
python3-pip \
rsync \
shellcheck \
strace \
sudo \
tcptraceroute \
termshark \
traceroute \
vim \
wget \
xauth \
zip \
ncdu \
cargo \
asciinema \
zsh \
ansible \
neovim \
google-cloud-sdk \
google-cloud-sdk-datastore-emulator \
kubectl \
postgresql-11 \
containerd.io \
docker-ce \
docker-ce-cli \
packer \
terraform \
buildah \
conmon \
containernetworking-plugins \
crun \
podman \
skopeo \
gh && \
# Delete package cache to avoid consuming space in layer
apt-get clean && \
# Configure FIPS-compliant policies
update-crypto-policies --set FIPS

# Install frontend utilities
RUN apt-get update && \
# Node.js (from nodesource) and Yarn (from yarnpkg)
apt-get install --yes --quiet \
nodejs yarn \
# Install browsers for e2e testing
google-chrome-stable microsoft-edge-beta && \
# Pre-install system dependencies that Playwright needs. npx doesn't work here
# for some reason. See https://github.com/microsoft/playwright-cli/issues/136
npm i -g playwright@1.19.1 && playwright install-deps

# Ensure PostgreSQL binaries are in the users $PATH.
RUN update-alternatives --install /usr/local/bin/initdb initdb /usr/lib/postgresql/11/bin/initdb 100 && \
update-alternatives --install /usr/local/bin/postgres postgres /usr/lib/postgresql/11/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

# Install tools with published releases, where that is the
# preferred/recommended installation method.
ARG CLOUD_SQL_PROXY_VERSION=1.26.0 \
DIVE_VERSION=0.10.0 \
DOCKER_GCR_VERSION=2.1.0 \
GOLANGCI_LINT_VERSION=1.44.2 \
GRYPE_VERSION=0.24.0 \
HELM_VERSION=3.8.0 \
KUBE_LINTER_VERSION=0.2.5 \
KUBECTX_VERSION=0.9.4 \
STRIPE_VERSION=1.7.4 \
TERRAGRUNT_VERSION=0.34.1 \
TRIVY_VERSION=0.23.0

# cloud_sql_proxy, for connecting to cloudsql instances
# the upstream go.mod prevents this from being installed with go install
RUN curl --silent --show-error --location --output /usr/local/bin/cloud_sql_proxy "https://storage.googleapis.com/cloudsql-proxy/v${CLOUD_SQL_PROXY_VERSION}/cloud_sql_proxy.linux.amd64" && \
chmod a=rx /usr/local/bin/cloud_sql_proxy && \
# dive for scanning image layer utilization metrics in CI
curl --silent --show-error --location "https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- dive && \
# docker-credential-gcr is a Docker credential helper for pushing/pulling
# images from Google Container Registry and Artifact Registry
curl --silent --show-error --location "https://github.com/GoogleCloudPlatform/docker-credential-gcr/releases/download/v${DOCKER_GCR_VERSION}/docker-credential-gcr_linux_amd64-${DOCKER_GCR_VERSION}.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- docker-credential-gcr && \
# golangci-lint performs static code analysis for our Go code
curl --silent --show-error --location "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" && \
# Anchore Grype for scanning container images for security issues
curl --silent --show-error --location "https://github.com/anchore/grype/releases/download/v${GRYPE_VERSION}/grype_${GRYPE_VERSION}_linux_amd64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- grype && \
# Helm is necessary for deploying Coder
curl --silent --show-error --location "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 && \
# kube-linter for linting Kubernetes objects, including those
# that Helm generates from our charts
curl --silent --show-error --location "https://github.com/stackrox/kube-linter/releases/download/${KUBE_LINTER_VERSION}/kube-linter-linux.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- kube-linter && \
# kubens and kubectx for managing Kubernetes namespaces and contexts
curl --silent --show-error --location "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 "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 && \
# stripe for coder.com billing API
curl --silent --show-error --location "https://github.com/stripe/stripe-cli/releases/download/v${STRIPE_VERSION}/stripe_${STRIPE_VERSION}_linux_x86_64.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- stripe && \
# terragrunt for running Terraform and Terragrunt files
curl --silent --show-error --location --output /usr/local/bin/terragrunt "https://github.com/gruntwork-io/terragrunt/releases/download/v${TERRAGRUNT_VERSION}/terragrunt_linux_amd64" && \
chmod a=rx /usr/local/bin/terragrunt && \
# AquaSec Trivy for scanning container images for security issues
curl --silent --show-error --location "https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" | \
tar --extract --gzip --directory=/usr/local/bin --file=- trivy

# Add Vercel globally. We can't install it in packages.json, because it
# includes Go files which make golangci-lint unhappy.
RUN yarn global add --prefix=/usr/local \
vercel \
typescript \
typescript-language-server && \
yarn cache clean

# We use yq during "make deploy" to manually substitute out fields in
# our helm values.yaml file. See https://github.com/helm/helm/issues/3141
#
# TODO: update to 4.x, we can't do this now because it included breaking
# changes (yq w doesn't work anymore)
# RUN curl --silent --show-error --location "https://github.com/mikefarah/yq/releases/download/v4.9.0/yq_linux_amd64.tar.gz" | \
# tar --extract --gzip --directory=/usr/local/bin --file=- ./yq_linux_amd64 && \
# mv /usr/local/bin/yq_linux_amd64 /usr/local/bin/yq

RUN curl --silent --show-error --location --output /usr/local/bin/yq "https://github.com/mikefarah/yq/releases/download/3.3.0/yq_linux_amd64" && \
chmod a=rx /usr/local/bin/yq

# Install GoLand.
RUN mkdir --parents /usr/local/goland && \
curl --silent --show-error --location "https://download.jetbrains.com/go/goland-2021.2.tar.gz" | \
tar --extract --gzip --directory=/usr/local/goland --file=- --strip-components=1 && \
ln --symbolic /usr/local/goland/bin/goland.sh /usr/local/bin/goland

# Install Antlrv4, needed to generate paramlang lexer/parser
RUN curl --silent --show-error --location --output /usr/local/lib/antlr-4.9.2-complete.jar "https://www.antlr.org/download/antlr-4.9.2-complete.jar"
ENV CLASSPATH="/usr/local/lib/antlr-4.9.2-complete.jar:${PATH}"

# Add coder user and allow use of docker/sudo
RUN 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/goboring.tar.gz /usr/local/goboring.tar.gz
RUN mkdir /usr/local/goboring && \
tar --extract --gzip --directory=/usr/local/goboring --file=/usr/local/goboring.tar.gz --strip-components=1 && \
ln -s /usr/local/goboring/bin/go /usr/local/bin/go
COPY --from=go /tmp/bin /usr/local/bin

COPY --from=rust-utils /tmp/bin /usr/local/bin
RUN mv /usr/local/bin/exa /usr/local/bin/ls
RUN mv /usr/local/bin/bat /usr/local/bin/cat

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}"

# 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"
10 changes: 10 additions & 0 deletions dogfood/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: docker-build docker-push

branch=$(shell git rev-parse --abbrev-ref HEAD)
build_tag=codercom/oss-dogfood:${branch}

docker-build:
DOCKER_BUILDKIT=1 docker build . -t ${build_tag}

docker-push: docker-build
docker push ${build_tag}
6 changes: 6 additions & 0 deletions dogfood/files/etc/apt/apt.conf.d/80-no-recommends
Original file line number Diff line number Diff line change
@@ -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";
1 change: 1 addition & 0 deletions dogfood/files/etc/apt/apt.conf.d/80-retries
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
APT::Acquire::Retries "3";
20 changes: 20 additions & 0 deletions dogfood/files/etc/apt/preferences.d/docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Ignore all packages from this repository by default
Package: *
Pin: origin download.docker.com
Pin-Priority: 1

# Docker Community Edition
Package: docker-ce
Pin: origin download.docker.com
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: version 1.5.11-1
Pin-Priority: 500
Loading