|
| 1 | +--- |
| 2 | +name: Develop in Docker with custom image builds |
| 3 | +description: Builds images and runs workspaces on the Docker host, no image registry required |
| 4 | +tags: [local, docker] |
| 5 | +--- |
| 6 | + |
| 7 | +# docker-image-builds |
| 8 | + |
| 9 | +This example bundles Dockerfiles in the Coder template, allowing the Docker host to build images itself instead of relying on an external registry. |
| 10 | + |
| 11 | +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. |
| 12 | + |
| 13 | +## Getting started |
| 14 | + |
| 15 | +Pick this template in `coder templates init` and follow instructions. |
| 16 | + |
| 17 | +## Adding images |
| 18 | + |
| 19 | +Create a Dockerfile (e.g `images/golang.Dockerfile`) |
| 20 | + |
| 21 | +```sh |
| 22 | +vim images/golang.Dockerfile |
| 23 | +``` |
| 24 | + |
| 25 | +```Dockerfile |
| 26 | +# Start from base image (built on Docker host) |
| 27 | +FROM coder-base:latest |
| 28 | + |
| 29 | +# Install everything as root |
| 30 | +USER root |
| 31 | + |
| 32 | +# Install go |
| 33 | +RUN curl -L "https://dl.google.com/go/go1.17.1.linux-amd64.tar.gz" | tar -C /usr/local -xzvf - |
| 34 | + |
| 35 | +# Setup go env vars |
| 36 | +ENV GOROOT /usr/local/go |
| 37 | +ENV PATH $PATH:$GOROOT/bin |
| 38 | + |
| 39 | +ENV GOPATH /home/coder/go |
| 40 | +ENV GOBIN $GOPATH/bin |
| 41 | +ENV PATH $PATH:$GOBIN |
| 42 | + |
| 43 | +# Set back to coder user |
| 44 | +USER coder |
| 45 | +``` |
| 46 | + |
| 47 | +Edit the template Terraform (`main.tf`) |
| 48 | + |
| 49 | +```sh |
| 50 | +vim main.tf |
| 51 | +``` |
| 52 | + |
| 53 | +Edit the validation to include the new image: |
| 54 | + |
| 55 | +```diff |
| 56 | +variable "docker_image" { |
| 57 | + description = "What docker image would you like to use for your workspace?" |
| 58 | + default = "base" |
| 59 | + |
| 60 | + # List of images available for the user to choose from. |
| 61 | + # Delete this condition to give users free text input. |
| 62 | + validation { |
| 63 | +- condition = contains(["base", "java", "node"], var.docker_image) |
| 64 | ++ condition = contains(["base", "java", "node", "golang], var.docker_image) |
| 65 | + error_message = "Invalid Docker Image!" |
| 66 | + } |
| 67 | +} |
| 68 | +``` |
| 69 | + |
| 70 | +Bump the image tag to a new version: |
| 71 | + |
| 72 | +```diff |
| 73 | +resource "docker_image" "coder_image" { |
| 74 | + name = "coder-base-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" |
| 75 | + build { |
| 76 | + path = "./images/" |
| 77 | + dockerfile = "${var.docker_image}.Dockerfile" |
| 78 | +- tag = ["coder-${var.docker_image}:v0.1"] |
| 79 | ++ tag = ["coder-${var.docker_image}:v0.2"] |
| 80 | + } |
| 81 | + |
| 82 | + # Keep alive for other workspaces to use upon deletion |
| 83 | + keep_locally = true |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +Update the template: |
| 88 | + |
| 89 | +```sh |
| 90 | +coder template update docker-image-builds |
| 91 | +``` |
| 92 | + |
| 93 | +Images can also be removed from the validation list. Workspaces using older template versions will continue using |
| 94 | +the removed image until the workspace is updated to the latest version. |
| 95 | + |
| 96 | +## Updating images |
| 97 | + |
| 98 | +Edit the Dockerfile (or related assets) |
| 99 | + |
| 100 | +```sh |
| 101 | +vim images/node.Dockerfile |
| 102 | +``` |
| 103 | + |
| 104 | +```diff |
| 105 | +# Install Node |
| 106 | +- RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - |
| 107 | ++ RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - |
| 108 | +RUN DEBIAN_FRONTEND="noninteractive" apt-get update -y && \ |
| 109 | + apt-get install -y nodejs |
| 110 | +``` |
| 111 | + |
| 112 | +1. Edit the template Terraform (`main.tf`) |
| 113 | + |
| 114 | +```sh |
| 115 | +vim main.tf |
| 116 | +``` |
| 117 | + |
| 118 | +Bump the image tag to a new version: |
| 119 | + |
| 120 | +```diff |
| 121 | +resource "docker_image" "coder_image" { |
| 122 | + name = "coder-base-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" |
| 123 | + build { |
| 124 | + path = "./images/" |
| 125 | + dockerfile = "${var.docker_image}.Dockerfile" |
| 126 | +- tag = ["coder-${var.docker_image}:v0.1"] |
| 127 | ++ tag = ["coder-${var.docker_image}:v0.2"] |
| 128 | + } |
| 129 | + |
| 130 | + # Keep alive for other workspaces to use upon deletion |
| 131 | + keep_locally = true |
| 132 | +} |
| 133 | +``` |
| 134 | + |
| 135 | +Update the template: |
| 136 | + |
| 137 | +```sh |
| 138 | +coder template update docker-image-builds |
| 139 | +``` |
| 140 | + |
| 141 | +Optional: Update workspaces to the latest template version |
| 142 | + |
| 143 | +```sh |
| 144 | +coder ls |
| 145 | +coder update [workspace name] |
| 146 | +``` |
| 147 | + |
| 148 | +## Extending this template |
| 149 | + |
| 150 | +See the [kreuzwerker/docker](https://registry.terraform.io/providers/kreuzwerker/docker) Terraform provider documentation to |
| 151 | +add the following features to your Coder template: |
| 152 | + |
| 153 | +- SSH/TCP docker host |
| 154 | +- Build args |
| 155 | +- Volume mounts |
| 156 | +- Custom container spec |
| 157 | +- More |
| 158 | + |
| 159 | +Contributions are also welcome! |
0 commit comments