Skip to content
Closed
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# Enterprise Example Images
# Coder Example Images

This repository contains example images for use with [Coder](https://coder.com/docs/v2/latest).

- `enterprise-base`: Contains an example image that can be used as a base for
- `example-base`: Contains an example image that can be used as a base for
other images.
- `enterprise-minimal`: Contains a minimal image that contains only the required
- `example-minimal`: Contains a minimal image that contains only the required
utilities for a Coder workspace to bootstrap successfully.
- `example-golang`: Contains Go development tools.
- `example-java`: Contains Java development tools.
- `example-node`: Contains Node.js development tools.
- `example-desktop`: Contains a desktop environment accessible via web browser.

## Images on Docker Hub

Each of these images is also published to Docker Hub under the
`codercom/enterprise-[name]` repository. For example, `base` is available at
https://hub.docker.com/r/codercom/enterprise-base. The tag is taken from the
Each of these images is published to Docker Hub under the
`codercom/example-[name]` repository. For example, `base` is available at
https://hub.docker.com/r/codercom/example-base. The tag is taken from the
filename of the Dockerfile. For example, `base/ubuntu.Dockerfile` is
under the `ubuntu` tag.

> For backward compatibility, these images are also available with the `enterprise-` prefix
> (e.g., `codercom/enterprise-base`), but the `example-` prefix is recommended for new deployments.

## Contributing

See our [contributing guide](.github/CONTRIBUTING.md).
Expand Down
4 changes: 2 additions & 2 deletions images/base/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Enterprise Base
# Example Base

[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/enterprise-base?label=codercom%2Fenterprise-base)](https://hub.docker.com/r/codercom/enterprise-base)
[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/example-base?label=codercom%2Fexample-base)](https://hub.docker.com/r/codercom/example-base)

## Description

Expand Down
4 changes: 2 additions & 2 deletions images/desktop/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Desktop

[![DockerPulls](https://img.shields.io/docker/pulls/codercom/enterprise-desktop)](https://hub.docker.com/r/codercom/enterprise-desktop)
[![DockerPulls](https://img.shields.io/docker/pulls/codercom/example-desktop)](https://hub.docker.com/r/codercom/example-desktop)

## Description

Wraps [enterprise-base](../base/README.md) with a xfce desktop environment.
Wraps [example-minimal](../minimal/README.md) with a xfce desktop environment.

> **Note:** This image does not contain a vnc-server.
> A VNC server can be added by using the [KasmVNC](https://registry.coder.com/modules/kasmvnc) module.
Expand Down
2 changes: 1 addition & 1 deletion images/desktop/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM codercom/enterprise-minimal:latest
FROM codercom/example-minimal:latest

USER root

Expand Down
4 changes: 2 additions & 2 deletions images/golang/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Golang

[![DockerPulls](https://img.shields.io/docker/pulls/codercom/enterprise-golang)](https://hub.docker.com/r/codercom/enterprise-golang)
[![DockerPulls](https://img.shields.io/docker/pulls/codercom/example-golang)](https://hub.docker.com/r/codercom/example-golang)

## Description

Wraps [enterprise-base](../base/README.md) with the basics for Go development.
Wraps [example-base](../base/README.md) with the basics for Go development.

> **Note:** This image does not contain GoLand. For an example of how to install
> GoLand, see [enterprise-goland](../../deprecated/goland/README.md)
Expand Down
2 changes: 1 addition & 1 deletion images/golang/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM codercom/enterprise-base:ubuntu
FROM codercom/example-base:ubuntu

# Run everything as root
USER root
Expand Down
4 changes: 2 additions & 2 deletions images/java/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Java

[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/enterprise-java?label=codercom%2Fenterprise-java)](https://hub.docker.com/r/codercom/enterprise-java)
[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/example-java?label=codercom%2Fexample-java)](https://hub.docker.com/r/codercom/example-java)

## Description

Wraps [enterprise-base](../base/README.md) with the basics for Java development.
Wraps [example-base](../base/README.md) with the basics for Java development.

> **Note:** This image does not contain IntelliJ. For an example of how to
> install IntelliJ, see [enterprise-intellij](../../deprecated/intellij/README.md)
Expand Down
2 changes: 1 addition & 1 deletion images/java/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM codercom/enterprise-base:ubuntu
FROM codercom/example-base:ubuntu

# Run everything as root
USER root
Expand Down
4 changes: 3 additions & 1 deletion images/minimal/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Minimal Image
# Example Minimal

[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/example-minimal?label=codercom%2Fexample-minimal)](https://hub.docker.com/r/codercom/example-minimal)

This image only contains the bare necessities:

Expand Down
4 changes: 2 additions & 2 deletions images/node/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Node

[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/enterprise-node?label=codercom%2Fenterprise-node)](https://hub.docker.com/r/codercom/enterprise-node)
[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/example-node?label=codercom%2Fexample-node)](https://hub.docker.com/r/codercom/example-node)

## Description

Wraps [enterprise-base](../base/README.md) with the basics for Node development.
Wraps [example-base](../base/README.md) with the basics for Node development.

## How To Use

Expand Down
2 changes: 1 addition & 1 deletion images/node/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM codercom/enterprise-base:ubuntu
FROM codercom/example-base:ubuntu

# Run everything as root
USER root
Expand Down
7 changes: 7 additions & 0 deletions images/universal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Example Universal Image

[![Docker Pulls](https://img.shields.io/docker/pulls/codercom/example-universal?label=codercom%2Fexample-universal)](https://hub.docker.com/r/codercom/example-universal)

## Description

Microsoft's [Universal Dev Container Image](https://github.com/devcontainers/images/tree/main/src/universal) extended with a `coder` user.
7 changes: 7 additions & 0 deletions images/universal/first-run-notice.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Welcome to Coder! This environment is based on Microsoft's Dev Container Universal image
with a suite of common tools and languages (Python, Java, Node.js, Go, Rust, etc.)

➡️ https://github.com/devcontainers/images/tree/main/src/universal

To use another image, modify your devcontainer.json or your Coder Template.

20 changes: 20 additions & 0 deletions images/universal/ubuntu.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM mcr.microsoft.com/devcontainers/universal:linux

USER root

COPY first-run-notice.txt /usr/local/etc/vscode-dev-containers/

# Remove Conda to avoid any license issues
RUN rm -R /opt/conda && \
rm /usr/local/etc/vscode-dev-containers/conda-notice.txt

RUN userdel -r codespace && \
useradd coder \
--create-home \
--shell=/bin/bash \
--groups=docker \
--uid=1000 \
--user-group && \
echo "coder ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers.d/nopasswd

USER coder
6 changes: 4 additions & 2 deletions scripts/build_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ fi
for image in "${IMAGES[@]}"; do
image_dir="$PROJECT_ROOT/images/$image"
image_file="${TAG}.Dockerfile"
image_ref="codercom/enterprise-$image:$TAG"
enterprise_image_ref="codercom/enterprise-$image:$TAG"
example_image_ref="codercom/example-$image:$TAG"
image_path="$image_dir/$image_file"

if [ ! -f "$image_path" ]; then
Expand All @@ -105,5 +106,6 @@ for image in "${IMAGES[@]}"; do
"${docker_flags[@]}" \
"$image_dir" \
--file="$image_path" \
--tag="$image_ref" \| indent
--tag="$example_image_ref" \
--tag="$enterprise_image_ref" \| indent
done
17 changes: 13 additions & 4 deletions scripts/push_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ date_str=$(date --utc +%Y%m%d)
for image in "${IMAGES[@]}"; do
image_dir="$PROJECT_ROOT/images/$image"
image_file="${TAG}.Dockerfile"
image_ref="codercom/enterprise-$image:$TAG"
image_ref_date="${image_ref}-${date_str}"
enterprise_image_ref="codercom/enterprise-$image:$TAG"
enterprise_image_ref_date="${enterprise_image_ref}-${date_str}"
example_image_ref="codercom/example-$image:$TAG"
example_image_ref_date="${example_image_ref}-${date_str}"
image_path="$image_dir/$image_file"

if [ ! -f "$image_path" ]; then
Expand All @@ -104,7 +106,14 @@ for image in "${IMAGES[@]}"; do
fi

build_id=$(cat "build_${image}.json" | jq -r .\[\"depot.build\"\].buildID)
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$image_ref" "$build_id"
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$image_ref_date" "$build_id"

# Push example images (primary)
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$example_image_ref" "$build_id"
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$example_image_ref_date" "$build_id"
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "codercom/example-${image}:latest" "$build_id"

# Push enterprise images (alias)
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$enterprise_image_ref" "$build_id"
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "$enterprise_image_ref_date" "$build_id"
run_trace $DRY_RUN depot push --project "gb3p8xrshk" --tag "codercom/enterprise-${image}:latest" "$build_id"
done
139 changes: 92 additions & 47 deletions scripts/scan_images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,58 +103,103 @@ trivy_tmp_dir="$(mktemp -d -p "$PROJECT_ROOT")"

trap 'rm -rf "$tmp_dir" "$trivy_tmp_dir"' EXIT

# Scan both example and enterprise images
for image in "${IMAGES[@]}"; do
image_ref="codercom/enterprise-${image}:${TAG}"
image_name="${image}-${TAG}"
output="${tmp_dir}/${image}-${TAG}.sarif"

if ! docker image inspect "$image_ref" >/dev/null 2>&1; then
echo "Image '$image_ref' does not exist locally; skipping" >&2
continue
fi

old_tmpdir="${TMPDIR:-}"
export TMPDIR="$trivy_tmp_dir"

# The timeout is set to 15 minutes because in Java images it can take a while
# to scan JAR files for vulnerabilities.
run_trace $DRY_RUN trivy image \
--severity CRITICAL,HIGH \
--format sarif \
--output "$output" \
--timeout 15m0s \
"$image_ref" 2>&1 | indent

if [ "$old_tmpdir" = "" ]; then
unset TMPDIR
# Process example images (primary)
example_image_ref="codercom/example-${image}:${TAG}"
example_image_name="example-${image}-${TAG}"
example_output="${tmp_dir}/example-${image}-${TAG}.sarif"

if docker image inspect "$example_image_ref" >/dev/null 2>&1; then
old_tmpdir="${TMPDIR:-}"
export TMPDIR="$trivy_tmp_dir"

# The timeout is set to 15 minutes because in Java images it can take a while
# to scan JAR files for vulnerabilities.
run_trace $DRY_RUN trivy image \
--severity CRITICAL,HIGH \
--format sarif \
--output "$example_output" \
--timeout 15m0s \
"$example_image_ref" 2>&1 | indent

if [ "$old_tmpdir" = "" ]; then
unset TMPDIR
else
export TMPDIR="$old_tmpdir"
fi

if [ $DRY_RUN = false ] && [ -f "$example_output" ]; then
# Do substitutions to add extra details to every message. Without these
# substitutions, most messages won't have any information about which image
# the vulnerability was found in.
jq \
".runs[].tool.driver.name |= \"Trivy ${example_image_name}\"" \
"$example_output" >"$example_output.tmp"
mv "$example_output.tmp" "$example_output"
jq \
".runs[].results[].locations[].physicalLocation.artifactLocation.uri |= \"${example_image_name}/\" + ." \
"$example_output" >"$example_output.tmp"
mv "$example_output.tmp" "$example_output"
jq \
".runs[].results[].locations[].message.text |= \"${example_image_name}: \" + ." \
"$example_output" >"$example_output.tmp"
mv "$example_output.tmp" "$example_output"
elif [ $DRY_RUN = false ]; then
echo "No SARIF output found for image '$example_image_ref' at '$example_output'" >&2
exit 1
fi
else
export TMPDIR="$old_tmpdir"
echo "Image '$example_image_ref' does not exist locally; skipping" >&2
fi

if [ $DRY_RUN = true ]; then
continue
fi

if [ ! -f "$output" ]; then
echo "No SARIF output found for image '$image_ref' at '$output'" >&2
exit 1
# Process enterprise images (alias)
enterprise_image_ref="codercom/enterprise-${image}:${TAG}"
enterprise_image_name="enterprise-${image}-${TAG}"
enterprise_output="${tmp_dir}/enterprise-${image}-${TAG}.sarif"

if docker image inspect "$enterprise_image_ref" >/dev/null 2>&1; then
old_tmpdir="${TMPDIR:-}"
export TMPDIR="$trivy_tmp_dir"

# The timeout is set to 15 minutes because in Java images it can take a while
# to scan JAR files for vulnerabilities.
run_trace $DRY_RUN trivy image \
--severity CRITICAL,HIGH \
--format sarif \
--output "$enterprise_output" \
--timeout 15m0s \
"$enterprise_image_ref" 2>&1 | indent

if [ "$old_tmpdir" = "" ]; then
unset TMPDIR
else
export TMPDIR="$old_tmpdir"
fi

if [ $DRY_RUN = false ] && [ -f "$enterprise_output" ]; then
# Do substitutions to add extra details to every message. Without these
# substitutions, most messages won't have any information about which image
# the vulnerability was found in.
jq \
".runs[].tool.driver.name |= \"Trivy ${enterprise_image_name}\"" \
"$enterprise_output" >"$enterprise_output.tmp"
mv "$enterprise_output.tmp" "$enterprise_output"
jq \
".runs[].results[].locations[].physicalLocation.artifactLocation.uri |= \"${enterprise_image_name}/\" + ." \
"$enterprise_output" >"$enterprise_output.tmp"
mv "$enterprise_output.tmp" "$enterprise_output"
jq \
".runs[].results[].locations[].message.text |= \"${enterprise_image_name}: \" + ." \
"$enterprise_output" >"$enterprise_output.tmp"
mv "$enterprise_output.tmp" "$enterprise_output"
elif [ $DRY_RUN = false ]; then
echo "No SARIF output found for image '$enterprise_image_ref' at '$enterprise_output'" >&2
exit 1
fi
else
echo "Image '$enterprise_image_ref' does not exist locally; skipping" >&2
fi

# Do substitutions to add extra details to every message. Without these
# substitutions, most messages won't have any information about which image
# the vulnerability was found in.
jq \
".runs[].tool.driver.name |= \"Trivy ${image_name}\"" \
"$output" >"$output.tmp"
mv "$output.tmp" "$output"
jq \
".runs[].results[].locations[].physicalLocation.artifactLocation.uri |= \"${image_name}/\" + ." \
"$output" >"$output.tmp"
mv "$output.tmp" "$output"
jq \
".runs[].results[].locations[].message.text |= \"${image_name}: \" + ." \
"$output" >"$output.tmp"
mv "$output.tmp" "$output"
done

# Merge all SARIF files into one.
Expand Down
Loading