# Offline Deployments All Coder features are supported in offline / behind firewalls / in air-gapped environments. However, some changes to your configuration are necessary. This is a general comparison. Keep reading for a full tutorial running Coder offline with Kubernetes or Docker. | | Public deployments | Offline deployments | |--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Terraform binary | By default, Coder downloads Terraform binary from [releases.hashicorp.com](https://releases.hashicorp.com) | Terraform binary must be included in `PATH` for the VM or container image. [Supported versions](https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24) | | Terraform registry | Coder templates will attempt to download providers from [registry.terraform.io](https://registry.terraform.io) or [custom source addresses](https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses) specified in each template | [Custom source addresses](https://developer.hashicorp.com/terraform/language/providers/requirements#source-addresses) can be specified in each Coder template, or a custom registry/mirror can be used. More details below | | STUN | By default, Coder uses Google's public STUN server for direct workspace connections | STUN can be safely [disabled](../reference/cli/server.md#--derp-server-stun-addresses) users can still connect via [relayed connections](../admin/networking/index.md#-geo-distribution). Alternatively, you can set a [custom DERP server](../reference/cli/server.md#--derp-server-stun-addresses) | | DERP | By default, Coder's built-in DERP relay can be used, or [Tailscale's public relays](../admin/networking/index.md#relayed-connections). | By default, Coder's built-in DERP relay can be used, or [custom relays](../admin/networking/index.md#custom-relays). | | PostgreSQL | If no [PostgreSQL connection URL](../reference/cli/server.md#--postgres-url) is specified, Coder will download Postgres from [repo1.maven.org](https://repo1.maven.org) | An external database is required, you must specify a [PostgreSQL connection URL](../reference/cli/server.md#--postgres-url) | | Telemetry | Telemetry is on by default, and [can be disabled](../reference/cli/server.md#--telemetry) | Telemetry [can be disabled](../reference/cli/server.md#--telemetry) | | Update check | By default, Coder checks for updates from [GitHub releases](https://github.com/coder/coder/releases) | Update checks [can be disabled](../reference/cli/server.md#--update-check) | ## Offline container images The following instructions walk you through how to build a custom Coder server image for Docker or Kubernetes First, build and push a container image extending our official image with the following: - CLI config (.tfrc) for Terraform referring to [external mirror](https://www.terraform.io/cli/config/config-file#explicit-installation-method-configuration) - [Terraform Providers](https://registry.terraform.io) for templates - These could also be specified via a volume mount (Docker) or [network mirror](https://www.terraform.io/internals/provider-network-mirror-protocol). See below for details. > [!NOTE] > Coder includes the latest > [supported version](https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24) > of Terraform in the official Docker images. If you need to bundle a different > version of terraform, you can do so by customizing the image. Here's an example Dockerfile: ```Dockerfile FROM ghcr.io/coder/coder:latest USER root RUN apk add curl unzip # Create directory for the Terraform CLI (and assets) RUN mkdir -p /opt/terraform # Terraform is already included in the official Coder image. # See https://github.com/coder/coder/blob/main/scripts/Dockerfile.base#L15 # If you need to install a different version of Terraform, you can do so here. # The below step is optional if you wish to keep the existing version. # See https://github.com/coder/coder/blob/main/provisioner/terraform/install.go#L23-L24 # for supported Terraform versions. ARG TERRAFORM_VERSION=1.11.0 RUN apk update && \ apk del terraform && \ curl -LOs https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ && unzip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ && mv terraform /opt/terraform \ && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip ENV PATH=/opt/terraform:${PATH} # Additionally, a Terraform mirror needs to be configured # to download the Terraform providers used in Coder templates. # There are two options: # Option 1) Use a filesystem mirror. # We can seed this at build-time or by mounting a volume to # /opt/terraform/plugins in the container. # https://developer.hashicorp.com/terraform/cli/config/config-file#filesystem_mirror # Be sure to add all the providers you use in your templates to /opt/terraform/plugins RUN mkdir -p /home/coder/.terraform.d/plugins/registry.terraform.io ADD filesystem-mirror-example.tfrc /home/coder/.terraformrc # Optionally, we can "seed" the filesystem mirror with common providers. # Comment out lines 40-49 if you plan on only using a volume or network mirror: WORKDIR /home/coder/.terraform.d/plugins/registry.terraform.io ARG CODER_PROVIDER_VERSION=2.2.0 RUN echo "Adding coder/coder v${CODER_PROVIDER_VERSION}" \ && mkdir -p coder/coder && cd coder/coder \ && curl -LOs https://github.com/coder/terraform-provider-coder/releases/download/v${CODER_PROVIDER_VERSION}/terraform-provider-coder_${CODER_PROVIDER_VERSION}_linux_amd64.zip ARG DOCKER_PROVIDER_VERSION=3.0.2 RUN echo "Adding kreuzwerker/docker v${DOCKER_PROVIDER_VERSION}" \ && mkdir -p kreuzwerker/docker && cd kreuzwerker/docker \ && curl -LOs https://github.com/kreuzwerker/terraform-provider-docker/releases/download/v${DOCKER_PROVIDER_VERSION}/terraform-provider-docker_${DOCKER_PROVIDER_VERSION}_linux_amd64.zip ARG KUBERNETES_PROVIDER_VERSION=2.36.0 RUN echo "Adding kubernetes/kubernetes v${KUBERNETES_PROVIDER_VERSION}" \ && mkdir -p hashicorp/kubernetes && cd hashicorp/kubernetes \ && curl -LOs https://releases.hashicorp.com/terraform-provider-kubernetes/${KUBERNETES_PROVIDER_VERSION}/terraform-provider-kubernetes_${KUBERNETES_PROVIDER_VERSION}_linux_amd64.zip ARG AWS_PROVIDER_VERSION=5.89.0 RUN echo "Adding aws/aws v${AWS_PROVIDER_VERSION}" \ && mkdir -p aws/aws && cd aws/aws \ && curl -LOs https://releases.hashicorp.com/terraform-provider-aws/${AWS_PROVIDER_VERSION}/terraform-provider-aws_${AWS_PROVIDER_VERSION}_linux_amd64.zip RUN chown -R coder:coder /home/coder/.terraform* WORKDIR /home/coder # Option 2) Use a network mirror. # https://developer.hashicorp.com/terraform/cli/config/config-file#network_mirror # Be sure uncomment line 60 and edit network-mirror-example.tfrc to # specify the HTTPS base URL of your mirror. # ADD network-mirror-example.tfrc /home/coder/.terraformrc USER coder # Use the .terraformrc file to inform Terraform of the locally installed providers. ENV TF_CLI_CONFIG_FILE=/home/coder/.terraformrc ``` > [!NOTE] > If you are bundling Terraform providers into your Coder image, be sure the > provider version matches any templates or > [example templates](https://github.com/coder/coder/tree/main/examples/templates) > you intend to use. ```tf # filesystem-mirror-example.tfrc provider_installation { filesystem_mirror { path = "/home/coder/.terraform.d/plugins" } } ``` ```tf # network-mirror-example.tfrc provider_installation { network_mirror { url = "https://terraform.example.com/providers/" } } ```