chore: reduce docker examples (#6849)

This commit is contained in:
Ben Potter 2023-04-12 16:26:03 +00:00 committed by GitHub
parent 770712e1f5
commit af24aea04f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 5 additions and 596 deletions

View File

@ -25,8 +25,6 @@ var (
//go:embed templates/azure-linux
//go:embed templates/do-linux
//go:embed templates/docker
//go:embed templates/docker-code-server
//go:embed templates/docker-image-builds
//go:embed templates/docker-with-dotfiles
//go:embed templates/gcp-linux
//go:embed templates/gcp-vm-container

View File

@ -36,7 +36,7 @@ func TestTemplate(t *testing.T) {
func TestSubdirs(t *testing.T) {
t.Parallel()
tarData, err := examples.Archive("docker-image-builds")
tarData, err := examples.Archive("docker")
require.NoError(t, err)
tarReader := tar.NewReader(bytes.NewReader(tarData))
@ -51,6 +51,6 @@ func TestSubdirs(t *testing.T) {
entryPaths[header.Typeflag] = append(entryPaths[header.Typeflag], header.Name)
}
require.Subset(t, entryPaths[tar.TypeDir], []string{"images"})
require.Subset(t, entryPaths[tar.TypeReg], []string{"README.md", "main.tf", "images/base.Dockerfile"})
require.Subset(t, entryPaths[tar.TypeDir], []string{"build"})
require.Subset(t, entryPaths[tar.TypeReg], []string{"README.md", "main.tf", "build/Dockerfile"})
}

View File

@ -22,7 +22,7 @@ This will:
- Install Docker and Terraform from the official repos
- Install Coder using the [installation script](https://coder.com/docs/coder-oss/latest/install#installsh)
- Generates an initial user account `admin@coder.com` with a randomly generated password (stored in the VM under `/home/${USER}.linux/.config/coderv2/password`)
- Initializes a [sample Docker template](https://github.com/coder/coder/tree/main/examples/templates/docker-code-server) for creating workspaces
- Initializes a [sample Docker template](https://github.com/coder/coder/tree/main/examples/templates/docker) for creating workspaces
Once this completes, you can visit `http://localhost:3000` and start creating workspaces!

View File

@ -103,7 +103,7 @@ provision:
fi
DOCKER_HOST=$(docker context inspect --format '{{.Endpoints.docker.Host}}')
printf 'docker_arch: "%s"\ndocker_host: "%s"\n' "${DOCKER_ARCH}" "${DOCKER_HOST}" | tee "${temp_template_dir}/params.yaml"
coder templates create "docker-code-server-${DOCKER_ARCH}" --directory "${temp_template_dir}" --parameter-file "${temp_template_dir}/params.yaml" --yes
coder templates create "docker-${DOCKER_ARCH}" --directory "${temp_template_dir}" --parameter-file "${temp_template_dir}/params.yaml" --yes
rm -rfv "${temp_template_dir}"
probes:
- description: "docker to be installed"

View File

@ -1,26 +0,0 @@
---
name: Develop code-server in Docker
description: Run code-server in a Docker development environment
tags: [local, docker]
icon: /icon/docker.png
---
# code-server in Docker
## Getting started
Run `coder templates init` and select this template. Follow the instructions that appear.
## Supported Parameters
You can create a file containing parameters and pass the argument
`--parameter-file` to `coder templates create`.
See `params.sample.yaml` for more information.
This template has the following predefined parameters:
- `docker_host`: Path to (or address of) the Docker socket.
> You can determine the correct value for this by running
> `docker context ls`.
- `docker_arch`: Architecture of the host running Docker.
This can be `amd64`, `arm64`, or `armv7`.

View File

@ -1,124 +0,0 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.6.17"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
data "coder_provisioner" "me" {
}
provider "docker" {
}
data "coder_workspace" "me" {
}
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"
login_before_ready = false
startup_script_timeout = 180
startup_script = <<-EOT
set -e
code-server --auth none >/tmp/code-server.log 2>&1 &
EOT
# These environment variables allow you to make Git commits right away after creating a
# workspace. Note that they take precedence over configuration defined in ~/.gitconfig!
# You can remove this block if you'd prefer to configure Git manually or using
# dotfiles. (see docs/dotfiles.md)
env = {
GIT_AUTHOR_NAME = "${data.coder_workspace.me.owner}"
GIT_COMMITTER_NAME = "${data.coder_workspace.me.owner}"
GIT_AUTHOR_EMAIL = "${data.coder_workspace.me.owner_email}"
GIT_COMMITTER_EMAIL = "${data.coder_workspace.me.owner_email}"
}
}
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "code-server"
url = "http://localhost:8080/?folder=/home/coder"
icon = "/icon/code.svg"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:8080/healthz"
interval = 3
threshold = 10
}
}
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace.me.id}-home"
# Protect the volume from being deleted due to changes in attributes.
lifecycle {
ignore_changes = all
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace.me.owner
}
labels {
label = "coder.owner_id"
value = data.coder_workspace.me.owner_id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
# This field becomes outdated if the workspace is renamed but can
# be useful for debugging or cleaning out dangling volumes.
labels {
label = "coder.workspace_name_at_creation"
value = data.coder_workspace.me.name
}
}
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = "codercom/code-server:latest"
# Uses lower() to avoid Docker restriction on container names.
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
# Hostname makes the shell more user friendly: coder@my-workspace:~$
hostname = data.coder_workspace.me.name
# Use the docker gateway if the access URL is 127.0.0.1
entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
host {
host = "host.docker.internal"
ip = "host-gateway"
}
volumes {
container_path = "/home/coder/"
volume_name = docker_volume.home_volume.name
read_only = false
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace.me.owner
}
labels {
label = "coder.owner_id"
value = data.coder_workspace.me.owner_id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
labels {
label = "coder.workspace_name"
value = data.coder_workspace.me.name
}
}

View File

@ -1,2 +0,0 @@
docker_host: "unix:///var/run/docker.sock"
docker_arch: "amd64"

View File

@ -1,167 +0,0 @@
---
name: Develop in Docker with custom image builds
description: Build images and run workspaces on the Docker host with no image registry required
tags: [local, docker]
icon: /icon/docker.png
---
# docker-image-builds
This example bundles Dockerfiles with the Coder template, allowing the Docker host to build images itself instead of relying on an external registry.
For large use cases, we recommend building images using CI/CD pipelines and registries instead of at workspace runtime. However, this example is practical for tinkering and iterating on Dockerfiles.
## Getting started
Run `coder templates init`. When prompted, select this template, and follow the
on-screen instructions to proceed.
## Adding images
Create a Dockerfile (e.g `images/golang.Dockerfile`):
```console
vim images/golang.Dockerfile
```
```Dockerfile
# Start from base image (built on Docker host)
FROM coder-base:latest
# Install everything as root
USER root
# Install go
RUN curl -L "https://dl.google.com/go/go1.18.1.linux-amd64.tar.gz" | tar -C /usr/local -xzvf -
# Setup go env vars
ENV GOROOT /usr/local/go
ENV PATH $PATH:$GOROOT/bin
ENV GOPATH /home/coder/go
ENV GOBIN $GOPATH/bin
ENV PATH $PATH:$GOBIN
# Set back to coder user
USER coder
```
Edit the Terraform template (`main.tf`):
```console
vim main.tf
```
Edit the validation to include the new image:
```diff
variable "docker_image" {
description = "What Docker image would you like to use for your workspace?"
default = "base"
# List of images available for the user to choose from.
# Delete this condition to give users free text input.
validation {
- condition = contains(["base", "java", "node"], var.docker_image)
+ condition = contains(["base", "java", "node", "golang], var.docker_image)
error_message = "Invalid Docker image!"
}
}
```
Bump the image tag to a new version:
```diff
resource "docker_image" "coder_image" {
name = "coder-base-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
build {
path = "./images/"
dockerfile = "${var.docker_image}.Dockerfile"
- tag = ["coder-${var.docker_image}:v0.1"]
+ tag = ["coder-${var.docker_image}:v0.2"]
}
# Keep alive for other workspaces to use upon deletion
keep_locally = true
}
```
Update the template:
```console
coder template push docker-image-builds
```
You can also remove images from the validation list. Workspaces using older template versions will continue using
the removed image until you update the workspace to the latest version.
## Updating images
Edit the Dockerfile (or related assets):
```console
vim images/node.Dockerfile
```
```diff
# Install Node
- RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
+ RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN DEBIAN_FRONTEND="noninteractive" apt-get update -y && \
apt-get install -y nodejs
```
1. Edit the Terraform template (`main.tf`)
```console
vim main.tf
```
Bump the image tag to a new version:
```diff
resource "docker_image" "coder_image" {
name = "coder-base-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
build {
path = "./images/"
dockerfile = "${var.docker_image}.Dockerfile"
- tag = ["coder-${var.docker_image}:v0.1"]
+ tag = ["coder-${var.docker_image}:v0.2"]
}
# Keep alive for other workspaces to use upon deletion
keep_locally = true
}
```
Update the template:
```console
coder template push docker-image-builds
```
Optional: Update workspaces to the latest template version
```console
coder ls
coder update [workspace name]
```
## code-server
`code-server` is installed via the `startup_script` argument in the `coder_agent`
resource block. The `coder_app` resource is defined to access `code-server` through
the dashboard UI over `localhost:13337`.
## Extending this template
See the [kreuzwerker/docker](https://registry.terraform.io/providers/kreuzwerker/docker) Terraform provider documentation to
add the following features to your Coder template:
- SSH/TCP docker host
- Build args
- Volume mounts
- Custom container spec
- More
We also welcome all contributions!

View File

@ -1,33 +0,0 @@
FROM ubuntu:20.04
RUN apt-get update && \
DEBIAN_FRONTEND="noninteractive" apt-get install --yes \
bash \
build-essential \
ca-certificates \
curl \
htop \
locales \
man \
python3 \
python3-pip \
software-properties-common \
sudo \
systemd \
systemd-sysv \
unzip \
vim \
wget && \
# Install latest Git using their official PPA
add-apt-repository ppa:git-core/ppa && \
DEBIAN_FRONTEND="noninteractive" apt-get install --yes git
# Add a user `coder` so that you're not developing as the `root` user
RUN useradd coder \
--create-home \
--shell=/bin/bash \
--uid=1000 \
--user-group && \
echo "coder ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers.d/nopasswd
USER coder

View File

@ -1,57 +0,0 @@
# From the base image (built on Docker host)
FROM coder-base:v0.1
# Install everything as root
USER root
# Install JDK (OpenJDK 8)
RUN DEBIAN_FRONTEND="noninteractive" apt-get update -y && \
apt-get install -y openjdk-11-jdk
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64
ENV PATH $PATH:$JAVA_HOME/bin
# Install Maven
ARG MAVEN_VERSION=3.6.3
ARG MAVEN_SHA512=c35a1803a6e70a126e80b2b3ae33eed961f83ed74d18fcd16909b2d44d7dada3203f1ffe726c17ef8dcca2dcaa9fca676987befeadc9b9f759967a8cb77181c0
ENV MAVEN_HOME /usr/share/maven
ENV MAVEN_CONFIG "/home/coder/.m2"
RUN mkdir -p $MAVEN_HOME $MAVEN_HOME/ref \
&& echo "Downloading Maven" \
&& curl -fsSL -o /tmp/apache-maven.tar.gz https://apache.osuosl.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
\
&& echo "Checking downloaded file hash" \
&& echo "${MAVEN_SHA512} /tmp/apache-maven.tar.gz" | sha512sum -c - \
\
&& echo "Unzipping Maven" \
&& tar -xzf /tmp/apache-maven.tar.gz -C $MAVEN_HOME --strip-components=1 \
\
&& echo "Cleaning and setting links" \
&& rm -f /tmp/apache-maven.tar.gz \
&& ln -s $MAVEN_HOME/bin/mvn /usr/bin/mvn
# Install Gradle
ENV GRADLE_VERSION=6.7
ARG GRADLE_SHA512=d495bc65379d2a854d2cca843bd2eeb94f381e5a7dcae89e6ceb6ef4c5835524932313e7f30d7a875d5330add37a5fe23447dc3b55b4d95dffffa870c0b24493
ENV GRADLE_HOME /usr/bin/gradle
RUN mkdir -p /usr/share/gradle /usr/share/gradle/ref \
&& echo "Downloading Gradle" \
&& curl -fsSL -o /tmp/gradle.zip https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip \
\
&& echo "Checking downloaded file hash" \
&& echo "${GRADLE_SHA512} /tmp/gradle.zip" | sha512sum -c - \
\
&& echo "Unziping gradle" \
&& unzip -d /usr/share/gradle /tmp/gradle.zip \
\
&& echo "Cleaning and setting links" \
&& rm -f /tmp/gradle.zip \
&& ln -s /usr/share/gradle/gradle-${GRADLE_VERSION} /usr/bin/gradle
ENV PATH $PATH:$GRADLE_HOME/bin
# Set back to coder user
USER coder

View File

@ -1,18 +0,0 @@
# Start from base image (built on Docker host)
FROM coder-base:v0.1
# Install everything as root
USER root
# Install Node
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN DEBIAN_FRONTEND="noninteractive" apt-get update -y && \
apt-get install -y nodejs
# Install Yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN DEBIAN_FRONTEND="noninteractive" apt-get update && apt-get install -y yarn
# Set back to coder user
USER coder

View File

@ -1,162 +0,0 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.6.17"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
data "coder_provisioner" "me" {
}
provider "docker" {
}
data "coder_workspace" "me" {
}
resource "coder_agent" "main" {
arch = data.coder_provisioner.me.arch
os = "linux"
login_before_ready = false
startup_script_timeout = 180
startup_script = <<-EOT
set -e
# install and start code-server
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.11.0
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
EOT
}
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "code-server"
url = "http://localhost:13337/?folder=/home/coder"
icon = "/icon/code.svg"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:13337/healthz"
interval = 3
threshold = 10
}
}
data "coder_parameter" "docker_image" {
name = "What Docker image would you like to use for your workspace?"
description = "The Docker image will be used to build your workspace. You can choose from a list of pre-built images or provide your own."
default = "base"
icon = "/icon/docker.png"
type = "string"
mutable = false
option {
name = "Base"
value = "base"
icon = "/icon/code.svg"
}
option {
name = "Java"
value = "java"
icon = "/icon/java.svg"
}
option {
name = "Node"
value = "node"
icon = "/icon/node.svg"
}
}
resource "docker_volume" "home_volume" {
name = "coder-${data.coder_workspace.me.id}-home"
# Protect the volume from being deleted due to changes in attributes.
lifecycle {
ignore_changes = all
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace.me.owner
}
labels {
label = "coder.owner_id"
value = data.coder_workspace.me.owner_id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
# This field becomes outdated if the workspace is renamed but can
# be useful for debugging or cleaning out dangling volumes.
labels {
label = "coder.workspace_name_at_creation"
value = data.coder_workspace.me.name
}
}
resource "docker_image" "coder_image" {
name = "coder-base-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
build {
context = "./images/"
dockerfile = "${data.coder_parameter.docker_image.value}.Dockerfile"
tag = ["coder-${data.coder_parameter.docker_image.value}:v0.1"]
}
# Keep alive for other workspaces to use upon deletion
keep_locally = true
}
resource "docker_container" "workspace" {
count = data.coder_workspace.me.start_count
image = docker_image.coder_image.image_id
# Uses lower() to avoid Docker restriction on container names.
name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}"
# Hostname makes the shell more user friendly: coder@my-workspace:~$
hostname = data.coder_workspace.me.name
# Use the docker gateway if the access URL is 127.0.0.1
entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")]
env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"]
host {
host = "host.docker.internal"
ip = "host-gateway"
}
volumes {
container_path = "/home/coder/"
volume_name = docker_volume.home_volume.name
read_only = false
}
# Add labels in Docker to keep track of orphan resources.
labels {
label = "coder.owner"
value = data.coder_workspace.me.owner
}
labels {
label = "coder.owner_id"
value = data.coder_workspace.me.owner_id
}
labels {
label = "coder.workspace_id"
value = data.coder_workspace.me.id
}
labels {
label = "coder.workspace_name"
value = data.coder_workspace.me.name
}
}
resource "coder_metadata" "container_info" {
count = data.coder_workspace.me.start_count
resource_id = docker_container.workspace[0].id
item {
key = "image"
value = data.coder_parameter.docker_image.value
}
}