|
| 1 | +# Offline Deployments |
| 2 | + |
| 3 | +Coder can run in offline / air-gapped environments. |
| 4 | + |
| 5 | +## Building & push a custom Coder image |
| 6 | + |
| 7 | +First, build and push a container image extending our official image with the following: |
| 8 | + |
| 9 | +- Terraform [(supported versions)](https://github.com/coder/coder/blob/main/provisioner/terraform/serve.go#L24-L25) |
| 10 | +- CLI config (.tfrc) for Terraform referring to [external mirror](https://www.terraform.io/cli/config/config-file#explicit-installation-method-configuration) |
| 11 | +- [Terraform Providers](https://registry.terraform.io) for templates |
| 12 | + - 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. |
| 13 | + |
| 14 | +Here's an example: |
| 15 | + |
| 16 | +```Dockerfile |
| 17 | +# Dockerfile |
| 18 | +FROM ghcr.io/coder/coder:latest |
| 19 | + |
| 20 | +USER root |
| 21 | + |
| 22 | +RUN apk add curl unzip |
| 23 | + |
| 24 | +# Create directory for the Terraform CLI (and assets) |
| 25 | +RUN mkdir -p /opt/terraform |
| 26 | + |
| 27 | +# In order to run Coder airgapped or within private networks, |
| 28 | +# Terraform has to be bundled into the image in PATH or /opt. |
| 29 | +# |
| 30 | +# See https://github.com/coder/coder/blob/main/provisioner/terraform/serve.go#L24-L25 |
| 31 | +# for supported Terraform versions. |
| 32 | +ARG TERRAFORM_VERSION=1.3.0 |
| 33 | +RUN curl -LOs https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ |
| 34 | + && unzip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip \ |
| 35 | + && mv terraform /opt/terraform \ |
| 36 | + && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip |
| 37 | +ENV PATH=/opt/terraform:${PATH} |
| 38 | + |
| 39 | +# Additionally, a Terraform mirror needs to be configured |
| 40 | +# to download the Terraform providers used in Coder templates. |
| 41 | +# |
| 42 | +# There are two options: |
| 43 | + |
| 44 | +# Option 1) Use a filesystem mirror. We can seed this at build-time |
| 45 | +# or by mounting a volume to /opt/terraform/plugins in the container. |
| 46 | +# https://developer.hashicorp.com/terraform/cli/config/config-file#filesystem_mirror |
| 47 | +# |
| 48 | +# Be sure to add all the providers you use in your templates to /opt/terraform/plugins |
| 49 | + |
| 50 | +RUN mkdir -p /opt/terraform/plugins |
| 51 | +ADD filesystem-mirror-example.tfrc /opt/terraform/config.tfrc |
| 52 | + |
| 53 | +# Optionally, we can "seed" the filesystem mirror with common providers. |
| 54 | +# Coder and Docker. Comment out lines 37-47 if you plan on only using a |
| 55 | +# volume or network mirror: |
| 56 | +RUN mkdir -p /opt/terraform/plugins/registry.terraform.io |
| 57 | +WORKDIR /opt/terraform/plugins/registry.terraform.io |
| 58 | +ARG CODER_PROVIDER_VERSION=0.5.3 |
| 59 | +RUN echo "Adding coder/coder v${CODER_PROVIDER_VERSION}" \ |
| 60 | + && mkdir -p coder/coder && cd coder/coder \ |
| 61 | + && curl -LOs https://github.com/coder/terraform-provider-coder/releases/download/v${CODER_PROVIDER_VERSION}/terraform-provider-coder_${CODER_PROVIDER_VERSION}_linux_amd64.zip |
| 62 | +ARG DOCKER_PROVIDER_VERSION=2.22.0 |
| 63 | +RUN echo "Adding kreuzwerker/docker v${DOCKER_PROVIDER_VERSION}" \ |
| 64 | + && mkdir -p kreuzwerker/docker && cd kreuzwerker/docker \ |
| 65 | + && curl -LOs https://github.com/kreuzwerker/terraform-provider-docker/releases/download/v${DOCKER_PROVIDER_VERSION}/terraform-provider-docker_${DOCKER_PROVIDER_VERSION}_linux_amd64.zip |
| 66 | + |
| 67 | +RUN chown -R coder:coder /opt/terraform/plugins |
| 68 | +WORKDIR /home/coder |
| 69 | + |
| 70 | +# Option 2) Use a network mirror. |
| 71 | +# https://developer.hashicorp.com/terraform/cli/config/config-file#network_mirror |
| 72 | + |
| 73 | +# Be sure uncomment line 56 and edit network-mirror-example.tfrc to |
| 74 | +# specify the HTTPS base URL of your mirror. |
| 75 | + |
| 76 | +# ADD network-mirror-example.tfrc /opt/terraform/config.tfrc |
| 77 | + |
| 78 | +USER coder |
| 79 | + |
| 80 | +# Use the tfrc file to inform |
| 81 | +ENV TF_CLI_CONFIG_FILE=/opt/terraform/config.tfrc |
| 82 | +``` |
| 83 | + |
| 84 | +```hcl |
| 85 | +# filesystem-mirror-example.tfrc |
| 86 | +provider_installation { |
| 87 | + filesystem_mirror { |
| 88 | + path = "/opt/terraform/plugins" |
| 89 | + } |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +```hcl |
| 94 | +# network-mirror-example.tfrc |
| 95 | +provider_installation { |
| 96 | + network_mirror { |
| 97 | + url = "https://terraform.example.com/providers/" |
| 98 | + } |
| 99 | +} |
| 100 | +``` |
| 101 | + |
| 102 | +## Run offline via Docker |
| 103 | + |
| 104 | +Follow our [docker-compose](./docker.md#run-coder-with-docker-compose) documentation and modify the docker-compose file to specify your custom Coder image. Additionally, you can add a volume mount to add providers to the filesystem mirror without re-building the image. |
| 105 | + |
| 106 | +First, make a create an empty plugins directory: |
| 107 | + |
| 108 | +```sh |
| 109 | +mkdir $HOME/plugins |
| 110 | +``` |
| 111 | + |
| 112 | +Next, add a volume mount to docker-compose.yaml: |
| 113 | + |
| 114 | +```sh |
| 115 | +vim docker-compose.yaml |
| 116 | +``` |
| 117 | + |
| 118 | +```yaml |
| 119 | +# docker-compose.yaml |
| 120 | +version: "3.9" |
| 121 | +services: |
| 122 | + coder: |
| 123 | + image: registry.example.com/coder:latest |
| 124 | + volumes: |
| 125 | + - ./plugins:/opt/registry.terraform.io |
| 126 | + # ... |
| 127 | + database: |
| 128 | + image: registry.example.com/postgres:13 |
| 129 | + # ... |
| 130 | +``` |
| 131 | + |
| 132 | +> The [terraform providers mirror](https://www.terraform.io/cli/commands/providers/mirror) command can be used to download the required plugins for a Coder template. This can be uploaded into the `plugins` directory on your offline server. |
| 133 | +
|
| 134 | +## Run offline via Kubernetes |
| 135 | + |
| 136 | +We publish the Helm chart for download on [GitHub Releases](https://github.com/coder/coder/releases). Follow our [Kubernetes](./kubernetes.md) documentation and modify the Helm values to specify your custom Coder image. |
| 137 | + |
| 138 | +```yaml |
| 139 | +# values.yaml |
| 140 | +coder: |
| 141 | + image: |
| 142 | + repo: "registry.example.com/coder" |
| 143 | + tag: "latest" |
| 144 | +# ... |
| 145 | +``` |
0 commit comments