--- title: "🚧 Deliberate limits" description: "What this Coder deployment does not enable and what each omission costs: no wildcard access URL, no Authelia gate, no open signup, no external provisioner, and a hard memory pressure gate." source: "verified deployment on the loca operator host, 2026-08-19" reviewed: 2026-08-20 --- # 🚧 Deliberate limits Every entry here is a choice, not an oversight. Each one states the cost, the true blocker, and what it would take to lift it. ## 🌐 No wildcard access URL `CODER_WILDCARD_ACCESS_URL` is unset. - the true blocker is TLS issuance, not DNS - nested names under the host wildcard do resolve; `foo.code.loca.zone` and even `deep.nested.code.loca.zone` answer on this host, as does any nonexistent label under `loca.zone` - each certbot lineage covers only the SANs it was issued for; the `code.loca.zone` lineage covers `code.loca.zone` and `wiki.code.loca.zone` and nothing else - a `*.code.loca.zone` certificate requires DNS-01 validation with DNS-provider API credentials, which are not configured on this host; HTTP-01 via the `/var/www/html` webroot cannot issue wildcards - upstream's own nginx walkthrough confirms the shape: a wildcard certificate is obtained with a DNS plugin and a provider API token, not with webroot validation - lost features, exactly: - dashboard port forwarding, including the Open Ports panel and port sharing URLs - `coder_app` resources with `subdomain = true`; upstream states such apps are not accessible when the administrator has not set up wildcards - web apps that require an absolute root path, notably Vite, the React dev server, the Next.js dev server, JupyterLab and RStudio per upstream - kept features, exactly: - path-based `coder_app` resources at `/@/./apps//` - the dashboard and the web terminal - `coder port-forward` from the CLI - SSH port forwarding, including `coder ssh -R` and anything set up by `coder config-ssh` - Coder Desktop and the IDE remotes (VS Code extension, JetBrains Gateway) ### Runbook: enabling `*.code.loca.zone` (blocked, do not start until both prerequisites exist) Preflight re-confirmed 2026-08-20: `sudo -n certbot plugins` lists exactly `nginx`, `standalone`, `webroot`, no `dns-*` plugin is installed, and `/etc/letsencrypt/` holds no DNS credential file. So this runbook cannot be executed today, and nothing below should be attempted piecemeal — a half-applied wildcard leaves nginx serving a name its certificate does not cover. Two named prerequisites, both operator decisions: 1. a DNS-provider API credential file for the `loca.zone` zone, mode 600 root-owned, e.g. `/etc/letsencrypt/dns-.ini`. The provider is genuinely unknown from this host: `loca.zone` nameservers point at `178.18.250.170`, self-hosted, so the credential shape cannot be guessed 2. the matching plugin package `python3-certbot-dns-`, which is a package install and therefore ask-first Then, in order: ```bash # 1. expand the existing lineage rather than creating a second one sudo certbot certonly \ --dns- \ --dns--credentials /etc/letsencrypt/dns-.ini \ --cert-name code.loca.zone --expand \ -d code.loca.zone -d wiki.code.loca.zone -d '*.code.loca.zone' sudo certbot certificates # confirm all three SANs on one lineage # 2. nginx: add the wildcard to both blocks that own the app name # /etc/nginx/sites-available/code.loca.zone # line 3 (listen 443 ssl) -> server_name code.loca.zone *.code.loca.zone; # line 56 (listen 80) -> server_name code.loca.zone *.code.loca.zone; # leave the two wiki.code.loca.zone blocks alone: a wildcard on the app # block would otherwise swallow the wiki host, and the wiki must stay static sudo nginx -t && sudo systemctl reload nginx # 3. Coder: add to the coder service environment in docker-compose.yml # CODER_WILDCARD_ACCESS_URL: "*.code.loca.zone" cd /home/loca/dev/coder && sudo -n docker compose config >/dev/null \ && sudo -n docker compose up -d --force-recreate coder curl -sf http://127.0.0.1:52226/healthz ``` Verified against the running v2.35.3 binary, not assumed: `coder server --help` documents `--wildcard-access-url, $CODER_WILDCARD_ACCESS_URL` taking the form `"*.example.com"`, and `--disable-path-apps, $CODER_DISABLE_PATH_APPS` whose own help text says it is "recommended for security purposes if a `--wildcard-access-url` is configured". So the follow-up hardening step is: - set `CODER_DISABLE_PATH_APPS: "true"` only after subdomain apps are confirmed working, because it removes the path-based routes this deployment currently depends on, including the `code-server` app on `ws1` - note the RFC 1035 label limit: app, agent, workspace and username together must stay under 63 characters in one hostname label - renewal: the lineage keeps its `--dns-` authenticator in `/etc/letsencrypt/renewal/code.loca.zone.conf`, so unattended renewal needs the credential file to stay in place; the existing nginx reload hook still applies ## 🔓 No Authelia gate - cost: the dashboard is publicly reachable and Coder's own login page is the only thing between the internet and the deployment; there is no second factor at the proxy - why the cost is accepted: an `auth_request` gate would 302 every cookie-less request, which is exactly what the `coder` CLI, the workspace agents and DERP relay traffic send. A browser-only gate is impossible because the SPA and the agents share `/api/v2` - compensating controls: Coder's own session handling, no open signup, a pinned server image, and a single admin account - since 2026-08-20 identity is nonetheless unified: Coder consumes Authelia over OIDC at the application layer, with password login kept as break-glass, while the proxy stays ungated — full argument in [[operations/auth-model]] ## 🚫 No open signup - cost: onboarding another person is a manual admin action; there is no self-service registration - why: `POST /api/v2/users` requires authentication, so only an admin can mint accounts, and `POST /api/v2/users/first` exists solely for the initial Owner - consequence to respect: do not create accounts for other people on this deployment. Template Admin is root-equivalent here because of the docker socket, so every additional privileged account widens host exposure - if multi-user access is ever wanted, do it through OIDC with Authelia as the provider rather than by handing out passwords ## 🏗️ No external provisioner - cost: template builds run inside the `coder` container, so a heavy build competes with the control plane for the same 8 GB ceiling, and a build failure shows up in the server log rather than in a separate daemon's log - why: an external provisioner needs its own credentialed daemon and a scoped provisioner key; for a single-admin docker-only deployment that is more moving parts than it removes - security note carried over from upstream: provisioner daemons hold the credentials that can create compute. Here that credential is the bind-mounted `/var/run/docker.sock`, which makes the server root-equivalent on the host. Containment list: [[operations/workspaces]] ## 🧠 Memory and swap pressure gate The measured state of this host on 2026-08-19, before Coder existed: - `free -m` showed 36447 of 60278 MB used - swap was 15926 of 16383 MB consumed, that is effectively exhausted - roughly ten co-tenant stacks were already running, including zulip, mattermost and eight postgres instances Containment already in place: - `mem_limit: 8g` on the `coder` container, so the control plane plus its in-process provisioner cannot exceed 8 GB - `mem_limit: 2g` on the `coder-database` container - postgres publishes no host port, so nothing outside the compose network can drive load into it The rules, in order: - record `free -m` before bring-up and again after the first workspace build, so the real cost of one workspace is known rather than estimated - do not create additional workspaces if available memory drops below about 8 GB - workspace containers are siblings on the host daemon and are not covered by the compose `mem_limit` values, so give every template an explicit resource ceiling - if swap is already exhausted, stop and free memory elsewhere before building anything; a build that lands on an exhausted swap will thrash the co-tenant stacks, not just this one ## 📚 Sources - https://coder.com/docs/admin/setup - https://coder.com/docs/admin/networking/wildcard-access-url - https://coder.com/docs/admin/networking/port-forwarding - https://coder.com/docs/tutorials/reverse-proxy-nginx - https://coder.com/docs/tutorials/best-practices/security-best-practices - https://coder.com/docs/reference/api/users - https://registry.terraform.io/providers/coder/coder/latest/docs/resources/app