- Notifications
You must be signed in to change notification settings - Fork1k
Proxy port from sidecar container#20140
-
I am trying to deployCopyParty as a sidecar application and expose the web interface through the Coder proxy. From inside the main workspace container, I can The button on the workspace dashboard shows the correct subdomain proxy URL, but I get a
terraform {required_providers {coder={ source="coder/coder" version=">=2.5.3" }docker={ source="kreuzwerker/docker" } }}#================================================================## Variables & Locals#================================================================locals {folder_name=try(trimsuffix(element(split("/", data.coder_parameter.repo.value),length(split("/", data.coder_parameter.repo.value))-1),".git"),"")repo_owner_name=try(element(split("/", data.coder_parameter.repo.value),length(split("/", data.coder_parameter.repo.value))-2),"")repo_host=try(one(regex("^(?:https?:\\/\\/)?(?:[^@\\/\\n]+@)?(?:www\\.)?([^:\\/\\n]+)", data.coder_parameter.repo.value)),"")root_dir="/workspace"username=data.coder_workspace_owner.me.name# Consolidated values for easier configurationdocker_host="unix:///var/run/docker.sock"container_image="docker.io/codercom/enterprise-base:ubuntu"# Centralized Docker labels to avoid repetitioncommon_docker_labels={"coder.owner"= data.coder_workspace_owner.me.name"coder.owner_id"= data.coder_workspace_owner.me.id"coder.workspace_id"= data.coder_workspace.me.id }# Define all IDE parameters in one place for easy managementide_parameters={"coder"="Coder IDE""jetbrains_primary"="JetBrains IDE (Primary)""jetbrains_secondary"="JetBrains IDE (Secondary)" }# Define cache cleanup configurations in a mapcache_cleanup_jobs={"jetbrains"= { display_name="JetBrains Cache Cleanup" icon="/icon/jetbrains-toolbox.svg" cache_path="JetBrains/RemoteDev/dist" }"code-server"= { display_name="Code-Server Cache Cleanup" icon="/icon/coder.svg" cache_path="code-server" } }}#================================================================## Providers#================================================================provider"coder" {}provider"docker" {host=local.docker_host}#================================================================## Data Sources#================================================================data"coder_provisioner""me" {}data"coder_workspace""me" {}data"coder_workspace_owner""me" {}data"coder_parameter""repo" {name="Source Code Repository"type="string"description="What source code repository do you want to clone?"mutable=trueicon="/icon/git.svg"}# https://playground.coder.app/parameters# https://coder.com/docs/@v2.26.0/admin/templates/extending-templates/dynamic-parameters# Generate IDE toggles dynamically using for_eachdata"coder_parameter""ide_toggle" {for_each=local.ide_parametersname="enable_${each.key}"display_name="Enable${each.value}"type="bool"form_type="checkbox"default=false}#================================================================## Resources#================================================================# https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agentresource"coder_agent""main" {arch=data.coder_provisioner.me.archos=data.coder_provisioner.me.osdir=local.root_dirorder=1display_apps {vscode=falsevscode_insiders=falseweb_terminal=truessh_helper=true }startup_script_behavior="blocking"startup_script=<<-EOT set -euo pipefail # Prepare user home with default files on first start. if [ ! -f ~/.init_done ]; then cp -rT /etc/skel ~ touch ~/.init_done fi # Add any commands that should be executed at workspace startup (e.g install requirements, start a program, etc) here # Add repo host to known hosts if test -z "${local.repo_host}" then echo "No git repo specified, skipping" else echo "Adding repo to known hosts" mkdir -p ~/.ssh ssh-keyscan -t rsa "${local.repo_host}" >> ~/.ssh/known_hosts fi EOTenv={ GIT_AUTHOR_NAME=coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) GIT_AUTHOR_EMAIL= data.coder_workspace_owner.me.email GIT_COMMITTER_NAME=coalesce(data.coder_workspace_owner.me.full_name, data.coder_workspace_owner.me.name) GIT_COMMITTER_EMAIL= data.coder_workspace_owner.me.email }metadata {display_name="CPU Usage"key="0_cpu_usage"script="coder stat cpu"interval=10timeout=1 }metadata {display_name="RAM Usage"key="1_ram_usage"script="coder stat mem"interval=10timeout=1 }metadata {display_name="Home Disk"key="3_home_disk"script="coder stat disk --path $${HOME}"interval=60timeout=1 }metadata {display_name="CPU Usage (Host)"key="4_cpu_usage_host"script="coder stat cpu --host"interval=10timeout=1 }metadata {display_name="Memory Usage (Host)"key="5_mem_usage_host"script="coder stat mem --host"interval=10timeout=1 }metadata {display_name="Load Average (Host)"key="6_load_host"script=<<EOT echo "`cat /proc/loadavg | awk '{ print $1 }'` `nproc`" | awk '{ printf "%0.2f", $1/$2 }' EOTinterval=60timeout=1 }}# Single resource to handle all cache cleanup jobsresource"coder_script""cache_cleanup" {# If the workspace is starting, iterate over the jobs.# Otherwise, iterate over an empty map {} to create nothing.for_each=data.coder_workspace.me.start_count>0? local.cache_cleanup_jobs: {}agent_id=coder_agent.main.iddisplay_name=each.value.display_nameicon=each.value.iconrun_on_start=truestart_blocks_login=falsetimeout=180script=<<-EOT set -euo pipefail sleep 60 DIST_DIR="$${HOME}/.cache/${each.value.cache_path}/" if [[ -d $${DIST_DIR} ]]; then find $${DIST_DIR} -mindepth 1 -maxdepth 1 -type d -printf '%T@\t%p\n' \ | sort -n | head -n -1 | cut -f2- | xargs -I {} rm -rf "{}" else echo "${each.value.display_name} Directory $${DIST_DIR} does not exist." fi EOT}resource"docker_volume""home_volume" {name="coder-${data.coder_workspace.me.id}-home"lifecycle {ignore_changes=all }# Use a dynamic block to generate the repeating "labels" blocks# required by the docker_volume resource.dynamic"labels" {for_each=merge(local.common_docker_labels, {"coder.workspace_name_at_creation"= data.coder_workspace.me.name })content {label=labels.keyvalue=labels.value } }}resource"docker_volume""workspace_volume" {name="coder-${data.coder_workspace.me.id}-workspace"lifecycle {ignore_changes=all }# Use the same dynamic block structure here.dynamic"labels" {for_each=merge(local.common_docker_labels, {"coder.workspace_name_at_creation"= data.coder_workspace.me.name })content {label=labels.keyvalue=labels.value } }}resource"docker_container""workspace" {count=data.coder_workspace.me.start_countimage=local.container_imagename="coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}"hostname=data.coder_workspace.me.namememory=0entrypoint=["sh","-c",replace(coder_agent.main.init_script,"/localhost|127\\.0\\.0\\.1/","host.docker.internal")]env=["CODER_AGENT_TOKEN=${coder_agent.main.token}","PROJECT_DIRECTORY=${one(module.git-clone).repo_dir}","JETBRAINS_IDE_ID=${try(module.jetbrains_gateway["jetbrains_primary"].identifier,"NONE")}","JETBRAINS_IDE_NAME=${try(module.jetbrains_gateway["jetbrains_primary"].display_name,"NONE")}","JETBRAINS_IDE_VERSION=${try(module.jetbrains_gateway["jetbrains_primary"].version,"NONE")}", ]host {host="host.docker.internal"ip="host-gateway" }host {host="coder.example.com"ip="host-gateway" }volumes {container_path="/home/coder/"volume_name=docker_volume.home_volume.nameread_only=false }volumes {container_path=local.root_dirvolume_name=docker_volume.workspace_volume.nameread_only=false }# Use a dynamic block for labels, consistent with this provider's syntax.dynamic"labels" {for_each=merge(local.common_docker_labels, {"coder.workspace_name"= data.coder_workspace.me.name })content {label=labels.keyvalue=labels.value } }}resource"coder_metadata""container_info" {count=data.coder_workspace.me.start_countresource_id=docker_container.workspace[count.index].id# Dynamically add metadata for any enabled JetBrains IDEsdynamic"item" {for_each=module.jetbrains_gatewaycontent {key=item.value.display_namevalue=item.value.version } }dynamic"item" {for_each=module.jetbrains_gatewaycontent {key=item.value.identifiervalue=item.value.build_number } }dynamic"item" {for_each=module.dotfilescontent {key=length(module.dotfiles)>1?"Dotfiles Repo [${item.key}]":"Dotfiles Repo"value=item.value.dotfiles_uri } }item {key="Repository"value="${local.repo_owner_name}/${local.folder_name}" }}# Create a Coder app for the websiteresource"coder_app""website" {count=length(module.git-clone)>0?1:0agent_id=coder_agent.main.idorder=2slug="website"external=truedisplay_name=one(module.git-clone).folder_nameurl=one(module.git-clone).web_urlicon=one(module.git-clone).git_provider!=""?"/icon/${one(module.git-clone).git_provider}.svg":"/icon/git.svg"}resource"docker_container""copyparty" {count=data.coder_workspace.me.start_countimage="ghcr.io/9001/copyparty-im"name="coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}-copyparty"hostname="${data.coder_workspace.me.name}-copyparty"# This tells the CopyParty *application* which paths inside the container to serve.# We map the internal /home/coder/ path to the URL /home, and the repo to /repo.command=["-v","/home/coder/:/home:r",# Share home directory (read-only)"-v","${one(module.git-clone).repo_dir}:/repo:rw",# Share project directory (read-write) ]# Expose the port to the internal Docker network so the coder_app can reach it.ports {internal=3923 }host {host="host.docker.internal"ip="host-gateway" }volumes {container_path="/home/coder/"volume_name=docker_volume.home_volume.nameread_only=false }volumes {container_path=local.root_dirvolume_name=docker_volume.workspace_volume.nameread_only=false }# Use a dynamic block for labels, consistent with this provider's syntax.dynamic"labels" {for_each=merge(local.common_docker_labels, {"coder.workspace_name"= data.coder_workspace.me.name })content {label=labels.keyvalue=labels.value } }}resource"coder_app""copyparty" {count=data.coder_workspace.me.start_countagent_id=coder_agent.main.idorder=3slug="files"display_name="Copy Party"icon="/icon/folder.svg"# URL points to the container's internal hostname and exposed port.url="http://host.docker.internal:${docker_container.copyparty[count.index].ports[0].external}"subdomain=trueopen_in="slim-window"healthcheck {url="tcp://host.docker.internal:${docker_container.copyparty[count.index].ports[0].external}"interval=5threshold=3 }}#================================================================## MODULES - https://registry.coder.com/modules#================================================================# Consolidated module for all JetBrains Gatewaysmodule"jetbrains_gateway" {for_each={forkey,paramindata.coder_parameter.ide_toggle:key=>paramifcontains(key,"jetbrains")&¶m.value==true }source="registry.coder.com/modules/jetbrains-gateway/coder"version="~> 1.0.0"agent_id=coder_agent.main.idfolder=one(module.git-clone).repo_dirdefault="GO"latest=true}module"dotfiles" {count=data.coder_workspace.me.start_countsource="registry.coder.com/modules/dotfiles/coder"version="~> 1.0.0"agent_id=coder_agent.main.iddefault_dotfiles_uri="https://github.com/djarbz/coder-dotfiles.git"}module"coder-login" {count=data.coder_workspace.me.start_countsource="registry.coder.com/modules/coder-login/coder"version="~> 1.0.0"agent_id=coder_agent.main.id}module"code-server" {count=data.coder_parameter.ide_toggle["coder"].value?1:0source="registry.coder.com/modules/code-server/coder"version="~> 1.0.0"agent_id=coder_agent.main.idfolder=one(module.git-clone).repo_diruse_cached_extensions=trueextensions=["timonwong.shellcheck","hangxingliu.vscode-systemd-support","streetsidesoftware.code-spell-checker","usernamehw.errorlens","donjayamanne.githistory","nonspicyburrito.hoverlens","christian-kohler.path-intellisense","esbenp.prettier-vscode","gruntfuggly.todo-tree","edwinhuish.better-comments-next","foxundermoon.shell-format","github.vscode-github-actions", ]}module"git-config" {count=data.coder_workspace.me.start_countsource="registry.coder.com/modules/git-config/coder"version="~> 1.0.0"agent_id=coder_agent.main.id}module"git-commit-signing" {count=data.coder_workspace.me.start_countsource="registry.coder.com/modules/git-commit-signing/coder"version="~> 1.0.0"agent_id=coder_agent.main.id}module"git-clone" {count=data.coder_workspace.me.start_countsource="registry.coder.com/modules/git-clone/coder"version="~> 1.0.0"agent_id=coder_agent.main.idurl=data.coder_parameter.repo.valuebase_dir=local.root_dirgit_providers={"https://github.com/"= {"provider":"github" },"git@github.com:"= {"provider":"github" },"https://gitlab.com/"= {"provider":"gitlab" },"git@gitlab.com:"= {"provider":"gitlab" }, }} |
BetaWas this translation helpful?Give feedback.
All reactions
Replies: 1 comment
-
Looks like the agent is trying to connect over a tailnet on localhost?
|
BetaWas this translation helpful?Give feedback.