docs: reorganize template docs (#10297)

* docs: rework our "templates" section

* wikistuff

* fix formatting

* add diagram

* reorganize some things

* docs: improve workspaces and templates doc (#9139)

* Reorg, updated/new screenshots, consistent terminology

* First pass

* Another pass

* Added integration section

* New outline for template pages, small updates

* Revised outline for templates, added tutorial

* First pass at tutorial

* Some feedback from Ben.

* Update docs/workspaces.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/workspaces.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/workspaces.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Fixed typos

* Expanded tutorial

I have read the CLA Document and I hereby sign the CLA

* New screenshots, improved tutorial, revised anatomy

* Improved tutorial. Anatomy is now a guided tour.

* First pass at guided tour

* Updated authentication info

* Reorganized the guided tour

* Edited more template pages

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tutorial.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Update docs/templates/tour.md

Co-authored-by: Muhammad Atif Ali <matifali@live.com>

* Revised devcontainers and docker-in-workspaces

* Edited and added screenshots

* Prepared first draft, except docs/templates/open-in-coder.md

* Fix typo

* remove legacy parameters and migration guide

* Use coder templates create

* Added screenshot for workspace template variables

* Made it prettier

* Fixed minor typos and markdown problems

* edits to repairing workspaces

* fix broken links in product

* Added troubleshooting, minor corrections.

* fix terminal links

* fmt

---------

Co-authored-by: Muhammad Atif Ali <matifali@live.com>
Co-authored-by: Ben Potter <me@bpmct.net>
Co-authored-by: Atif Ali <atif@coder.com>

* make fmt

* fix merge conflict

* make fmt

* make gen

* update

* lint

* Discard changes to coderd/database/queries.sql.go

* Discard changes to cli/templates.go

* Discard changes to cli/templateversionarchive.go

* Discard changes to cli/templateversions.go

* Update docker-in-workspaces.md

* replace ```sh with ```shell

* open-in-coder

* fmt

* mention coder_metadata in icons.md

* resource_metadata

* use shell

* modules.md

* mention coder registry module

* workspace.md

* resource_metadata

* remove duplication

* address comments

* cleanup

* fmt

* fix broken links

* fix numbering

* mention module registry

* add example

* demote heading

* remove top level entry from manifest

* fmt

---------

Co-authored-by: Ben <me@bpmct.net>
Co-authored-by: Marc Paquette <22124737+marcpaq@users.noreply.github.com>
This commit is contained in:
Muhammad Atif Ali 2023-10-17 17:47:12 +03:00 committed by GitHub
parent b5e5b39de2
commit a49e6b88f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 1438 additions and 1143 deletions

View File

@ -1,4 +1,4 @@
# Provisioners
# External provisioners
By default, the Coder server runs
[built-in provisioner daemons](../cli/server.md#provisioner-daemons), which

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -139,55 +139,86 @@
},
{
"title": "Templates",
"description": "Learn about templates, which define the infrastructure underlying workspaces",
"description": "Templates define the infrastructure for workspaces",
"path": "./templates/index.md",
"icon_path": "./images/icons/picture.svg",
"children": [
{
"title": "Resource Persistence",
"description": "Learn how resource persistence works in Coder",
"path": "./templates/resource-persistence.md",
"icon_path": "./images/icons/infinity.svg"
"title": "Working with templates",
"description": "Creating, editing, and updating templates",
"path": "./templates/creating.md"
},
{
"title": "Provider Authentication",
"description": "Learn how to authenticate the provisioner",
"path": "./templates/authentication.md",
"icon_path": "./images/icons/key.svg"
"title": "Your first template",
"description": "A tutorial for creating and editing your first template",
"path": "./templates/tutorial.md"
},
{
"title": "Change Management",
"description": "Learn how to source-control templates with git and CI",
"path": "./templates/change-management.md",
"icon_path": "./images/icons/git.svg"
"title": "Guided tour",
"description": "Create a template from scratch",
"path": "./templates/tour.md"
},
{
"title": "Resource Metadata",
"description": "Learn how to expose resource data to users",
"path": "./templates/resource-metadata.md",
"icon_path": "./images/icons/table-rows.svg"
"title": "Setting up templates",
"description": "Best practices for writing templates",
"path": "./templates/best-practices.md",
"children": [
{
"title": "Change management",
"description": "Versioning templates with git and CI",
"path": "./templates/change-management.md",
"icon_path": "./images/icons/git.svg"
},
{
"title": "Provider authentication",
"description": "Authenticate the provisioner",
"path": "./templates/authentication.md",
"icon_path": "./images/icons/key.svg"
},
{
"title": "Resource persistence",
"description": "How resource persistence works in Coder",
"path": "./templates/resource-persistence.md",
"icon_path": "./images/icons/infinity.svg"
},
{
"title": "Terraform modules",
"description": "Reuse code across Coder templates",
"path": "./templates/modules.md"
}
]
},
{
"title": "Agent Metadata",
"description": "Learn how to expose live agent information to users",
"path": "./templates/agent-metadata.md",
"icon_path": "./images/icons/table-rows.svg"
},
{
"title": "Parameters",
"description": "Use parameters to customize templates",
"path": "./templates/parameters.md",
"icon_path": "./images/icons/code.svg"
"title": "Customizing templates",
"description": "Give information and options to workspace users",
"path": "./templates/customizing.md",
"children": [
{
"title": "Agent metadata",
"description": "Show operational metrics in the workspace",
"path": "./templates/agent-metadata.md"
},
{
"title": "Resource metadata",
"description": "Show information in the workspace about template resources",
"path": "./templates/resource-metadata.md"
},
{
"title": "Parameters",
"description": "Prompt the user for additional information about a workspace",
"path": "./templates/parameters.md"
}
]
},
{
"title": "Open in Coder",
"description": "Learn how to add an \"Open in Coder\" button to your repos",
"description": "Add an \"Open in Coder\" button to your repos",
"path": "./templates/open-in-coder.md",
"icon_path": "./images/icons/key.svg"
},
{
"title": "Docker in Workspaces",
"description": "Use docker inside containerized templates",
"title": "Docker in workspaces",
"description": "Use Docker inside containerized templates",
"path": "./templates/docker-in-workspaces.md",
"icon_path": "./images/icons/docker.svg"
},
@ -198,9 +229,9 @@
"state": "alpha"
},
{
"title": "Terraform Modules",
"description": "Reuse code across Coder templates",
"path": "./templates/modules.md"
"title": "Troubleshooting templates",
"description": "Fix common template problems",
"path": "./templates/troubleshooting.md"
},
{
"title": "Process Logging",
@ -337,7 +368,7 @@
"icon_path": "./images/icons/scale.svg"
},
{
"title": "Provisioners",
"title": "External Provisioners",
"description": "Run provisioners isolated from the Coder server",
"path": "./admin/provisioners.md",
"icon_path": "./images/icons/queue.svg",

View File

@ -24,6 +24,10 @@ The admin-level access token is used to provision user tokens and is never expos
developers or stored in workspaces.
</blockquote>
<blockquote class="info">
You can skip the whole page and use [JFrog module](https://registry.coder.com/modules/jfrog) for easy JFrog Artifactory integration.
</blockquote>
## Provisioner Authentication
The most straight-forward way to authenticate your template with Artifactory is

View File

@ -1,13 +1,12 @@
# Agent Metadata
# Agent metadata
![agent-metadata](../images/agent-metadata.png)
With Agent Metadata, template admins can expose operational metrics from their
workspaces to their users. It is the dynamic complement of
[Resource Metadata](./resource-metadata.md).
You can show live operational metrics to workspace users with agent metadata. It
is the dynamic complement of [resource metadata](./resource-metadata.md).
See the
[Terraform reference](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#metadata).
You specify agent metadata in the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).
## Examples
@ -16,9 +15,10 @@ All of these examples use
for the script declaration. With heredoc strings, you can script without messy
escape codes, just as if you were working in your terminal.
Some of the below examples use the [`coder stat`](../cli/stat.md) command. This
is useful for determining CPU/memory usage inside a container, which can be
tricky otherwise.
Some of the examples use the [`coder stat`](../cli/stat.md) command. This is
useful for determining CPU and memory usage of the VM or container that the
workspace is running in, which is more accurate than resource usage about the
workspace's host.
Here's a standard set of metadata snippets for Linux agents:
@ -86,11 +86,13 @@ resource "coder_agent" "main" {
}
```
## Utilities
## Useful utilities
[top](https://linux.die.net/man/1/top) is available in most Linux distributions
and provides virtual memory, CPU and IO statistics. Running `top` produces
output that looks like:
You can also show agent metadata for information about the workspace's host.
[top](https://manpages.ubuntu.com/manpages/jammy/en/man1/top.1.html) is
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `top` produces output that looks like:
```text
%Cpu(s): 65.8 us, 4.4 sy, 0.0 ni, 29.3 id, 0.3 wa, 0.0 hi, 0.2 si, 0.0 st
@ -98,9 +100,9 @@ MiB Mem : 16009.0 total, 493.7 free, 4624.8 used, 10890.5 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 11021.3 avail Mem
```
[vmstat](https://linux.die.net/man/8/vmstat) is available in most Linux
distributions and provides virtual memory, CPU and IO statistics. Running
`vmstat` produces output that looks like:
[vmstat](https://manpages.ubuntu.com/manpages/jammy/en/man8/vmstat.8.html) is
available in most Linux distributions and provides virtual memory, CPU and IO
statistics. Running `vmstat` produces output that looks like:
```text
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
@ -108,10 +110,10 @@ r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 19580 4781680 12133692 217646944 0 2 4 32 1 0 1 1 98 0 0
```
[dstat](https://linux.die.net/man/1/dstat) is considerably more parseable than
`vmstat` but often not included in base images. It is easily installed by most
package managers under the name `dstat`. The output of running `dstat 1 1` looks
like:
[dstat](https://manpages.ubuntu.com/manpages/jammy/man1/dstat.1.html) is
considerably more parseable than `vmstat` but often not included in base images.
It is easily installed by most package managers under the name `dstat`. The
output of running `dstat 1 1` looks like:
```text
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
@ -119,27 +121,28 @@ usr sys idl wai stl| read writ| recv send| in out | int csw
1 1 98 0 0|3422k 25M| 0 0 | 153k 904k| 123k 174k
```
## DB Write Load
## Managing the database load
Agent metadata can generate a significant write load and overwhelm your database
if you're not careful. The approximate writes per second can be calculated using
the following formula (applied once for each unique metadata interval):
Agent metadata can generate a significant write load and overwhelm your Coder
database if you're not careful. The approximate writes per second can be
calculated using the formula:
```text
num_running_agents * write_multiplier / metadata_interval
(metadata_count * num_running_agents * 2) / metadata_avg_interval
```
For example, let's say you have:
For example, let's say you have
- 10 running agents
- each with 4 metadata snippets
- where two have an interval of 4 seconds, and the other two 6 seconds
- each with 6 metadata snippets
- with an average interval of 4 seconds
You can expect at most `(10 * 2 / 4) + (10 * 2 / 6)` or ~8 writes per second.
The actual writes per second may be a bit lower due to batching of metadata.
Adding more metadata with the same interval will not increase writes per second,
but it may still increase database load slightly.
You can expect `(10 * 6 * 2) / 4`, or 30 writes per second.
We use a `write_multiplier` of `2` because each metadata write generates two
writes. One of the writes is to the `UNLOGGED` `workspace_agent_metadata` table
and the other to the `NOTIFY` query that enables live stats streaming in the UI.
One of the writes is to the `UNLOGGED` `workspace_agent_metadata` table and the
other to the `NOTIFY` query that enables live stats streaming in the UI.
## Next Steps
- [Resource metadata](./resource-metadata.md)
- [Parameters](./parameters.md)

View File

@ -7,31 +7,42 @@
</p>
</blockquote>
Coder's provisioner process needs to authenticate with cloud provider APIs to
provision workspaces. You can either pass credentials to the provisioner as
parameters or execute Coder in an environment that is authenticated with the
cloud provider.
The Coder server's
[provisioner](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/provisioner)
process needs to authenticate with other provider APIs to provision workspaces.
There are two approaches to do this:
We encourage the latter where supported. This approach simplifies the template,
keeps cloud provider credentials out of Coder's database (making it a less
valuable target for attackers), and is compatible with agent-based
authentication schemes (that handle credential rotation and/or ensure the
credentials are not written to disk).
- Pass credentials to the provisioner as parameters.
- Preferred: Execute the Coder server in an environment that is authenticated
with the provider.
Cloud providers for which the Terraform provider supports authenticated
environments include
We encourage the latter approach where supported:
- Simplifies the template.
- Keeps provider credentials out of Coder's database, making it a less valuable
target for attackers.
- Compatible with agent-based authentication schemes, which handle credential
rotation or ensure the credentials are not written to disk.
Generally, you can set up an environment to provide credentials to Coder in
these ways:
- A well-known location on disk. For example, `~/.aws/credentials` for AWS on
POSIX systems.
- Environment variables.
It is usually sufficient to authenticate using the CLI or SDK for the provider
before running Coder, but check the Terraform provider's documentation for
details.
These platforms have Terraform providers that support authenticated
environments:
- [Google Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs)
- [Amazon Web Services](https://registry.terraform.io/providers/hashicorp/aws/latest/docs)
- [Microsoft Azure](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs)
- [Kubernetes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs)
Additional providers may be supported; check the
Other providers might also support authenticated environments. Check the
[documentation of the Terraform provider](https://registry.terraform.io/browse/providers)
for details.
The way these generally work is via the credentials being available to Coder
either in some well-known location on disk (e.g. `~/.aws/credentials` for AWS on
posix systems), or via environment variables. It is usually sufficient to
authenticate using the CLI or SDK for the cloud provider before running Coder
for this to work, but check the Terraform provider documentation for details.

7
docs/templates/best-practices.md vendored Normal file
View File

@ -0,0 +1,7 @@
# Template best practices
We recommend a few ways to manage workspace resources, authentication, and
versioning.
<children>
</children>

View File

@ -1,7 +1,7 @@
# Template Change Management
We recommend source controlling your templates as you would other code.
[Install Coder](../install/) in CI/CD pipelines to push new template versions.
We recommend source-controlling your templates as you would other code. You can
[install Coder](../install/) in CI/CD pipelines to push new template versions.
```console
# Install the Coder CLI
@ -21,14 +21,12 @@ export CODER_TEMPLATE_DIR=.coder/templates/kubernetes
export CODER_TEMPLATE_VERSION=$(git rev-parse --short HEAD)
# Push the new template version to Coder
coder login --url $CODER_URL --token $CODER_SESSION_TOKEN
coder templates push --yes $CODER_TEMPLATE_NAME \
--directory $CODER_TEMPLATE_DIR \
--name=$CODER_TEMPLATE_VERSION # Version name is optional
```
> Looking for an example? See how we push our development image and template
> [via GitHub actions](https://github.com/coder/coder/blob/main/.github/workflows/dogfood.yaml).
> To cap token lifetime on creation,
> [configure Coder server to set a shorter max token lifetime](../cli/server.md#--max-token-lifetime)
To cap token lifetime on creation,
[configure Coder server to set a shorter max token lifetime](../cli/server.md#--max-token-lifetime).
For an example, see how we push our development image and template
[with GitHub actions](https://github.com/coder/coder/blob/main/.github/workflows/dogfood.yaml).

94
docs/templates/creating.md vendored Normal file
View File

@ -0,0 +1,94 @@
# Working with templates
You create and edit Coder templates as [Terraform](./tour.md) configuration
files (`.tf`) and any supporting files, like a README or configuration files for
other services.
## Who creates templates?
The [Template Admin](../admin/users.md) role (and above) can create templates.
End users, like developers, create workspaces from them.
Templates can also be [managed with git](./change-management.md), allowing any
developer to propose changes to a template.
You can give different users and groups access to templates with
[role-based access control](../admin/rbac.md).
## Starter templates
We provide starter templates for common cloud providers, like AWS, and
orchestrators, like Kubernetes. From there, you can modify them to use your own
images, VPC, cloud credentials, and so on. Coder supports all Terraform
resources and properties, so fear not if your favorite cloud provider isn't
here!
![Starter templates](../images/templates/starter-templates.png)
If you prefer to use Coder on the [command line](../cli.md), use
`coder templates init`.
> Coder starter templates are also available on our
> [GitHub repo](https://github.com/coder/coder/tree/main/examples/templates).
## Community Templates
As well as Coder's starter templates, you can see a list of community templates
by our users
[here](https://github.com/coder/coder/blob/main/examples/templates/community-templates.md).
## Editing templates
Our starter templates are meant to be modified for your use cases. You can edit
any template's files directly in the Coder dashboard.
![Editing a template](../images/templates/choosing-edit-template.gif)
If you'd prefer to use the CLI, use `coder templates pull`, edit the template
files, then `coder templates push`.
> Even if you are a Terraform expert, we suggest reading our
> [guided tour](./tour.md).
## Updating templates
Coder tracks a template's versions, keeping all developer workspaces up-to-date.
When you publish a new version, developers are notified to get the latest
infrastructure, software, or security patches. Learn more about
[change management](./change-management.md).
![Updating a template](../images/templates/update.png)
## Delete templates
You can delete a template using both the coder CLI and UI. Only
[template admins and owners](../admin/users.md) can delete a template, and the
template must not have any running workspaces associated to it.
In the UI, navigate to the template you want to delete, and select the dropdown
in the right-hand corner of the page to delete the template.
![delete-template](../images/delete-template.png)
Using the CLI, login to Coder and run the following command to delete a
template:
```shell
coder templates delete <template-name>
```
### Delete workspaces
When a workspace is deleted, the Coder server essentially runs a
[terraform destroy](https://www.terraform.io/cli/commands/destroy) to remove all
resources associated with the workspace.
> Terraform's
> [prevent-destroy](https://www.terraform.io/language/meta-arguments/lifecycle#prevent_destroy)
> and
> [ignore-changes](https://www.terraform.io/language/meta-arguments/lifecycle#ignore_changes)
> meta-arguments can be used to prevent accidental data loss.
## Next steps
- [Your first template](./tutorial.md)

6
docs/templates/customizing.md vendored Normal file
View File

@ -0,0 +1,6 @@
# Customizing templates
You can give developers more information and control over their workspaces:
<children>
</children>

View File

@ -2,31 +2,31 @@
[Devcontainers](https://containers.dev) are an open source specification for
defining development environments.
[envbuilder](https://github.com/coder/envbuilder) is an open source project by
Coder that runs devcontainers via Coder templates and your underlying
infrastructure.
infrastructure. It can run on Docker or Kubernetes.
There are several benefits to adding a devcontainer-compatible template to
Coder:
- Drop-in migration from Codespaces (or any existing repositories that use
devcontainers)
- Easier to start projects from Coder (new workspace, pick starter devcontainer)
- Easier to start projects from Coder. Just create a new workspace then pick a
starter devcontainer.
- Developer teams can "bring their own image." No need for platform teams to
manage complex images, registries, and CI pipelines.
## How it works
- Coder admins add a devcontainer-compatible template to Coder (envbuilder can
run on Docker or Kubernetes)
A Coder admin adds a devcontainer-compatible template to Coder (envbuilder).
Then developers enter their repository URL as a [parameter](./parameters.md)
when they create their workspace.
[envbuilder](https://github.com/coder/envbuilder) clones the repo and builds a
container from the `devcontainer.json` specified in the repo.
- Developers enter their repository URL as a [parameter](./parameters.md) when
they create their workspace. [envbuilder](https://github.com/coder/envbuilder)
clones the repo and builds a container from the `devcontainer.json` specified
in the repo.
- Developers can edit the `devcontainer.json` in their workspace to rebuild to
iterate on their development environments.
Developers can edit the `devcontainer.json` in their workspace to rebuild to
iterate on their development environments.
## Example templates
@ -35,13 +35,13 @@ Coder:
![Devcontainer parameter screen](../images/templates/devcontainers.png)
[Parameters](./parameters.md) can be used to prompt the user for a repo URL when
they are creating a workspace.
Your template can prompt the user for a repo URL with
[Parameters](./parameters.md).
## Authentication
You may need to authenticate to your container registry (e.g. Artifactory) or
git provider (e.g. GitLab) to use envbuilder. Refer to the
You may need to authenticate to your container registry, such as Artifactory, or
git provider such as GitLab, to use envbuilder. See the
[envbuilder documentation](https://github.com/coder/envbuilder/) for more
information.

View File

@ -4,7 +4,7 @@ There are a few ways to run Docker within container-based Coder workspaces.
| Method | Description | Limitations |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Sysbox container runtime](#sysbox-container-runtime) | Install the sysbox runtime on your Kubernetes nodes for secure docker-in-docker and systemd-in-docker. Works with GKE, EKS, AKS. | Requires [compatible nodes](https://github.com/nestybox/sysbox#host-requirements). |
| [Sysbox container runtime](#sysbox-container-runtime) | Install the sysbox runtime on your Kubernetes nodes for secure docker-in-docker and systemd-in-docker. Works with GKE, EKS, AKS. | Requires [compatible nodes](https://github.com/nestybox/sysbox#host-requirements). [Limitations](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/limitations.md) |
| [Envbox](#envbox) | A container image with all the packages necessary to run an inner sysbox container. Removes the need to setup sysbox-runc on your nodes. Works with GKE, EKS, AKS. | Requires running the outer container as privileged (the inner container that acts as the workspace is locked down). Requires compatible [nodes](https://github.com/nestybox/sysbox/blob/master/docs/distro-compat.md#sysbox-distro-compatibility). |
| [Rootless Podman](#rootless-podman) | Run podman inside Coder workspaces. Does not require a custom runtime or privileged containers. Works with GKE, EKS, AKS, RKE, OpenShift | Requires smarter-device-manager for FUSE mounts. [See all](https://github.com/containers/podman/blob/main/rootless.md#shortcomings-of-rootless-podman) |
| [Privileged docker sidecar](#privileged-sidecar-container) | Run docker as a privileged sidecar container. | Requires a privileged container. Workspaces can break out to root on the host machine. |
@ -18,10 +18,6 @@ from the workspace containers. Sysbox requires a
to implement these security features. Sysbox can also be used to run systemd
inside Coder workspaces. See [Systemd in Docker](#systemd-in-docker).
The Sysbox container runtime is not compatible with our
[workspace process logging](./process-logging.md) feature. Envbox is compatible
with process logging, however.
### Use Sysbox in Docker-based templates
After [installing Sysbox](https://github.com/nestybox/sysbox#installation) on
@ -197,8 +193,7 @@ env {
compatible with OCI containers specification. which can run rootless inside
Kubernetes pods. No custom RuntimeClass is required.
Prior to completing the steps below, please review the following Podman
documentation:
Before using Podman, please review the following documentation:
- [Basic setup and use of Podman in a rootless environment](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md)
@ -256,7 +251,7 @@ documentation:
> Otherwise, your nodes may drop the labels and break podman functionality.
3. For systems running SELinux (typically Fedora-, CentOS-, and Red Hat-based
systems), you may need to disable SELinux or set it to permissive mode.
systems), you might need to disable SELinux or set it to permissive mode.
4. Import our
[kubernetes-with-podman](https://github.com/coder/coder/tree/main/examples/templates/kubernetes-with-podman)

View File

@ -20,6 +20,7 @@ come bundled with your Coder deployment.
[`option`](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter#nested-schema-for-option)
blocks
- [`coder_script`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/script#icon)
- [`coder_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata#icon)
These can all be configured to use an icon by setting the `icon` field.

View File

@ -1,633 +1,8 @@
# Templates
Templates are written in [Terraform](https://www.terraform.io/) and describe the
infrastructure for workspaces (e.g., docker_container, aws_instance,
kubernetes_pod).
Templates define the underlying infrastructure that Coder
[workspaces](../workspaces.md) run on. All workspaces are created from
templates.
In most cases, a small group of users (team leads or Coder administrators)
[have permissions](../admin/users.md#roles) to create and manage templates.
Then, other users provision their [workspaces](../workspaces.md) from templates
using the UI or CLI.
## Get the CLI
The CLI and the server are the same binary. We did this to encourage virality so
individuals can start their own Coder deployments.
From your local machine, download the CLI for your operating system from the
[releases](https://github.com/coder/coder/releases/latest) or run:
```shell
curl -fsSL https://coder.com/install.sh | sh
```
To see the sub-commands for managing templates, run:
```shell
coder templates --help
```
## Login to your Coder Deployment
Before you can create templates, you must first login to your Coder deployment
with the CLI.
```shell
coder login https://coder.example.com # aka the URL to your coder instance
```
This will open a browser and ask you to authenticate to your Coder deployment,
returning an API Key.
> Make a note of the API Key. You can re-use the API Key in future CLI logins or
> sessions.
```shell
coder --token <your-api-key> login https://coder.example.com/ # aka the URL to your coder instance
```
## Add a template
Before users can create workspaces, you'll need at least one template in Coder.
```shell
# create a local directory to store templates
mkdir -p $HOME/coder/templates
cd $HOME/coder/templates
# start from an example
coder templates init
# optional: modify the template
vim <template-name>/main.tf
# add the template to Coder deployment
coder templates create <template-name>
```
> See the documentation and source code for each example as well as community
> templates in the
> [examples/](https://github.com/coder/coder/tree/main/examples/templates)
> directory in the repo.
## Configure Max Workspace Autostop
To control cost, specify a maximum time to live flag for a template in hours or
minutes.
```shell
coder templates create my-template --default-ttl 4h
```
## Customize templates
Example templates are not designed to support every use (e.g
[examples/aws-linux](https://github.com/coder/coder/tree/main/examples/templates/aws-linux)
does not support custom VPCs). You can add these features by editing the
Terraform code once you run `coder templates init` (new) or
`coder templates pull` (existing).
Refer to the following resources to build your own templates:
- Terraform: [Documentation](https://developer.hashicorp.com/terraform/docs) and
[Registry](https://registry.terraform.io)
- Common [concepts in templates](#concepts-in-templates) and
[Coder Terraform provider](https://registry.terraform.io/providers/coder/coder/latest/docs)
- [Coder example templates](https://github.com/coder/coder/tree/main/examples/templates)
code
## Concepts in templates
While templates are written with standard Terraform, the
[Coder Terraform Provider](https://registry.terraform.io/providers/coder/coder/latest/docs)
is used to define the workspace lifecycle and establish a connection from
resources to Coder.
Below is an overview of some key concepts in templates (and workspaces). For all
template options, reference
[Coder Terraform provider docs](https://registry.terraform.io/providers/coder/coder/latest/docs).
### Resource
Resources in Coder are simply
[Terraform resources](https://www.terraform.io/language/resources). If a Coder
agent is attached to a resource, users can connect directly to the resource over
SSH or web apps.
### Coder agent
Once a Coder workspace is created, the Coder agent establishes a connection
between a resource (docker_container) and Coder, so that a user can connect to
their workspace from the web UI or CLI. A template can have multiple agents to
allow users to connect to multiple resources in their workspace.
> Resources must download and start the Coder agent binary to connect to Coder.
> This means the resource must be able to reach your Coder URL.
```hcl
data "coder_workspace" "me" {
}
resource "coder_agent" "pod1" {
os = "linux"
arch = "amd64"
}
resource "kubernetes_pod" "pod1" {
spec {
...
container {
command = ["sh", "-c", coder_agent.pod1.init_script]
env {
name = "CODER_AGENT_TOKEN"
value = coder_agent.dev.token
}
}
}
}
```
The `coder_agent` resource can be configured with additional arguments. For
example, you can use the `env` property to set environment variables that will
be inherited by all child processes of the agent, including SSH sessions. See
the
[Coder Terraform Provider documentation](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
for the full list of supported arguments for the `coder_agent`.
#### `startup_script`
Use the Coder agent's `startup_script` to run additional commands like
installing IDEs, [cloning dotfiles](../dotfiles.md#templates), and cloning
project repos.
**Note:** By default, the startup script is executed in the background. This
allows users to access the workspace before the script completes. If you want to
change this, see [`startup_script_behavior`](#startup_script_behavior) below.
Here are a few guidelines for writing a good startup script (more on these
below):
1. Use `set -e` to exit the script if any command fails and `|| true` for
commands that are allowed to fail
2. Use `&` to start a process in the background, allowing the startup script to
complete
3. Inform the user about what's going on via `echo`
```hcl
resource "coder_agent" "coder" {
os = "linux"
arch = "amd64"
dir = "/home/coder"
startup_script = <<EOT
#!/bin/bash
# Install code-server 4.8.3 under /tmp/code-server using the "standalone" installation
# that does not require root permissions. Note that /tmp may be mounted in tmpfs which
# can lead to increased RAM usage. To avoid this, you can pre-install code-server inside
# the Docker image or VM image.
echo "Installing code-server..."
curl -fsSL https://code-server.dev/install.sh | sh -s -- --method=standalone --prefix=/tmp/code-server --version 4.8.3
# The & prevents the startup_script from blocking so the next commands can run.
# The stdout and stderr of code-server is redirected to /tmp/code-server.log.
echo "Starting code-server..."
/tmp/code-server/bin/code-server --auth none --port 13337 >/tmp/code-server.log 2>&1 &
# Notice: var.repo and var.dotfiles_uri are specified elsewhere in the Terraform
# code as input variables.
REPO=${var.repo}
DOTFILES_URI=${var.dotfiles_uri}
# clone repo
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
echo "Cloning $REPO..."
git clone --progress git@github.com:"$REPO"
# use coder CLI to clone and install dotfiles
echo "Cloning dotfiles..."
coder dotfiles -y "$DOTFILES_URI"
EOT
}
```
The startup script can contain important steps that must be executed
successfully so that the workspace is in a usable state, for this reason we
recommend using `set -e` (exit on error) at the top and `|| true` (allow command
to fail) to ensure the user is notified when something goes wrong. These are not
shown in the example above because, while useful, they need to be used with
care. For more assurance, you can utilize
[shellcheck](https://www.shellcheck.net) to find bugs in the script and employ
[`set -euo pipefail`](https://wizardzines.com/comics/bash-errors/) to exit on
error, unset variables, and fail on pipe errors.
We also recommend that startup scripts do not run forever. Long-running
processes, like code-server, should be run in the background. This is usually
achieved by adding `&` to the end of the command. For example, `sleep 10 &` will
run the command in the background and allow the startup script to complete.
> **Note:** If a backgrounded command (`&`) writes to stdout or stderr, the
> startup script will not complete until the command completes or closes the
> file descriptors. To avoid this, you can redirect the stdout and stderr to a
> file. For example, `sleep 10 >/dev/null 2>&1 &` will redirect the stdout and
> stderr to `/dev/null` (discard) and run the command in the background.
PS. Notice how each step starts with `echo "..."` to provide feedback to the
user about what is happening? This is especially useful when the startup script
behavior is set to blocking because the user will be informed about why they're
waiting to access their workspace.
#### `startup_script_behavior`
Use the Coder agent's `startup_script_behavior` to change the behavior between
`blocking` and `non-blocking` (default). The blocking behavior is recommended
for most use cases because it allows the startup script to complete before the
user accesses the workspace. For example, let's say you want to check out a very
large repo in the startup script. If the startup script is non-blocking, the
user may log in via SSH or open the IDE before the repo is fully checked out.
This can lead to a poor user experience.
```hcl
resource "coder_agent" "coder" {
os = "linux"
arch = "amd64"
startup_script_behavior = "blocking"
startup_script = "echo 'Starting...'"
```
Whichever behavior is enabled, the user can still choose to override it by
specifying the appropriate flags (or environment variables) in the CLI when
connecting to the workspace. The behavior can be overridden by one of the
following means:
- Set an environment variable (for use with `ssh` or `coder ssh`):
- `export CODER_SSH_WAIT=yes` (blocking)
- `export CODER_SSH_WAIT=no` (non-blocking)
- Use a flag with `coder ssh`:
- `coder ssh --wait=yes my-workspace` (blocking)
- `coder ssh --wait=no my-workspace` (non-blocking)
- Use a flag to configure all future `ssh` connections:
- `coder config-ssh --wait=yes` (blocking)
- `coder config-ssh --wait=no` (non-blocking)
### Start/stop
[Learn about resource persistence in Coder](./resource-persistence.md)
Coder workspaces can be started/stopped. This is often used to save on cloud
costs or enforce ephemeral workflows. When a workspace is started or stopped,
the Coder server runs an additional
[terraform apply](https://www.terraform.io/cli/commands/apply), informing the
Coder provider that the workspace has a new transition state.
This template sample has one persistent resource (docker volume) and one
ephemeral resource (docker container).
```hcl
data "coder_workspace" "me" {
}
resource "docker_volume" "home_volume" {
# persistent resource (remains a workspace is stopped)
count = 1
name = "coder-${data.coder_workspace.me.id}-home"
lifecycle {
ignore_changes = all
}
}
resource "docker_container" "workspace" {
# ephemeral resource (deleted when workspace is stopped, created when started)
count = data.coder_workspace.me.start_count # 0 (stopped), 1 (started)
volumes {
container_path = "/home/coder/"
volume_name = docker_volume.home_volume.name
read_only = false
}
# ... other config
}
```
#### Using updated images when rebuilding a workspace
To ensure that Coder uses an updated image when rebuilding a workspace, we
suggest that admins update the tag in the template (e.g., `my-image:v0.4.2` ->
`my-image:v0.4.3`) or digest (`my-image@sha256:[digest]` ->
`my-image@sha256:[new_digest]`).
Alternatively, if you're willing to wait for longer start times from Coder, you
can set the `imagePullPolicy` to `Always` in your Terraform template; when set,
Coder will check `image:tag` on every build and update if necessary:
```hcl
resource "kubernetes_pod" "podName" {
spec {
container {
image_pull_policy = "Always"
}
}
}
```
### Edit templates
You can edit a template using the coder CLI or the UI. Only
[template admins and owners](../admin/users.md) can edit a template.
Using the UI, navigate to the template page, click on the menu, and select "Edit
files". In the template editor, you create, edit and remove files. Before
publishing a new template version, you can test your modifications by clicking
the "Build template" button. Newly published template versions automatically
become the default version selection when creating a workspace.
> **Tip**: Even without publishing a version as active, you can still use it to
> create a workspace before making it the default for everybody in your
> organization. This may help you debug new changes without impacting others.
Using the CLI, login to Coder and run the following command to edit a single
template:
```shell
coder templates edit <template-name> --description "This is my template"
```
Review editable template properties by running `coder templates edit -h`.
Alternatively, you can pull down the template as a tape archive (`.tar`) to your
current directory:
```shell
coder templates pull <template-name> file.tar
```
Then, extract it by running:
```shell
tar -xf file.tar
```
Make the changes to your template then run this command from the root of the
template folder:
```shell
coder templates push <template-name>
```
Your updated template will now be available. Outdated workspaces will have a
prompt in the dashboard to update.
### Delete templates
You can delete a template using both the coder CLI and UI. Only
[template admins and owners](../admin/users.md) can delete a template, and the
template must not have any running workspaces associated to it.
Using the CLI, login to Coder and run the following command to delete a
template:
```shell
coder templates delete <template-name>
```
In the UI, navigate to the template you want to delete, and select the dropdown
in the right-hand corner of the page to delete the template.
![delete-template](../images/delete-template.png)
#### Delete workspaces
When a workspace is deleted, the Coder server essentially runs a
[terraform destroy](https://www.terraform.io/cli/commands/destroy) to remove all
resources associated with the workspace.
> Terraform's
> [prevent-destroy](https://www.terraform.io/language/meta-arguments/lifecycle#prevent_destroy)
> and
> [ignore-changes](https://www.terraform.io/language/meta-arguments/lifecycle#ignore_changes)
> meta-arguments can be used to prevent accidental data loss.
### Coder apps
By default, all templates allow developers to connect over SSH and a web
terminal. See [Configuring Web IDEs](../ides/web-ides.md) to learn how to give
users access to additional web applications.
Template administrators can hide apps like the web-based Terminal or VS Code
Desktop with the
[`display_apps`](https://registry.terraform.io/providers/coder/coder/0.11.2/docs/resources/agent#display_apps)
configuration in the
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
resource. For example, the following configuration block will hide all default
Coder apps except the web terminal.
```hcl
display_apps {
vscode = false
vscode_insiders = false
ssh_helper = false
port_forwarding_helper = false
web_terminal = true
}
```
Example use cases for `display_apps` are JetBrains users or zero-trust
deployments who do not want nor should have access to a local VS Code IDE.
![display-apps](../images/display-apps.png)
### Data source
When a workspace is being started or stopped, the `coder_workspace` data source
provides some useful parameters. See the
[Coder Terraform provider](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace)
for more information.
For example, the
[Docker quick-start template](https://github.com/coder/coder/tree/main/examples/templates/docker)
sets a few environment variables based on the username and email address of the
workspace's owner, so that you can make Git commits immediately without any
manual configuration:
```hcl
resource "coder_agent" "main" {
# ...
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}"
}
}
```
You can add these environment variable definitions to your own templates, or
customize them however you like.
## Troubleshooting templates
Occasionally, you may run into scenarios where a workspace is created, but the
agent is either not connected or the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
has failed or timed out.
### Agent connection issues
If the agent is not connected, it means the agent or
[init script](https://github.com/coder/coder/tree/main/provisionersdk/scripts)
has failed on the resource.
```console
$ coder ssh myworkspace
⢄⡱ Waiting for connection from [agent]...
```
While troubleshooting steps vary by resource, here are some general best
practices:
- Ensure the resource has `curl` installed (alternatively, `wget` or `busybox`)
- Ensure the resource can `curl` your Coder
[access URL](../admin/configure.md#access-url)
- Manually connect to the resource and check the agent logs (e.g.,
`kubectl exec`, `docker exec` or AWS console)
- The Coder agent logs are typically stored in `/tmp/coder-agent.log`
- The Coder agent startup script logs are typically stored in
`/tmp/coder-startup-script.log`
- The Coder agent shutdown script logs are typically stored in
`/tmp/coder-shutdown-script.log`
- This can also happen if the websockets are not being forwarded correctly when
running Coder behind a reverse proxy.
[Read our reverse-proxy docs](../admin/configure.md#tls--reverse-proxy)
### Startup script issues
Depending on the contents of the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script),
and whether or not the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
is set to blocking or non-blocking, you may notice issues related to the startup
script. In this section we will cover common scenarios and how to resolve them.
#### Unable to access workspace, startup script is still running
If you're trying to access your workspace and are unable to because the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is still running, it means the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
option is set to blocking or you have enabled the `--wait=yes` option (for e.g.
`coder ssh` or `coder config-ssh`). In such an event, you can always access the
workspace by using the web terminal, or via SSH using the `--wait=no` option. If
the startup script is running longer than it should, or never completing, you
can try to [debug the startup script](#debugging-the-startup-script) to resolve
the issue. Alternatively, you can try to force the startup script to exit by
terminating processes started by it or terminating the startup script itself (on
Linux, `ps` and `kill` are useful tools).
For tips on how to write a startup script that doesn't run forever, see the
[`startup_script`](#startup_script) section. For more ways to override the
startup script behavior, see the
[`startup_script_behavior`](#startup_script_behavior) section.
Template authors can also set the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
option to non-blocking, which will allow users to access the workspace while the
startup script is still running. Note that the workspace must be updated after
changing this option.
#### Your workspace may be incomplete
If you see a warning that your workspace may be incomplete, it means you should
be aware that programs, files, or settings may be missing from your workspace.
This can happen if the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is still running or has exited with a non-zero status (see
[startup script error](#startup-script-error)). No action is necessary, but you
may want to
[start a new shell session](#session-was-started-before-the-startup-script-finished-web-terminal)
after it has completed or check the
[startup script logs](#debugging-the-startup-script) to see if there are any
issues.
#### Session was started before the startup script finished
The web terminal may show this message if it was started before the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
finished, but the startup script has since finished. This message can safely be
dismissed, however, be aware that your preferred shell or dotfiles may not yet
be activated for this shell session. You can either start a new session or
source your dotfiles manually. Note that starting a new session means that
commands running in the terminal will be terminated and you may lose unsaved
work.
Examples for activating your preferred shell or sourcing your dotfiles:
- `exec zsh -l`
- `source ~/.bashrc`
#### Startup script exited with an error
When the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
exits with an error, it means the last command run by the script failed. When
`set -e` is used, this means that any failing command will immediately exit the
script and the remaining commands will not be executed. This also means that
[your workspace may be incomplete](#your-workspace-may-be-incomplete). If you
see this error, you can check the
[startup script logs](#debugging-the-startup-script) to figure out what the
issue is.
Common causes for startup script errors:
- A missing command or file
- A command that fails due to missing permissions
- Network issues (e.g., unable to reach a server)
#### Debugging the startup script
The simplest way to debug the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is to open the workspace in the Coder dashboard and click "Show startup log" (if
not already visible). This will show all the output from the script. Another
option is to view the log file inside the workspace (usually
`/tmp/coder-startup-script.log`). If the logs don't indicate what's going on or
going wrong, you can increase verbosity by adding `set -x` to the top of the
startup script (note that this will show all commands run and may output
sensitive information). Alternatively, you can add `echo` statements to show
what's going on.
Here's a short example of an informative startup script:
```shell
echo "Running startup script..."
echo "Run: long-running-command"
/path/to/long-running-command
status=$?
echo "Done: long-running-command, exit status: ${status}"
if [ $status -ne 0 ]; then
echo "Startup script failed, exiting..."
exit $status
fi
```
> **Note:** We don't use `set -x` here because we're manually echoing the
> commands. This protects against sensitive information being shown in the log.
This script tells us what command is being run and what the exit status is. If
the exit status is non-zero, it means the command failed and we exit the script.
Since we are manually checking the exit status here, we don't need `set -e` at
the top of the script to exit on error.
## Template permissions (enterprise)
Template permissions can be used to give users and groups access to specific
templates. [Learn more about RBAC](../admin/rbac.md) to learn how to manage
## Community Templates
You can see a list of community templates by our users
[here](https://github.com/coder/coder/blob/main/examples/templates/community-templates.md).
## Next Steps
- Learn about [Authentication & Secrets](./authentication.md)
- Learn about [Change Management](./change-management.md)
- Learn about [Resource Metadata](./resource-metadata.md)
- Learn about [Workspaces](../workspaces.md)
<children>
</children>

View File

@ -1,12 +1,12 @@
# Template inheritance
# Reusing template code
In instances where you want to reuse code across different Coder templates, such
as common scripts or resource definitions, we suggest using
To reuse code across different Coder templates, such as common scripts or
resource definitions, we suggest using
[Terraform Modules](https://developer.hashicorp.com/terraform/language/modules).
These modules can be stored externally from Coder, like in a Git repository or a
Terraform registry. Below is an example of how to reference a module in your
template:
You can store these modules externally from your Coder deployment, like in a git
repository or a Terraform registry. This example shows how to reference a module
from your template:
```hcl
data "coder_workspace" "me" {}
@ -29,32 +29,32 @@ resource "coder_agent" "dev" {
}
```
> Learn more about
> [creating modules](https://developer.hashicorp.com/terraform/language/modules)
> and
> [module sources](https://developer.hashicorp.com/terraform/language/modules/sources)
> in the Terraform documentation.
Learn more about
[creating modules](https://developer.hashicorp.com/terraform/language/modules)
and
[module sources](https://developer.hashicorp.com/terraform/language/modules/sources)
in the Terraform documentation.
## Git authentication
If you are importing a module from a private git repository, the Coder server
[or provisioner](../admin/provisioners.md) needs git credentials. Since this
token will only be used for cloning your repositories with modules, it is best
to create a token with limited access to repositories and no extra permissions.
If you are importing a module from a private git repository, the Coder server or
[provisioner](../admin/provisioners.md) needs git credentials. Since this token
will only be used for cloning your repositories with modules, it is best to
create a token with access limited to the repository and no extra permissions.
In GitHub, you can generate a
[fine-grained token](https://docs.github.com/en/rest/overview/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28)
with read only access to repos.
with read only access to the necessary repos.
If you are running Coder on a VM, make sure you have `git` installed and the
`coder` user has access to the following files
If you are running Coder on a VM, make sure that you have `git` installed and
the `coder` user has access to the following files:
```toml
```shell
# /home/coder/.gitconfig
[credential]
helper = store
```
```toml
```shell
# /home/coder/.git-credentials
# GitHub example:
@ -68,8 +68,8 @@ a Docker volume mount or Kubernetes secrets.
### Passing git credentials in Kubernetes
First, create a `.gitconfig` and `.git-credentials` file on your local machine.
You may want to do this in a temporary directory to avoid conflicting with your
own git credentials.
You might want to do this in a temporary directory to avoid conflicting with
your own git credentials.
Next, create the secret in Kubernetes. Be sure to do this in the same namespace
that Coder is installed in.
@ -158,3 +158,4 @@ Learn more about
[here](https://jfrog.com/help/r/jfrog-artifactory-documentation/terraform-registry).
- Configuring the JFrog toolchain inside a workspace
[here](../platforms/jfrog.md).
- Coder Module Registry [here](https://registry.coder.com/modules)

View File

@ -1,7 +1,7 @@
# Open in Coder
An "Open in Coder" button can be embedded into your git repos or internal wikis
to allow developers to quickly launch a new workspace.
You can embed an "Open in Coder" button into your git repos or internal wikis to
let developers quickly launch a new workspace.
<video autoplay playsinline loop>
<source src="https://github.com/coder/coder/blob/main/docs/images/templates/open-in-coder.mp4?raw=true" type="video/mp4">
@ -13,112 +13,108 @@ Your browser does not support the video tag.
To support any infrastructure and software stack, Coder provides a generic
approach for "Open in Coder" flows.
1. Set up
[Git Authentication](../admin/external-auth.md#require-git-authentication-in-templates)
in your Coder deployment
### 1. Set up git authentication
1. Modify your template to auto-clone repos:
See [External Authentication](../admin/external-auth.md) to set up git
authentication in your Coder deployment.
> The id in the template's `coder_git_auth` data source must match the
> `CODER_GITAUTH_0_ID` in the Coder deployment configuration.
### 2. Modify your template to auto-clone repos
- If you want the template to clone a specific git repo
The id in the template's `coder_git_auth` data source must match the
`CODER_GITAUTH_0_ID` in the Coder deployment configuration.
```hcl
# Require git authentication to use this template
data "coder_git_auth" "github" {
id = "primary-github"
}
If you want the template to clone a specific git repo:
resource "coder_agent" "dev" {
# ...
dir = "~/coder"
startup_script =<<EOF
```hcl
# Require git authentication to use this template
data "coder_git_auth" "github" {
id = "primary-github"
}
# Clone repo from GitHub
if [ ! -d "coder" ]
then
git clone https://github.com/coder/coder
fi
resource "coder_agent" "dev" {
# ...
dir = "~/coder"
startup_script =<<EOF
EOF
}
```
# Clone repo from GitHub
if [ ! -d "coder" ]
then
git clone https://github.com/coder/coder
fi
> Note: The `dir` attribute can be set in multiple ways, for example:
>
> - `~/coder`
> - `/home/coder/coder`
> - `coder` (relative to the home directory)
EOF
}
```
- If you want the template to support any repository via
[parameters](./parameters.md)
> Note: The `dir` attribute can be set in multiple ways, for example:
>
> - `~/coder`
> - `/home/coder/coder`
> - `coder` (relative to the home directory)
```hcl
# Require git authentication to use this template
data "coder_git_auth" "github" {
id = "primary-github"
}
If you want the template to support any repository via
[parameters](./parameters.md)
# Prompt the user for the git repo URL
data "coder_parameter" "git_repo" {
name = "git_repo"
display_name = "Git repository"
default = "https://github.com/coder/coder"
}
```hcl
# Require git authentication to use this template
data "coder_git_auth" "github" {
id = "primary-github"
}
locals {
folder_name = try(element(split("/", data.coder_parameter.git_repo.value), length(split("/", data.coder_parameter.git_repo.value)) - 1), "")
}
# Prompt the user for the git repo URL
data "coder_parameter" "git_repo" {
name = "git_repo"
display_name = "Git repository"
default = "https://github.com/coder/coder"
}
resource "coder_agent" "dev" {
# ...
dir = "~/${local.folder_name}"
startup_script =<<EOF
locals {
folder_name = try(element(split("/", data.coder_parameter.git_repo.value), length(split("/", data.coder_parameter.git_repo.value)) - 1), "")
}
# Clone repo from GitHub
if [ ! -d "${local.folder_name}" ]
then
git clone ${data.coder_parameter.git_repo.value}
fi
resource "coder_agent" "dev" {
# ...
dir = "~/${local.folder_name}"
startup_script =<<EOF
EOF
}
```
# Clone repo from GitHub
if [ ! -d "${local.folder_name}" ]
then
git clone ${data.coder_parameter.git_repo.value}
fi
1. Embed the "Open in Coder" button with Markdown
EOF
}
```
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace)
```
### 3. Embed the "Open in Coder" button with Markdown
> Be sure to replace `YOUR_ACCESS_URL` with your Coder access url (e.g.
> https://coder.example.com) and `YOUR_TEMPLATE` with the name of your
> template.
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace)
```
1. Optional: pre-fill parameter values in the "Create Workspace" page
Be sure to replace `YOUR_ACCESS_URL` with your Coder access url (e.g.
<https://coder.example.com>) and `YOUR_TEMPLATE` with the name of your template.
This can be used to pre-fill the git repo URL, disk size, image, etc.
### 4. Optional: pre-fill parameter values in the "Create Workspace" page
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?param.git_repo=https://github.com/coder/slog&param.home_disk_size%20%28GB%29=20)
```
This can be used to pre-fill the git repo URL, disk size, image, etc.
![Pre-filled parameters](../images/templates/pre-filled-parameters.png)
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?param.git_repo=https://github.com/coder/slog&param.home_disk_size%20%28GB%29=20)
```
1. Optional: disable specific parameter fields by including their names as
specified in your template in the `disable_params` search params list
![Pre-filled parameters](../images/templates/pre-filled-parameters.png)
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?disable_params=first_parameter,second_parameter)
```
### 5. Optional: disable specific parameter fields by including their names as
## Example: Kubernetes
specified in your template in the `disable_params` search params list
```md
[![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?disable_params=first_parameter,second_parameter)
```
### Example: Kubernetes
For a full example of the Open in Coder flow in Kubernetes, check out
[this example template](https://github.com/bpmct/coder-templates/tree/main/kubernetes-open-in-coder).
## Devcontainer support
Devcontainer support is on the roadmap.
[Follow along here](https://github.com/coder/coder/issues/5559)

View File

@ -1,10 +1,19 @@
# Parameters
Templates can contain _parameters_, which allow prompting the user for
additional information when creating workspaces in both the UI and CLI.
A template can prompt the user for additional information when creating
workspaces with
[_parameters_](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter).
![Parameters in Create Workspace screen](../images/parameters.png)
The user can set parameters in the dashboard UI and CLI.
You'll likely want to hardcode certain template properties for workspaces, such
as security group. But you can let developers specify other properties with
parameters like instance size, geographical location, repository URL, etc.
This example lets a developer choose a Docker host for the workspace:
```hcl
data "coder_parameter" "docker_host" {
name = "Region"
@ -33,7 +42,7 @@ data "coder_parameter" "docker_host" {
}
```
From there, parameters can be referenced during build-time:
From there, a template can refer to a parameter's value:
```hcl
provider "docker" {
@ -41,21 +50,19 @@ provider "docker" {
}
```
> For a complete list of supported parameter properties, see the
> [coder_parameter Terraform reference](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/parameter)
## Types
The following parameter types are supported: `string`, `list(string)`, `bool`,
and `number`.
A Coder parameter can have one of these types:
### List of strings
- `string`
- `bool`
- `number`.
- `list(string)`
List of strings is a specific parameter type, that can't be easily mapped to the
default value, which is string type. Parameters with the `list(string)` type
must be converted to JSON arrays using
To specify a default value for a parameter with the `list(string)` type, use a
JSON array and the Terraform
[jsonencode](https://developer.hashicorp.com/terraform/language/functions/jsonencode)
function.
function. For example:
```hcl
data "coder_parameter" "security_groups" {
@ -74,7 +81,7 @@ data "coder_parameter" "security_groups" {
## Options
A _string_ parameter can provide a set of options to limit the choice:
A `string` parameter can provide a set of options to limit the user's choices:
```hcl
data "coder_parameter" "docker_host" {
@ -135,9 +142,8 @@ Example:
## Required and optional parameters
A parameter is considered to be _required_ if it doesn't have the `default`
property. The user **must** provide a value to this parameter before creating a
workspace.
A parameter is _required_ if it doesn't have the `default` property. The user
**must** provide a value to this parameter before creating a workspace:
```hcl
data "coder_parameter" "account_name" {
@ -170,30 +176,18 @@ data "coder_parameter" "dotfiles_url" {
}
```
Terraform
[conditional expressions](https://developer.hashicorp.com/terraform/language/expressions/conditionals)
can be used to determine whether the user specified a value for an optional
parameter:
```hcl
resource "coder_agent" "main" {
# ...
startup_script_timeout = 180
startup_script = <<-EOT
set -e
echo "The optional parameter value is: ${data.coder_parameter.optional.value == "" ? "[empty]" : data.coder_parameter.optional.value}"
EOT
}
```
## Mutability
Immutable parameters can be only set before workspace creation, or during update
on the first usage to set the initial value for required parameters. The idea is
to prevent users from modifying fragile or persistent workspace resources like
volumes, regions, etc.:
Immutable parameters can only be set in these situations:
- Creating a workspace for the first time.
- Updating a workspace to a new template version. This sets the initial value
for required parameters.
The idea is to prevent users from modifying fragile or persistent workspace
resources like volumes, regions, and so on.
Example:
```hcl
data "coder_parameter" "region" {
@ -204,19 +198,19 @@ data "coder_parameter" "region" {
}
```
It is allowed to modify the mutability state anytime. In case of emergency,
template authors can temporarily allow for changing immutable parameters to fix
an operational issue, but it is not advised to overuse this opportunity.
You can modify a parameter's `mutable` attribute state anytime. In case of
emergency, you can temporarily allow for changing immutable parameters to fix an
operational issue, but it is not advised to overuse this opportunity.
## Ephemeral parameters
Ephemeral parameters are introduced to users in the form of "build options."
This functionality can be used to model specific behaviors within a Coder
workspace, such as reverting to a previous image, restoring from a volume
snapshot, or building a project without utilizing cache.
Ephemeral parameters are introduced to users in the form of "build options." Use
ephemeral parameters to model specific behaviors in a Coder workspace, such as
reverting to a previous image, restoring from a volume snapshot, or building a
project without using cache.
As these parameters are ephemeral in nature, subsequent builds will proceed in
the standard manner.
Since these parameters are ephemeral in nature, subsequent builds proceed in the
standard manner:
```hcl
data "coder_parameter" "force_rebuild" {
@ -229,17 +223,18 @@ data "coder_parameter" "force_rebuild" {
}
```
## Validation
## Validating parameters
Rich parameters support multiple validation modes - min, max, monotonic numbers,
and regular expressions.
Coder supports rich parameters with multiple validation modes: min, max,
monotonic numbers, and regular expressions.
### Number
A _number_ parameter can be limited to boundaries - min, max. Additionally, the
monotonicity (`increasing` or `decreasing`) between the current parameter value
and the new one can be verified too. Monotonicity can be enabled for resources
that can't be shrunk without implications, for instance - disk volume size.
You can limit a `number` parameter to `min` and `max` boundaries.
You can also specify its monotonicity as `increasing` or `decreasing` to verify
the current and new values. Use the `monotonic` aatribute for resources that
can't be shrunk or grown without implications, like disk volume size.
```hcl
data "coder_parameter" "instances" {
@ -256,9 +251,8 @@ data "coder_parameter" "instances" {
### String
A _string_ parameter can have a regular expression defined to make sure that the
parameter value matches the pattern. The `regex` property requires a
corresponding `error` property.
You can validate a `string` parameter to match a regular expression. The `regex`
property requires a corresponding `error` property.
```hcl
data "coder_parameter" "project_id" {
@ -266,106 +260,24 @@ data "coder_parameter" "project_id" {
description = "Alpha-numeric project ID"
validation {
regex = "^[a-z0-9]+$"
error = "Unfortunately, it isn't a valid project ID"
error = "Unfortunately, this isn't a valid project ID"
}
}
```
## Legacy
### Legacy parameters are unsupported now
In Coder, workspaces using legacy parameters can't be deployed anymore. To
address this, it is necessary to either remove or adjust incompatible templates.
In some cases, deleting a workspace with a hard dependency on a legacy parameter
may be challenging. To cleanup unsupported workspaces, administrators are
advised to take the following actions for affected templates:
1. Enable the `feature_use_managed_variables` provider flag.
2. Ensure that every legacy variable block has defined missing default values,
or convert it to `coder_parameter`.
3. Push the new template version using UI or CLI.
4. Update unsupported workspaces to the newest template version.
5. Delete the affected workspaces that have been updated to the newest template
version.
### Migration
> ⚠️ Migration is available until v0.24.0 (Jun 2023) release.
Terraform `variable` shouldn't be used for workspace scoped parameters anymore,
and it's required to convert `variable` to `coder_parameter` resources. To make
the migration smoother, there is a special property introduced -
`legacy_variable` and `legacy_variable_name` , which can link `coder_parameter`
with a legacy variable.
```hcl
variable "legacy_cpu" {
sensitive = false
description = "CPU cores"
default = 2
}
data "coder_parameter" "cpu" {
name = "CPU cores"
type = "number"
description = "Number of CPU cores"
mutable = true
legacy_variable_name = "legacy_cpu"
legacy_variable = var.legacy_cpu
}
```
#### Steps
1. Prepare and update a new template version:
- Add `coder_parameter` resource matching the legacy variable to migrate.
- Use `legacy_variable_name` and `legacy_variable` to link the
`coder_parameter` to the legacy variable.
- Mark the new parameter as `mutable`, so that Coder will not block updating
existing workspaces.
2. Update all workspaces to the updated template version. Coder will populate
the added `coder_parameter`s with values from legacy variables.
3. Prepare another template version:
- Remove the migrated variables.
- Remove properties `legacy_variable` and `legacy_variable_name` from
`coder_parameter`s.
4. Update all workspaces to the updated template version (2nd).
5. Prepare a third template version:
- Enable the `feature_use_managed_variables` provider flag to use managed
Terraform variables for template customization. Once the flag is enabled,
legacy variables won't be used.
6. Update all workspaces to the updated template version (3rd).
7. Delete legacy parameters.
As a template improvement, the template author can consider making some of the
new `coder_parameter` resources `mutable`.
## Terraform template-wide variables
> ⚠️ Flag `feature_use_managed_variables` is available until v0.25.0 (Jul 2023)
> release. After this release, template-wide Terraform variables will be enabled
> by default.
As parameters are intended to be used only for workspace customization purposes,
Terraform variables can be freely managed by the template author to build
templates. Workspace users are not able to modify template variables.
The template author can enable Terraform template-wide variables mode by
specifying the following flag:
```hcl
provider "coder" {
feature_use_managed_variables = "true"
}
```
Once it's defined, coder will allow for modifying variables by using CLI and UI
forms, but it will not be possible to use legacy parameters.
variable "CLOUD_API_KEY" {
type = string
description = "API key for the service"
default = "1234567890"
sensitive = true
}
```

View File

@ -1,23 +1,24 @@
# Resource Metadata
Expose key workspace information to your users via
Expose key workspace information to your users with
[`coder_metadata`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/metadata)
resources in your template code.
You can use `coder_metadata` to show Terraform resource attributes like these:
- Compute resources
- IP addresses
- [Secrets](../secrets.md#displaying-secrets)
- Important file paths
![ui](../images/metadata-ui.png)
<blockquote class="info">
Coder automatically generates the <code>type</code> metadata.
</blockquote>
You can use `coder_metadata` to show
- Compute resources
- IP addresses
- [Secrets](../secrets.md#displaying-secrets)
- Important file paths
and any other Terraform resource attribute.
You can also present automatically updating, dynamic values with
[agent metadata](./agent-metadata.md).
## Example
@ -57,10 +58,11 @@ resource "coder_metadata" "deployment" {
}
```
## Hiding resources in the UI
## Hiding resources in the dashboard
Some resources don't need to be exposed in the UI; this helps keep the workspace
view clean for developers. To hide a resource, use the `hide` attribute:
Some resources don't need to be exposed in the dashboard's UI. This helps keep
the workspace view clean for developers. To hide a resource, use the `hide`
attribute:
```hcl
resource "coder_metadata" "hide_serviceaccount" {
@ -74,10 +76,10 @@ resource "coder_metadata" "hide_serviceaccount" {
}
```
## Using custom resource icon
## Using a custom resource icon
To use custom icons on your resources, use the `icon` attribute (must be a valid
path or URL):
To use custom icons for your resource metadata, use the `icon` attribute. It
must be a valid path or URL.
```hcl
resource "coder_metadata" "resource_with_icon" {
@ -91,7 +93,8 @@ resource "coder_metadata" "resource_with_icon" {
}
```
To make easier for you to customize your resource we added some built-in icons:
To make it easier for you to customize your resource we added some built-in
icons:
- Folder `/icon/folder.svg`
- Memory `/icon/memory.svg`
@ -99,31 +102,10 @@ To make easier for you to customize your resource we added some built-in icons:
- Widgets `/icon/widgets.svg`
- Database `/icon/database.svg`
We also have other icons related to the IDEs. You can see all the icons
[here](https://github.com/coder/coder/tree/main/site/static/icon).
## Agent Metadata
In cases where you want to present automatically updating, dynamic values. You
can use the `metadata` block in the `coder_agent` resource. For example:
```hcl
resource "coder_agent" "dev" {
os = "linux"
arch = "amd64"
dir = "/workspace"
metadata {
name = "Process Count"
script = "ps aux | wc -l"
interval = 1
timeout = 3
}
}
```
Read more [here](./agent-metadata.md).
We also have other icons related to the IDEs. You can see more information on
how to use the builtin icons [here](./icons.md).
## Up next
- Learn about [secrets](../secrets.md)
- Learn about [Agent Metadata](./agent-metadata.md)
- [Secrets](../secrets.md)
- [Agent metadata](./agent-metadata.md)

View File

@ -1,25 +1,28 @@
# Resource Persistence
# Resource persistence
By default, all Coder resources are persistent, but production templates
**must** use the practices laid out in this document to prevent accidental
deletion.
Coder templates have full control over workspace ephemerality. In a completely
ephemeral workspace, there are zero resources in the Off state. In a completely
persistent workspace, there is no difference between the Off and On states.
Most workspaces fall somewhere in the middle, persisting user data such as
filesystem volumes, but deleting expensive, reproducible resources such as
The needs of most workspaces fall somewhere in the middle, persisting user data
like filesystem volumes, but deleting expensive, reproducible resources such as
compute instances.
By default, all Coder resources are persistent, but production templates
**must** employ the practices laid out in this document to prevent accidental
deletion.
## Disabling persistence
## Disabling Persistence
The
The Terraform
[`coder_workspace` data source](https://registry.terraform.io/providers/coder/coder/latest/docs/data-sources/workspace)
exposes the `start_count = [0 | 1]` attribute that other resources reference to
become ephemeral.
exposes the `start_count = [0 | 1]` attribute. To make a resource ephemeral, you
can assign the `start_count` attribute to resource's
[`count`](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
meta-argument.
For example:
In this example, Coder will provision or tear down the `docker_container`
resource:
```hcl
data "coder_workspace" "me" {
@ -32,7 +35,7 @@ resource "docker_container" "workspace" {
}
```
## ⚠️ Persistence Pitfalls
## ⚠️ Persistence pitfalls
Take this example resource:
@ -46,10 +49,10 @@ resource "docker_volume" "home_volume" {
```
Because we depend on `coder_workspace.me.owner`, if the owner changes their
username, Terraform would recreate the volume (wiping its data!) the next time
the workspace restarts.
username, Terraform will recreate the volume (wiping its data!) the next time
that Coder starts the workspace.
Therefore, persistent resource names must only depend on immutable IDs such as:
To prevent this, use immutable IDs:
- `coder_workspace.me.owner_id`
- `coder_workspace.me.id`
@ -67,12 +70,12 @@ resource "docker_volume" "home_volume" {
## 🛡 Bulletproofing
Even if our persistent resource depends exclusively on static IDs, a change to
the `name` format or other attributes would cause Terraform to rebuild the
Even if your persistent resource depends exclusively on immutable IDs, a change
to the `name` format or other attributes would cause Terraform to rebuild the
resource.
Prevent Terraform from recreating the resource under any circumstance by setting
the
You can prevent Terraform from recreating a resource under any circumstance by
setting the
[`ignore_changes = all` directive in the `lifecycle` block](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#ignore_changes).
```hcl
@ -88,7 +91,3 @@ resource "docker_volume" "home_volume" {
}
}
```
## Up next
- [Templates](../templates/index.md)

418
docs/templates/tour.md vendored Normal file
View File

@ -0,0 +1,418 @@
# A guided tour of a template
This guided tour introduces you to the different parts of a Coder template by
showing you how to create a template from scratch.
You'll write a simple template that provisions a workspace as a Docker container
with Ubuntu. This simple template is based on the same Docker starter template
that the [tutorial](./tutorial.md) uses.
## 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.
- 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).
## What's in a template
The main part of a Coder template is a [Terraform](https://terraform.io) `tf`
file. A Coder template often has other files to configure the other resources
that the template needs. In this tour you'll also create a `Dockerfile`.
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.
Here's a simplified diagram that shows the main parts of the template we'll
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`.
```shell
mkdir template-tour
cd template-tour
mkdir build
nano build/Dockerfile
```
You'll enter a simple `Dockerfile` that starts with the
[official Ubuntu image](https://hub.docker.com/_/ubuntu/). In the editor, enter
and save the following text in `Dockerfile` then exit the editor:
```dockerfile
FROM ubuntu
RUN apt-get update \
&& apt-get install -y \
sudo \
curl \
&& rm -rf /var/lib/apt/lists/*
ARG USER=coder
RUN useradd --groups sudo --no-create-home --shell /bin/bash ${USER} \
&& echo "${USER} ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/${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:
- 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
```
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:
```hcl
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "~> 0.8.3"
}
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0.1"
}
}
}
provider "coder" {
}
provider "docker" {
}
locals {
username = data.coder_workspace.me.owner
}
data "coder_provisioner" "me" {
}
data "coder_workspace" "me" {
}
```
Notice that the `provider` blocks for `coder` and `docker` are empty. In a more
practical template, you would add arguments to these blocks to configure the
providers, if needed.
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:
- Set some environment variables based on the workspace owner.
- Manage ephemeral and persistent storage.
## 3. coder_agent
All templates need to create and run a
[Coder agent](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent).
This lets developers connect to their workspaces. The `coder_agent` resource
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.
This snippet creates the agent:
```hcl
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
/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}"
}
metadata {
display_name = "CPU Usage"
key = "0_cpu_usage"
script = "coder stat cpu"
interval = 10
timeout = 1
}
metadata {
display_name = "RAM Usage"
key = "1_ram_usage"
script = "coder stat mem"
interval = 10
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
[authentication credentials](./authentication.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.
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.
Your template can use metadata to show information to the workspace owner. Coder
displays this metadata in the Coder dashboard. Our template has
[`metadata`](./agent-metadata.md) blocks for CPU and RAM usage.
## 4. coder_app
A
[`coder_app`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app)
resource lets a developer use an app from the workspace's Coder dashboard.
![Apps in a Coder workspace](../images/templates/workspace-apps.png)
This is commonly used for [web IDEs](../ides/web-ides.md) such as
[code-server](https://coder.com/docs/code-server/latest), 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](../ides/web-ides.md) for
more examples.
```hcl
resource "coder_app" "code-server" {
agent_id = coder_agent.main.id
slug = "code-server"
display_name = "code-server"
url = "http://localhost:13337/?folder=/home/${local.username}"
icon = "/icon/code.svg"
subdomain = false
share = "owner"
healthcheck {
url = "http://localhost:13337/healthz"
interval = 5
threshold = 6
}
}
```
You can also use a `coder_app` resource to link to external apps, such as links
to wikis or cloud consoles.
```hcl
resource "coder_app" "coder-server-doc" {
agent_id = coder_agent.main.id
icon = "/emojis/1f4dd.png"
slug = "getting-started"
url = "https://coder.com/docs/code-server"
external = true
}
```
## 5. Persistent and ephemeral resources
Managing the lifecycle of template resources is important. We want to make sure
that workspaces use computing, storage, and other services efficiently.
We want our workspace's home directory to persist after the workspace is stopped
so that a developer can continue their work when they start the workspace again.
We do this in 2 parts:
- Our `docker_volume` resource uses the `lifecycle` block with the
`ignore_changes = all` argument to prevent accidental deletions.
- To prevent Terraform from destroying persistent Docker volumes in case of a
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
[count](https://developer.hashicorp.com/terraform/language/meta-arguments/count)
meta-argument.
```hcl
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
}
}
```
For details, see [Resource persistence](./resource-persistence.md).
## 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.
```hcl
resource "docker_image" "main" {
name = "coder-${data.coder_workspace.me.id}"
build {
context = "./build"
build_args = {
USER = local.username
}
}
triggers = {
dir_sha1 = sha1(join("", [for f in fileset(path.module, "build/*") : filesha1(f)]))
}
}
```
Our `docker_container` resource uses `coder_workspace` `start_count` to start
and stop the Docker container:
```hcl
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)}"
# 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/${local.username}"
volume_name = docker_volume.home_volume.name
read_only = false
}
}
```
## 7. Create the template in Coder
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
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:
```console
$ coder login https://coder.example.com
Your browser has been opened to visit:
https://coder.example.com/cli-auth
> Paste your token here:
```
In your web browser, enter your credentials:
![Logging in to your Coder deployment](../images/templates/coder-login-web.png)
Copy the session token into the clipboard:
![Logging in to your Coder deployment](../images/templates/coder-session-token.png)
And paste it into the CLI:
```
> Welcome to Coder, marc! You're authenticated.
$
```
Now you can add your template files to your Coder deployment:
```console
$ pwd
/home/marc/template-tour
$ coder templates create
> Upload "."? (yes/no) yes
```
The Coder CLI tool gives progress information then prompts you to confirm:
```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]
```
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)
## Next steps
- [Setting up templates](./best-practices.md)
- [Customizing templates](./customizing.md)
- [Troubleshooting template](./troubleshooting.md)

152
docs/templates/troubleshooting.md vendored Normal file
View File

@ -0,0 +1,152 @@
# Troubleshooting templates
Occasionally, you may run into scenarios where a workspace is created, but the
agent is either not connected or the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
has failed or timed out.
## Agent connection issues
If the agent is not connected, it means the agent or
[init script](https://github.com/coder/coder/tree/main/provisionersdk/scripts)
has failed on the resource.
```console
$ coder ssh myworkspace
⢄⡱ Waiting for connection from [agent]...
```
While troubleshooting steps vary by resource, here are some general best
practices:
- Ensure the resource has `curl` installed (alternatively, `wget` or `busybox`)
- Ensure the resource can `curl` your Coder
[access URL](../admin/configure.md#access-url)
- Manually connect to the resource and check the agent logs (e.g.,
`kubectl exec`, `docker exec` or AWS console)
- The Coder agent logs are typically stored in `/tmp/coder-agent.log`
- The Coder agent startup script logs are typically stored in
`/tmp/coder-startup-script.log`
- The Coder agent shutdown script logs are typically stored in
`/tmp/coder-shutdown-script.log`
- This can also happen if the websockets are not being forwarded correctly when
running Coder behind a reverse proxy.
[Read our reverse-proxy docs](../admin/configure.md#tls--reverse-proxy)
## Startup script issues
Depending on the contents of the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script),
and whether or not the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
is set to blocking or non-blocking, you may notice issues related to the startup
script. In this section we will cover common scenarios and how to resolve them.
### Unable to access workspace, startup script is still running
If you're trying to access your workspace and are unable to because the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is still running, it means the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
option is set to blocking or you have enabled the `--wait=yes` option (for e.g.
`coder ssh` or `coder config-ssh`). In such an event, you can always access the
workspace by using the web terminal, or via SSH using the `--wait=no` option. If
the startup script is running longer than it should, or never completing, you
can try to [debug the startup script](#debugging-the-startup-script) to resolve
the issue. Alternatively, you can try to force the startup script to exit by
terminating processes started by it or terminating the startup script itself (on
Linux, `ps` and `kill` are useful tools).
For tips on how to write a startup script that doesn't run forever, see the
[`startup_script`](#startup_script) section. For more ways to override the
startup script behavior, see the
[`startup_script_behavior`](#startup_script_behavior) section.
Template authors can also set the
[startup script behavior](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script_behavior)
option to non-blocking, which will allow users to access the workspace while the
startup script is still running. Note that the workspace must be updated after
changing this option.
### Your workspace may be incomplete
If you see a warning that your workspace may be incomplete, it means you should
be aware that programs, files, or settings may be missing from your workspace.
This can happen if the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is still running or has exited with a non-zero status (see
[startup script error](#startup-script-error)). No action is necessary, but you
may want to
[start a new shell session](#session-was-started-before-the-startup-script-finished-web-terminal)
after it has completed or check the
[startup script logs](#debugging-the-startup-script) to see if there are any
issues.
### Session was started before the startup script finished
The web terminal may show this message if it was started before the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
finished, but the startup script has since finished. This message can safely be
dismissed, however, be aware that your preferred shell or dotfiles may not yet
be activated for this shell session. You can either start a new session or
source your dotfiles manually. Note that starting a new session means that
commands running in the terminal will be terminated and you may lose unsaved
work.
Examples for activating your preferred shell or sourcing your dotfiles:
- `exec zsh -l`
- `source ~/.bashrc`
### Startup script exited with an error
When the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
exits with an error, it means the last command run by the script failed. When
`set -e` is used, this means that any failing command will immediately exit the
script and the remaining commands will not be executed. This also means that
[your workspace may be incomplete](#your-workspace-may-be-incomplete). If you
see this error, you can check the
[startup script logs](#debugging-the-startup-script) to figure out what the
issue is.
Common causes for startup script errors:
- A missing command or file
- A command that fails due to missing permissions
- Network issues (e.g., unable to reach a server)
### Debugging the startup script
The simplest way to debug the
[startup script](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#startup_script)
is to open the workspace in the Coder dashboard and click "Show startup log" (if
not already visible). This will show all the output from the script. Another
option is to view the log file inside the workspace (usually
`/tmp/coder-startup-script.log`). If the logs don't indicate what's going on or
going wrong, you can increase verbosity by adding `set -x` to the top of the
startup script (note that this will show all commands run and may output
sensitive information). Alternatively, you can add `echo` statements to show
what's going on.
Here's a short example of an informative startup script:
```shell
echo "Running startup script..."
echo "Run: long-running-command"
/path/to/long-running-command
status=$?
echo "Done: long-running-command, exit status: ${status}"
if [ $status -ne 0 ]; then
echo "Startup script failed, exiting..."
exit $status
fi
```
> **Note:** We don't use `set -x` here because we're manually echoing the
> commands. This protects against sensitive information being shown in the log.
This script tells us what command is being run and what the exit status is. If
the exit status is non-zero, it means the command failed and we exit the script.
Since we are manually checking the exit status here, we don't need `set -e` at
the top of the script to exit on error.

130
docs/templates/tutorial.md vendored Normal file
View File

@ -0,0 +1,130 @@
# Your first template
A common way to create a template is to begin with a starter template then
modify it for your needs. Coder makes this easy with starter templates for
popular development targets like Docker, Kubernetes, Azure, and so on. Once your
template is up and running, you can edit it in the Coder dashboard. Coder even
handles versioning for you so you can publish official updates or revert to
previous versions.
In this tutorial, you'll create your first template from the Docker starter
template.
## Before you start
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.
## 1. Log in to Coder
In your web browser, go to your Coder dashboard to log in.
## 2. Choose a starter template
Select **Templates** > **Starter Templates**.
![Starter Templates button](../images/templates/starter-templates-button.png)
In **Filter**, select **Docker** then select **Develop in Docker**.
![Choosing a starter template](../images/templates/develop-in-docker-template.png)
Select **Use template**.
![Using a starter template](../images/templates/use-template.png)
## 3. Create your template
In **Create template**, fill in **Name** and **Display name**,then scroll down
and select **Create template**.
![Creating a template](../images/templates/create-template.png)
## 4. Create a workspace from your template
When the template is ready, select **Create Workspace**.
![Create workspace](../images/templates/create-workspace.png)
In **New workspace**, fill in **Name** then scroll down to select **Create
Workspace**.
![New workspace](../images/templates/new-workspace.png)
Coder starts your new workspace from your template.
After a few seconds, your workspace is ready to use.
![Workspace is ready](../images/templates/workspace-ready.png)
## 5. Try out your new workspace
This starter template lets you connect to your workspace in a few ways:
- VS Code Desktop: Loads your workspace into
[VS Code Desktop](https://code.visualstudio.com/Download) installed on your
local computer.
- code-server: Opens [browser-based VS Code](../ides/web-ides.md) with your
workspace.
- Terminal: Opens a browser-based terminal with a shell in the workspace's
Docker instance.
- SSH: Use SSH to log in to the workspace from your local machine. If you
haven't already, you'll have to install Coder on your local machine to
configure your SSH client.
> **Tip**: You can edit the template to let developers connect to a workspace in
> [a few more ways](../ides.md).
When you're done, you can stop the workspace.
## 6. Modify your template
Now you can modify your template to suit your team's needs.
Let's replace the `golang` package in the Docker image with the `python3`
package. You can do this by editing the template's `Dockerfile` directly in your
web browser.
In the Coder dashboard, select **Templates** then your first template.
![Selecting the first template](../images/templates/select-template.png)
In the drop-down menu, select **Edit files**.
![Edit template files](../images/templates/edit-files.png)
Expand the **build** directory and select **Dockerfile**.
![Selecting source code](../images/templates/source-code.png)
Edit `build/Dockerfile` to replace `golang` with `python3`.
![Editing source code](../images/templates/edit-source-code.png)
Select **Build template** and wait for Coder to prepare the template for
workspaces.
![Building a template](../images/templates/build-template.png)
Select **Publish version**. In the **Publish new version** dialog, make sure
**Promote to default version** is checked then select **Publish**.
![Publish a template](../images/templates/publish.png)
Now when developers create a new workspace from this template, they can use
Python 3 instead of Go.
For developers with workspaces that were created with a previous version of your
template, Coder will notify them that there's a new version of the template.
You can also handle [change management](./change-management.md) through your own
repo and continuous integration.
## Next steps
- [Write your own template](./tour.md)
- [Setting up templates](./best-practices.md)

View File

@ -1,9 +1,25 @@
# Workspaces
Workspaces contain the IDEs, dependencies, and configuration information needed
for software development.
A workspace is the environment that a developer works in. Developers in a team
each work from their own workspace and can use [multiple IDEs](./ides.md).
## Create workspaces
A developer creates a workspace from a [shared template](./templates/index.md).
This lets an entire team work in environments that are identically configured
and provisioned with the same resources.
## Creating workspaces
You can create a workspace in the UI. Log in to your Coder instance, go to the
**Templates** tab, find the template you need, and select **Create Workspace**.
![Creating a workspace in the UI](./images/creating-workspace-ui.png)
When you create a workspace, you will be prompted to give it a name. You might
also be prompted to set some parameters that the template provides.
You can manage your existing templates in the **Workspaces** tab.
You can also create a workspace from the command line:
Each Coder user has their own workspaces created from
[shared templates](./templates/index.md):
@ -16,11 +32,72 @@ coder create --template="<templateName>" <workspaceName>
coder show <workspace-name>
```
## IDEs
## Workspace filtering
Coder [supports multiple IDEs](./ides.md) for use with your workspaces.
In the Coder UI, you can filter your workspaces using pre-defined filters or
Coder's filter query. For example, you can find the workspaces that you own or
that are currently running.
## Workspace lifecycle
The following filters are supported:
- `owner` - Represents the `username` of the owner. You can also use `me` as a
convenient alias for the logged-in user.
- `template` - Specifies the name of the template.
- `status` - Indicates the status of the workspace. For a list of supported
statuses, see
[WorkspaceStatus documentation](https://pkg.go.dev/github.com/coder/coder/codersdk#WorkspaceStatus).
## Starting and stopping workspaces
By default, you manually start and stop workspaces as you need. You can also
schedule a workspace to start and stop automatically.
To set a workspace's schedule, go to the workspace, then **Settings** >
**Schedule**.
![Scheduling UI](./images/schedule.png)
Coder might also stop a workspace automatically if there is a
[template update](./templates/index.md#Start/stop) available.
### Autostart and autostop
Use autostart to start a workspace at a specified time and which days of the
week. Also, you can choose your preferred timezone.
![Autostart UI](./images/autostart.png)
Use autostop to stop a workspace after a number of hours. Autostop won't stop a
workspace if you're still using it. It waits for another hour before checking
again. Coder checks for active connections in the IDE, SSH, Port Forwarding, and
coder_app.
![Autostop UI](./images/autostop.png)
### Max lifetime
Max lifetime is a template setting that determines the number of hours a
workspace will run before Coder automatically stops it, regardless of any active
connections. Use this setting to ensure that workspaces do not run in perpetuity
when connections are left open inadvertently.
## Updating workspaces
After updating the default version of the template that a workspace was created
from, you can update the workspace.
![Updating a workspace](./images/workspace-update.png)
If the workspace is running, Coder stops it, updates it, then starts the
workspace again.
On the command line:
```shell
coder update <workspace-name>
```
## Workspace resources
Workspaces in Coder are started and stopped, often based on whether there was
any activity or if there was a
@ -33,53 +110,13 @@ though the exact behavior depends on the template. For more information, see
> ⚠️ To avoid data loss, refer to your template documentation for information on
> where to store files, install software, etc., so that they persist. Default
> templates are documented in
> [../examples/templates](https://github.com/coder/coder/tree/c6b1daabc5a7aa67bfbb6c89966d728919ba7f80/examples/templates).
> [../examples/templates](https://github.com/coder/coder/tree/main/examples/templates).
>
> You can use `coder show <workspace-name>` to see which resources are
> persistent and which are ephemeral.
When a workspace is deleted, all of the workspace's resources are deleted.
## Workspace scheduling
By default, workspaces are manually turned on/off by the user. However, a
schedule can be defined on a per-workspace basis to automate the workspace
start/stop.
![Scheduling UI](./images/schedule.png)
### Autostart
The autostart feature automates the workspace build at a user-specified time and
day(s) of the week. In addition, users can select their preferred timezone.
![Autostart UI](./images/autostart.png)
### Autostop
The autostop feature shuts off workspaces after given number of hours in the
"on" state. If Coder detects workspace connection activity, the autostop timer
is bumped up one hour. IDE, SSH, Port Forwarding, and coder_app activity trigger
this bump.
![autostop UI](./images/autostop.png)
### Max lifetime
Max lifetime is a template-level setting that determines the number of hours a
workspace can run before it is automatically shutdown, regardless of any active
connections. This setting ensures workspaces do not run in perpetuity when
connections are left open inadvertently.
## Updating workspaces
Use the following command to update a workspace to the latest template version.
The workspace will be stopped and started:
```shell
coder update <workspace-name>
```
## Repairing workspaces
Use the following command to re-enter template input variables in an existing
@ -90,6 +127,33 @@ state is out of sync with the template.
coder update <your workspace name> --always-prompt
```
First, try re-entering parameters from a workspace. In the Coder UI, you can
filter your workspaces using pre-defined filters or employing the Coder's filter
query. Take a look at the following examples to understand how to use the
Coder's filter query:
- To find the workspaces that you own, use the filter `owner:me`.
- To find workspaces that are currently running, use the filter
`status:running`.
![Re-entering template variables](./images/template-variables.png)
You can also do this in the CLI with the following command:
```shell
coder update <your workspace name> --always-prompt
```
If that does not work, a Coder admin can manually push and pull the Terraform
state for a given workspace. This can lead to state corruption or deleted
resources if you do not know what you are doing.
```shell
coder state pull <username>/<workspace name>
# Make changes
coder state push <username>/<workspace name>
```
## Logging
Coder stores macOS and Linux logs at the following locations:
@ -102,27 +166,6 @@ Coder stores macOS and Linux logs at the following locations:
> Note: Logs are truncated once they reach 5MB in size.
## Workspace filtering
In the Coder UI, you can filter your workspaces using pre-defined filters or
employing the Coder's filter query. Take a look at the following examples to
understand how to use the Coder's filter query:
- To find the workspaces that you own, use the filter `owner:me`.
- To find workspaces that are currently running, use the filter
`status:running`.
The following filters are supported:
- `owner` - Represents the `username` of the owner. You can also use `me` as a
convenient alias for the logged-in user.
- `template` - Specifies the name of the template.
- `status` - Indicates the status of the workspace. For a list of supported
statuses, please refer to the
[WorkspaceStatus documentation](https://pkg.go.dev/github.com/coder/coder/v2/codersdk#WorkspaceStatus).
---
## Up next
- Learn about how to personalize your workspace with [Dotfiles](./dotfiles.md)

BIN
filebrowser.db Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -51,7 +51,7 @@ export const EmptyTemplates: FC<{
for workspaces (e.g., docker_container, aws_instance,
kubernetes_pod). Select a starter template below or
<Link
href={docs("/templates#add-a-template")}
href={docs("/templates/tutorial")}
target="_blank"
rel="noreferrer"
>

View File

@ -68,7 +68,7 @@ const TemplateHelpTooltip: React.FC = () => {
<HelpTooltipTitle>{Language.templateTooltipTitle}</HelpTooltipTitle>
<HelpTooltipText>{Language.templateTooltipText}</HelpTooltipText>
<HelpTooltipLinksGroup>
<HelpTooltipLink href={docs("/templates#manage-templates")}>
<HelpTooltipLink href={docs("/templates")}>
{Language.templateTooltipLink}
</HelpTooltipLink>
</HelpTooltipLinksGroup>

View File

@ -0,0 +1,139 @@
import { AlertColor } from "@mui/material/Alert/Alert";
import Button from "@mui/material/Button";
import Link from "@mui/material/Link";
import { Alert } from "components/Alert/Alert";
import { ReactNode } from "react";
import { docs } from "utils/docs";
export type TerminalPageAlertType = "error" | "starting" | "success";
type MapAlertTypeToComponent = {
[key in TerminalPageAlertType]: {
severity: AlertColor;
children: ReactNode | undefined;
};
};
const mapAlertTypeToText: MapAlertTypeToComponent = {
error: {
severity: "warning",
children: (
<>
The workspace{" "}
<Link
title="startup script has exited with an error"
href={docs(
"/templates/troubleshooting#startup-script-exited-with-an-error",
)}
target="_blank"
rel="noreferrer"
>
startup script has exited with an error
</Link>
, we recommend reloading this session and{" "}
<Link
title=" debugging the startup script"
href={docs("/templates/troubleshooting#debugging-the-startup-script")}
target="_blank"
rel="noreferrer"
>
debugging the startup script
</Link>{" "}
because{" "}
<Link
title="your workspace may be incomplete."
href={docs(
"/templates/troubleshooting#your-workspace-may-be-incomplete",
)}
target="_blank"
rel="noreferrer"
>
your workspace may be incomplete.
</Link>{" "}
</>
),
},
starting: {
severity: "info",
children: (
<>
Startup script is still running. You can continue using this terminal,
but{" "}
<Link
title="your workspace may be incomplete."
href={docs(
"/templates/troubleshooting#your-workspace-may-be-incomplete",
)}
target="_blank"
rel="noreferrer"
>
{" "}
your workspace may be incomplete.
</Link>
</>
),
},
success: {
severity: "success",
children: (
<>
Startup script has completed successfully. The workspace is ready but
this{" "}
<Link
title="session was started before the startup script finished"
href={docs(
"/templates/troubleshooting#your-workspace-may-be-incomplete",
)}
target="_blank"
rel="noreferrer"
>
session was started before the startup script finished.
</Link>{" "}
To ensure your shell environment is up-to-date, we recommend reloading
this session.
</>
),
},
};
export default ({
alertType,
onDismiss,
}: {
alertType: TerminalPageAlertType;
onDismiss: () => void;
}) => {
const severity = mapAlertTypeToText[alertType].severity;
return (
<Alert
severity={severity}
sx={{
borderRadius: 0,
borderWidth: 0,
borderBottomWidth: 1,
borderBottomColor: (theme) => theme.palette.divider,
backgroundColor: (theme) => theme.palette.background.paperLight,
borderLeft: (theme) => `3px solid ${theme.palette[severity].light}`,
marginBottom: 1,
}}
onDismiss={onDismiss}
dismissible
actions={[
<Button
key="refresh-session"
size="small"
variant="text"
onClick={() => {
// By redirecting the user without the session in the URL we
// create a new one
window.location.href = window.location.pathname;
}}
>
Refresh session
</Button>,
]}
>
{mapAlertTypeToText[alertType].children}
</Alert>
);
};

View File

@ -23,15 +23,12 @@ export const WorkspaceHelpTooltip: FC = () => {
<HelpTooltipTitle>{Language.workspaceTooltipTitle}</HelpTooltipTitle>
<HelpTooltipText>{Language.workspaceTooltipText}</HelpTooltipText>
<HelpTooltipLinksGroup>
<HelpTooltipLink href={docs("/workspaces#create-workspaces")}>
<HelpTooltipLink href={docs("/workspaces")}>
{Language.workspaceTooltipLink1}
</HelpTooltipLink>
<HelpTooltipLink href={docs("/workspaces#connect-with-ssh")}>
<HelpTooltipLink href={docs("/ides")}>
{Language.workspaceTooltipLink2}
</HelpTooltipLink>
<HelpTooltipLink href={docs("/workspaces#editors-and-ides")}>
{Language.workspaceTooltipLink3}
</HelpTooltipLink>
</HelpTooltipLinksGroup>
</HelpTooltip>
);