diff --git a/docs/images/templates/coder-login-web.png b/docs/images/templates/coder-login-web.png index 161ff92a00401..423cc17f06a22 100644 Binary files a/docs/images/templates/coder-login-web.png and b/docs/images/templates/coder-login-web.png differ diff --git a/docs/images/templates/coder-session-token.png b/docs/images/templates/coder-session-token.png index f982550901813..571c28ccd0568 100644 Binary files a/docs/images/templates/coder-session-token.png and b/docs/images/templates/coder-session-token.png differ diff --git a/docs/images/templates/upload-create-template-form.png b/docs/images/templates/upload-create-template-form.png new file mode 100644 index 0000000000000..e2d038e602bb8 Binary files /dev/null and b/docs/images/templates/upload-create-template-form.png differ diff --git a/docs/images/templates/upload-create-your-first-template.png b/docs/images/templates/upload-create-your-first-template.png new file mode 100644 index 0000000000000..858a8533f0c3c Binary files /dev/null and b/docs/images/templates/upload-create-your-first-template.png differ diff --git a/docs/images/templates/workspace-apps.png b/docs/images/templates/workspace-apps.png index cf4f8061899e6..4ace0f542ff4a 100644 Binary files a/docs/images/templates/workspace-apps.png and b/docs/images/templates/workspace-apps.png differ diff --git a/docs/tutorials/template-from-scratch.md b/docs/tutorials/template-from-scratch.md index c1a9b556fdae2..3198b622724bf 100644 --- a/docs/tutorials/template-from-scratch.md +++ b/docs/tutorials/template-from-scratch.md @@ -1,30 +1,15 @@ -# A guided tour of a template +# Write a template from scratch -This guided tour introduces you to the different parts of a Coder template by -showing you how to create a template from scratch. +A template is a common configuration that you use to deploy workspaces. -You'll write a simple template that provisions a workspace as a Docker container -with Ubuntu. +This tutorial teaches you how to create a template that provisions a workspace +as a Docker container with Ubuntu. ## Before you start -To follow this guide, you'll need: - -- A computer or cloud computing instance with both - [Docker](https://docs.docker.com/get-docker/) and [Coder](../install/index.md) - installed on it. - -> When setting up your computer or computing instance, make sure to install -> Docker first, then Coder. Otherwise, you'll need to add the `coder` user to -> the `docker` group. - -- The URL for your Coder instance. If you're running Coder locally, the default - URL is [http://127.0.0.1:3000](http://127.0.0.1:3000). - -- A text editor. For this tour, we use [GNU nano](https://nano-editor.org/). - -> Haven't written Terraform before? Check out Hashicorp's -> [Getting Started Guides](https://developer.hashicorp.com/terraform/tutorials). +You'll need a computer or cloud computing instance with both +[Docker](https://docs.docker.com/get-docker/) and [Coder](../install/index.md) +installed on it. ## What's in a template @@ -36,25 +21,25 @@ Coder can provision all Terraform modules, resources, and properties. The Coder server essentially runs a `terraform apply` every time a workspace is created, started, or stopped. +> Haven't written Terraform before? Check out Hashicorp's +> [Getting Started Guides](https://developer.hashicorp.com/terraform/tutorials). + Here's a simplified diagram that shows the main parts of the template we'll -create. +create: ![Template architecture](../images/templates/template-architecture.png) ## 1. Create template files On your local computer, create a directory for your template and create the -`Dockerfile`. +`Dockerfile`. You will upload the files to your Coder instance later. ```sh -mkdir template-tour -cd template-tour -mkdir build -nano build/Dockerfile +mkdir -p template-tour/build && cd $_ ``` -You'll enter a simple `Dockerfile` that starts with the -[official Ubuntu image](https://hub.docker.com/_/ubuntu/). In the editor, enter +Enter content into a `Dockerfile` that starts with the +[official Ubuntu image](https://hub.docker.com/_/ubuntu/). In your editor, enter and save the following text in `Dockerfile` then exit the editor: ```dockerfile @@ -72,56 +57,48 @@ RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \ && chmod 0440 /etc/sudoers.d/${USER} USER ${USER} WORKDIR /home/${USER} - ``` -Notice how `Dockerfile` adds a few things to the parent `ubuntu` image, which -your template needs later: +`Dockerfile` adds a few things to the parent `ubuntu` image, which your template +needs later: - It installs the `sudo` and `curl` packages. - It adds a `coder` user, including a home directory. ## 2. Set up template providers -Now you can edit the Terraform file, which provisions the workspace's resources. - -```shell -nano main.tf -``` +Edit the Terraform `main.tf` file to provision the workspace's resources. -We'll start by setting up our providers. At a minimum, we need the `coder` -provider. For this template, we also need the `docker` provider: +Start by setting up the providers. At a minimum, we need the `coder` provider. +For this template, we also need the `docker` provider: ```tf terraform { required_providers { coder = { source = "coder/coder" - version = "~> 0.8.3" } docker = { source = "kreuzwerker/docker" - version = "~> 3.0.1" } } } -provider "coder" { +locals { + username = data.coder_workspace_owner.me.name } -provider "docker" { +data "coder_provisioner" "me" { } -locals { - username = data.coder_workspace.me.owner +provider "docker" { } -data "coder_provisioner" "me" { +provider "coder" { } data "coder_workspace" "me" { } - ``` Notice that the `provider` blocks for `coder` and `docker` are empty. In a more @@ -132,8 +109,7 @@ The [`coder_workspace`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace) data source provides details about the state of a workspace, such as its name, owner, and so on. The data source also lets us know when a workspace is being -started or stopped. We'll take advantage of this information in later steps to -do these things: +started or stopped. We'll use this information in later steps to: - Set some environment variables based on the workspace owner. - Manage ephemeral and persistent storage. @@ -147,29 +123,27 @@ runs inside the compute aspect of your workspace, typically a VM or container. In our case, it will run in Docker. You do not need to have any open ports on the compute aspect, but the agent -needs `curl` access to the Coder server. Remember that we installed `curl` in -`Dockerfile`, earlier. +needs `curl` access to the Coder server. -This snippet creates the agent: +Add this snippet after the last closing `}` in `main.tf` to create the agent: ```tf resource "coder_agent" "main" { arch = data.coder_provisioner.me.arch os = "linux" - 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 + curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server /tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 & EOT 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}" + GIT_AUTHOR_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_AUTHOR_EMAIL = "${data.coder_workspace_owner.me.email}" + GIT_COMMITTER_NAME = coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) + GIT_COMMITTER_EMAIL = "${data.coder_workspace_owner.me.email}" } metadata { @@ -188,34 +162,37 @@ resource "coder_agent" "main" { timeout = 1 } } - ``` Because Docker is running locally in the Coder server, there is no need to -authenticate `coder_agent`. But if your `coder_agent` were running on a remote -host, your template would need +authenticate `coder_agent`. But if your `coder_agent` is running on a remote +host, your template will need [authentication credentials](../admin/external-auth.md). This template's agent also runs a startup script, sets environment variables, and provides metadata. -The -[`startup script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script) -installs [code-server](https://coder.com/docs/code-server), a browser-based -[VS Code](https://code.visualstudio.com/) app that runs in the workspace. We'll -give users access to code-server through `coder_app`, later. +- [`startup script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script) -The -[`env`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#env) -block sets environments variables for the workspace. We use the data source from -`coder_workspace` to set the environment variables based on the workspace's -owner. This way, the owner can make git commits immediately without any manual -configuration. + - Installs [code-server](https://coder.com/docs/code-server), a browser-based + [VS Code](https://code.visualstudio.com/) app that runs in the workspace. + + We'll give users access to code-server through `coder_app`, later. + +- [`env` block](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#env) + + - Sets environments variables for the workspace. + + We use the data source from `coder_workspace` to set the environment + variables based on the workspace's owner. This way, the owner can make git + commits immediately without any manual configuration. + +- [`metadata`](../admin/templates/extending-templates/agent-metadata.md) blocks + + - Your template can use metadata to show information to the workspace owner + Coder displays this metadata in the Coder dashboard. -Your template can use metadata to show information to the workspace owner. Coder -displays this metadata in the Coder dashboard. Our template has -[`metadata`](../admin/templates/extending-templates/agent-metadata.md) blocks -for CPU and RAM usage. + Our template has `metadata` blocks for CPU and RAM usage. ## 4. coder_app @@ -229,10 +206,9 @@ This is commonly used for [web IDEs](../user-guides/workspace-access/web-ides.md) such as [code-server](https://coder.com/docs/code-server), RStudio, and JupyterLab. -To install and code-server in the workspace, remember that we installed it in -the `startup_script` argument in `coder_agent`. We make it available from a -workspace with a `coder_app` resource. See -[web IDEs](../user-guides/workspace-access/web-ides.md) for more examples. +We installed code-server in the `startup_script` argument. To add code-server to +the workspace, make it available in the workspace with a `coder_app` resource. +See [web IDEs](../user-guides/workspace-access/web-ides.md) for more examples: ```tf resource "coder_app" "code-server" { @@ -250,11 +226,10 @@ resource "coder_app" "code-server" { threshold = 6 } } - ``` You can also use a `coder_app` resource to link to external apps, such as links -to wikis or cloud consoles. +to wikis or cloud consoles: ```tf resource "coder_app" "coder-server-doc" { @@ -264,7 +239,6 @@ resource "coder_app" "coder-server-doc" { url = "https://coder.com/docs/code-server" external = true } - ``` ## 5. Persistent and ephemeral resources @@ -283,10 +257,9 @@ We do this in 2 parts: workspace name change, we use an immutable parameter, like `data.coder_workspace.me.id`. -You'll see later that we make sure that our Docker container is ephemeral with -the Terraform +Later, we use the Terraform [count](https://developer.hashicorp.com/terraform/language/meta-arguments/count) -meta-argument. +meta-argument to make sure that our Docker container is ephemeral. ```tf resource "docker_volume" "home_volume" { @@ -296,7 +269,6 @@ resource "docker_volume" "home_volume" { ignore_changes = all } } - ``` For details, see @@ -305,7 +277,7 @@ For details, see ## 6. Set up the Docker container To set up our Docker container, our template has a `docker_image` resource that -uses `build/Dockerfile`, which we created earlier. +uses `build/Dockerfile`, which we created earlier: ```tf resource "docker_image" "main" { @@ -320,7 +292,6 @@ resource "docker_image" "main" { dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)])) } } - ``` Our `docker_container` resource uses `coder_workspace` `start_count` to start @@ -331,7 +302,7 @@ resource "docker_container" "workspace" { count = data.coder_workspace.me.start_count image = docker_image.main.name # Uses lower() to avoid Docker restriction on container names. - name = "coder-${data.coder_workspace.me.owner}-${lower(data.coder_workspace.me.name)}" + name = "coder-${data.coder_workspace_owner.me.name}-${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 @@ -349,7 +320,6 @@ resource "docker_container" "workspace" { read_only = false } } - ``` ## 7. Create the template in Coder @@ -359,59 +329,102 @@ Save `main.tf` and exit the editor. Now that we've created the files for our template, we can add them to our Coder deployment. -We can do this with the Coder CLI or the Coder dashboard. For this tour, we'll +We can do this with the Coder CLI or the Coder dashboard. In this example, we'll use the Coder CLI. -First, you'll need to log in to your Coder deployment from the CLI. This is -where you need the URL for your deployment: +1. Log in to your Coder deployment from the CLI. This is where you need the URL + for your deployment: -```sh -$ coder login https://coder.example.com -Your browser has been opened to visit: + ```console + $ coder login https://coder.example.com + Attempting to authenticate with config URL: 'https://coder.example.com' + Open the following in your browser: - https://coder.example.com/cli-auth + https://coder.example.com/cli-auth -> Paste your token here: -``` + > Paste your token here: + ``` -In your web browser, enter your credentials: +1. In your web browser, enter your credentials: -![Logging in to your Coder deployment](../images/templates/coder-login-web.png) + Log in to your Coder deployment -Copy the session token into the clipboard: +1. Copy the session token to the clipboard: -![Logging in to your Coder deployment](../images/templates/coder-session-token.png) + Copy session token -And paste it into the CLI: +1. Paste it into the CLI: -```sh -> Welcome to Coder, marc! You're authenticated. -$ -``` + ```output + > Welcome to Coder, marc! You're authenticated. + $ + ``` -Now you can add your template files to your Coder deployment: +### Add the template files to Coder -```sh -$ pwd -/home/marc/template-tour -$ coder templates create -> Upload "."? (yes/no) yes -``` +Add your template files to your Coder deployment. You can upload the template +through the CLI, or through the Coder dashboard: -The Coder CLI tool gives progress information then prompts you to confirm: +
-```sh -> Confirm create? (yes/no) yes +#### CLI + +1. Run `coder templates create` from the directory with your template files: + + ```console + $ pwd + /home/docs/template-tour + $ coder templates push + > Upload "."? (yes/no) yes + ``` + +1. The Coder CLI tool gives progress information then prompts you to confirm: -The template-tour template has been created! Developers can provision a workspace with this template using: + ```console + > Confirm create? (yes/no) yes + + The template-tour template has been created! Developers can provision a workspace with this template using: coder create --template="template-tour" [workspace name] -``` + ``` + +1. In your web browser, log in to your Coder dashboard, select **Templates**. + +1. Once the upload completes, select **Templates** from the top to deploy it to + a new workspace. + + ![Your new template, ready to use](../images/templates/template-tour.png) + +#### Dashboard + +1. Create a `.zip` of the template files. + + - On Mac or Windows, highlight the files and then right click. A "compress" + option is available through the right-click context menu. + + - To zip the files through the command line: + + ```shell + zip templates.zip Dockerfile main.tf + ``` + +1. Select **Templates** from the top of the Coder dashboard, then **Create + Template**. +1. Select **Upload template**: + + ![Upload your first template](../images/templates/upload-create-your-first-template.png) + +1. Drag the `.zip` file into the **Upload template** section and fill out the + details, then select **Create template**. + + ![Upload the template files](../images/templates/upload-create-template-form.png) + +1. Once the upload completes, select **Templates** from the top to deploy it to + a new workspace. -In your web browser, log in to your Coder dashboard, select **Templates**. Your -template is ready to use for new workspaces. + ![Your new template, ready to use](../images/templates/template-tour.png) -![Your new template, ready to use](../images/templates/template-tour.png) +
### Next steps diff --git a/site/src/pages/CreateTemplatePage/TemplateUpload.tsx b/site/src/pages/CreateTemplatePage/TemplateUpload.tsx index ffb455de1afa3..800cab0ce0512 100644 --- a/site/src/pages/CreateTemplatePage/TemplateUpload.tsx +++ b/site/src/pages/CreateTemplatePage/TemplateUpload.tsx @@ -29,7 +29,7 @@ export const TemplateUpload: FC = ({ > starter templates {" "} - to getting started with Coder. + to get started with Coder. );