diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml new file mode 100644 index 0000000..8e6bd26 --- /dev/null +++ b/.github/workflows/docs-check.yml @@ -0,0 +1,66 @@ +name: Check docs + +# Checks the Zensical docs site in docs/content, the same way ddev/ddev checks +# its docs. Read the Docs builds the PR preview and publishes +# https://docs.coder.ddev.com/ from main; this workflow only checks. + +on: + push: + branches: [main] + pull_request: + paths: + - "docs/**" + - "mkdocs.yml" + - ".readthedocs.yaml" + - ".markdownlint.jsonc" + - ".linkspector.yml" + - "scripts/check-doc-params.sh" + - "drupal-core/template.tf" + - "drupal-contrib/template.tf" + - "freeform/template.tf" + - "modules/**" + - ".github/workflows/docs-check.yml" + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + checks: write + pull-requests: read + +jobs: + docs-check: + name: Docs check (build, markdownlint, links, deep-link parameters) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - uses: actions/setup-python@v6 + with: + python-version: "3.x" + + - name: Build with Zensical (strict) + run: | + pip install -r docs/requirements.txt + make zensical + + - name: Run markdownlint + run: | + npm install -g markdownlint-cli + make markdownlint + + - name: Check deep-link parameters + run: make check-doc-params + + - name: Run linkspector to check external links + uses: umbrelladocs/action-linkspector@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + reporter: github-check + fail_on_error: true + # Check links only in added lines for PRs, but check everything otherwise + filter_mode: ${{ github.event_name == 'pull_request' && 'added' || 'nofilter' }} + config_file: ".linkspector.yml" diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index 70e55da..ffdf6bc 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -1,8 +1,10 @@ name: Deploy Docs to GitHub Pages -# Builds and deploys /docs to the root of the gh-pages branch on every push -# to main that touches the docs directory. PR previews (in /pr-preview/) are -# preserved across production deployments. +# Builds and deploys the start.coder.ddev.com landing pages in /docs to the root +# of the gh-pages branch on every push to main that touches them. The user docs +# in /docs/content are a separate Zensical site published by Read the Docs to +# https://docs.coder.ddev.com and are excluded from this Jekyll build. +# PR previews (in /pr-preview/) are preserved across production deployments. # # GitHub Pages must be configured to serve from: # Branch: gh-pages / (root) @@ -10,7 +12,7 @@ name: Deploy Docs to GitHub Pages on: push: branches: [main] - paths: ['docs/**'] + paths: ['docs/**', '!docs/content/**'] workflow_dispatch: permissions: diff --git a/.gitignore b/.gitignore index 8d9dea7..7d343c8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ composer.json.tmp **/.claude/settings.local.json CLAUDE.local.md .claude/agent-memory-local/ + +# Zensical build output and cache (make zensical) +site/ +.cache/ diff --git a/.linkspector.yml b/.linkspector.yml new file mode 100644 index 0000000..e8bcee7 --- /dev/null +++ b/.linkspector.yml @@ -0,0 +1,30 @@ +dirs: + - docs/content +# Message templates for the coder-ddev-com GitHub org; they contain +# [PLACEHOLDER] URLs that operators fill in before sending +excludedDirs: + - docs/content/self-hosting/coder-ddev-com +ignorePatterns: + # Internal anchors are already checked by `zensical build --strict` + - pattern: ".md#" + # Behind GitHub sign-in or org membership, so linkspector can't load them + - pattern: "^https://coder.ddev.com" + - pattern: "^https://staging-coder.ddev.com" + - pattern: "^https://github.com/orgs/" + - pattern: "^https://github.com/settings/" + - pattern: "^https://gitlab.com/-/" + - pattern: "^https://www.drupal.org/user" + - pattern: "^https://claude.ai" + # Example hostnames used in docs + - pattern: "coder.example.com" + - pattern: "localhost" + - pattern: "127.0.0.1" + # Private to DDEV maintainers + - pattern: "^https://github.com/ddev/maintainer-info" + - pattern: "^https://monitor.ddev.com" + # Rate-limits automated requests + - pattern: "^https://robot.hetzner.com" +aliveStatusCodes: + - 200 + - 206 + - 301 diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 0000000..b8b04e2 --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,43 @@ +{ + // These rules mostly come from mkdocs rules + // https://github.com/mkdocs/mkdocs/blob/master/.markdownlintrc + // Using markdownlint from https://github.com/DavidAnson/markdownlint + // and https://github.com/igorshubovych/markdownlint-cli + // npm install --global markdownlint-cli + + // Enable all markdownlint rules + "default": true, + + // Fine with long lines, editor can wrap + "line-length": false, + + // Unfortunately, mkdocs messes up nearly everything if you insist on this; + // the problem is that it's concatenating files, so you lose important levels + // of sidebar headings if every file starts with H1. + "first-line-h1": false, + + "MD004": { "style": "consistent" }, + + // Set Ordered list item prefix to "ordered" (use 1. 2. 3. not 1. 1. 1.) + "MD029": { "style": "ordered" }, + + // Set list indent level to 4 which Python-Markdown requires + "MD007": { "indent": 4 }, + + // Embedded html allowed; often used for named anchors with mkdocs/readthedocs + "no-inline-html": false, + + // Fenced code blocks do not need language spec + "MD040": false, + + // Exclude code block style + "MD046": false, + + // Repeated headings such as "Verify" or "Troubleshooting" under different + // sections are fine; only flag duplicates among siblings + "MD024": { "siblings_only": true }, + + // Table column alignment style - disabled as it creates maintenance burden + // without improving rendered output + "MD060": false +} diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..c227fd5 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,23 @@ +# .readthedocs.yaml +# Read the Docs configuration file, modeled on ddev/ddev's. +# Publishes the Zensical site in docs/content to https://docs.coder.ddev.com/ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3.14" + jobs: + install: + - pip install -r docs/requirements.txt + - 'sed -i "s|site_url:.*|site_url: $READTHEDOCS_CANONICAL_URL|" mkdocs.yml' + - grep site_url mkdocs.yml + build: + html: + - zensical build --clean --strict + post_build: + - mkdir -p $READTHEDOCS_OUTPUT/html/ + - cp -rv site/* $READTHEDOCS_OUTPUT/html/ diff --git a/AGENTS.md b/AGENTS.md index 5d62a57..a69ed49 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,7 +29,22 @@ This project provides a Coder v2+ template for DDEV-based development environmen - **VS Code for Web** - Browser-based IDE via official Coder module - **Ubuntu 24.04** - Base container OS -**Note:** User-facing documentation lives in `/docs/`. This file focuses on developer/contributor guidance. +**Note:** User-facing documentation lives in `docs/content/` and is published to https://docs.coder.ddev.com. This file focuses on developer/contributor guidance. + +## Documentation + +Two separate sites are built from `docs/`: + +| Site | Source | Built with | Published by | +| ---- | ------ | ---------- | ------------ | +| https://docs.coder.ddev.com (user docs) | `docs/content/**/*.md`, config in root `mkdocs.yml` | [Zensical](https://zensical.org), set up the same way as ddev/ddev's docs | Read the Docs (`.readthedocs.yaml`), including PR previews | +| https://start.coder.ddev.com (landing pages, deep-link builders) | `docs/*.html`, `docs/*.js`, `docs/coder-ddev-start.css` | Jekyll (`docs/_config.yml` excludes `content/`) | GitHub Pages (`docs-deploy.yml`, previews via `docs-preview.yml`) | + +- **Audience:** the user docs are written for people using the hosted service at coder.ddev.com. Self-hosting material goes under `docs/content/self-hosting/`. +- **Add a page:** create the Markdown file under `docs/content/` and add it to `nav:` in `mkdocs.yml`; links between pages are relative `.md` links. +- **Before pushing docs changes:** `make docs-check` (strict Zensical build, markdownlint with `.markdownlint.jsonc`, and `scripts/check-doc-params.sh`). Needs `pip install -r docs/requirements.txt` and `npm install -g markdownlint-cli`. `make zensical-serve` previews at http://localhost:8000. CI runs the same checks plus linkspector in `.github/workflows/docs-check.yml`. +- **Moved or renamed a page?** Add a `redirect_maps` entry in `mkdocs.yml`. Old `start.coder.ddev.com` Markdown URLs are kept alive by the `redirect_to` stubs in `docs/user/`, `docs/admin/`, `docs/architecture/` and `docs/reference/`. +- **When a template's user-facing behavior changes** (parameters, app buttons, URLs, `ddev coder-setup`/`coder-routes`/`launch`), update the matching page in `docs/content/` in the same PR — especially `docs/content/freeform/create.md` for freeform parameters. ## Coder CLI Commands in Docs @@ -57,7 +72,7 @@ When writing or reviewing `coder` CLI commands in documentation, **always verify - **Never change an existing `coder_parameter`'s `type` in place — always give it a new `name`.** The `coder_parameter` data source validates the incoming value against the declared `type` *before* any of the template's own `locals` ever run, so a `try(tobool(...), false)`-style fallback in a `locals` block cannot rescue a stale value — the plan fails hard first, with an opaque `Error: Parameter value is not of type "bool"`. Any client still holding an old-typed value for that parameter name (a bookmarked workspace-creation deep link, a cached copy of a `docs/*.html` page, an already-open browser tab) will hit this on every future `terraform plan`, including the Coder UI's live dynamic-parameter preview during workspace creation. Renaming the parameter is the only fix — `terraform` code cannot intercept the provider's own type validation. Root-caused and fixed for `share_drupal_site` → `drupal_site_public` in #206 (`drupal-core`/`drupal-contrib`; both changed the parameter from a 3-way `owner`/`authenticated`/`public` string to a `bool` switch in #205, one PR earlier — the type change and the deep-link doc pages that still emitted the old string values shipped in the same PR and nothing caught the mismatch). - **`terraform test`'s `mock_provider "coder"` cannot catch the above class of bug.** The mock replaces the real `coder_parameter` data source entirely (including its type validation), so a run block asserting behavior for a stale/incompatible parameter value will pass locally and in CI even when the real provider would hard-fail. There is no terraform-test-layer way to close this gap; the only defense is the naming discipline above. -- **`docs/drupal-core.html`, `docs/drupal-issue.html`, and `docs/coder-workspace-name.js` build Coder workspace-creation deep links (`?param.=`) and are not covered by any CI check against the live `coder_parameter` definitions in `template.tf`.** Whenever a template's parameter names, types, or allowed values change, grep these docs files for the old name/values and update them in the same PR — nothing currently fails CI if they drift out of sync. +- **`docs/drupal-core.html`, `docs/drupal-issue.html`, and `docs/coder-workspace-name.js` build Coder workspace-creation deep links (`?param.=`).** `scripts/check-doc-params.sh` (`make check-doc-params`, run in `docs-check.yml`) fails if a `param.` used in `docs/` no longer exists as a `coder_parameter` in any template or shared module, which catches renames and removals. It does **not** check parameter types or allowed values, or that a link targets the template that defines the parameter — whenever a template's parameter types or allowed values change, grep these docs files for the old values and update them in the same PR. ## Template Architecture Overview diff --git a/Makefile b/Makefile index 5e99a98..c93d0c7 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,29 @@ test-templates: sync-shared ## Run Terraform mock unit tests for all templates ( done @echo "All template tests passed." +# --- Documentation (Zensical, same setup as ddev/ddev; published by Read the Docs) --- +# Install the docs toolchain with: pip install -r docs/requirements.txt +# and markdownlint with: npm install -g markdownlint-cli + +.PHONY: zensical +zensical: ## Build the docs site in docs/content with Zensical (strict, like Read the Docs) + zensical build --clean --strict + +.PHONY: zensical-serve +zensical-serve: ## Preview the docs site locally at http://localhost:8000 with live reload + zensical serve + +.PHONY: markdownlint +markdownlint: ## Lint the docs Markdown with markdownlint (config in .markdownlint.jsonc) + markdownlint --config .markdownlint.jsonc docs/content + +.PHONY: check-doc-params +check-doc-params: ## Check that deep-link param. values in the docs exist as coder_parameters + scripts/check-doc-params.sh + +.PHONY: docs-check +docs-check: zensical markdownlint check-doc-params ## Run all local docs checks + .PHONY: push-staging push-staging: ## Push all templates to staging-coder.ddev.com inactive (ACTIVATE=false); requires CODER_URL set to staging $(MAKE) push-all-templates ACTIVATE=false diff --git a/README.md b/README.md index c097d31..d10c8b5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Coder workspace template for DDEV-based development with Docker-in-Docker support, Node.js, and Git. +📚 **Documentation:** [docs.coder.ddev.com](https://docs.coder.ddev.com/) + **Get started (recommended paths):** - **Drupal.org issue or project** → [Drupal Issue Picker](https://start.coder.ddev.com/drupal-issue) (auto-detects core vs contrib and prefills sensible defaults) @@ -62,7 +64,7 @@ make help # See all available commands ### Version Management -The `VERSION` file in the root directory controls the image tag. The Makefile automatically copies it into each template directory before pushing, and `template.tf` reads it from there — no manual edits to `template.tf` are needed. +The `VERSION` file in the root directory controls the image tag. The Makefile passes it to every template as `--variable image_version=...` at push time, so no edits to `template.tf` are needed. **To release a new version:** 1. Update the `VERSION` file (e.g., `v0.7`) @@ -77,22 +79,16 @@ make build-and-push-no-cache && make push-all-templates # Clean build and deplo ## Documentation -**New to Coder?** -- 📘 [Getting Started Guide](./docs/user/getting-started.md) - Create your first workspace -- 📗 [Using Workspaces](./docs/user/using-workspaces.md) - Daily workflows and tips - -**Administrators:** -- 📕 [Operations Guide](./docs/admin/operations-guide.md) - Deploy and manage template -- 📙 [User Management](./docs/admin/user-management.md) - Users, roles, permissions -- 📔 [Troubleshooting](./docs/admin/troubleshooting.md) - Debug common issues +📚 **User documentation: [docs.coder.ddev.com](https://docs.coder.ddev.com/)**, built with [Zensical](https://zensical.org) from [`docs/content/`](./docs/content/) and published by Read the Docs, the same way as [docs.ddev.com](https://docs.ddev.com). -**DDEV Experts:** -- 🔍 [Comparison to Local DDEV](./docs/architecture/comparison-to-local.md) - Architecture, tradeoffs, migration +- [Getting started](https://docs.coder.ddev.com/getting-started/): access, sign-in, choosing a template +- [Freeform workspaces](https://docs.coder.ddev.com/freeform/): running your own DDEV projects +- [Drupal quickstart](https://docs.coder.ddev.com/drupal/quickstart/) +- [Self-hosting](https://docs.coder.ddev.com/self-hosting/overview/): server setup, operations, user management -**Developers/Contributors:** -- 🤖 [AGENTS.md](./AGENTS.md) - AI-assisted development guide +Preview the docs locally with `pip install -r docs/requirements.txt` and `make zensical-serve`. Developer and contributor guidance is in [AGENTS.md](./AGENTS.md). -📚 **[Full Documentation Index](./docs/README.md)** +The landing pages at [start.coder.ddev.com](https://start.coder.ddev.com) (`docs/*.html`) are a separate Jekyll site deployed to GitHub Pages. ## Template Structure @@ -205,7 +201,7 @@ coder create --template drupal-contrib \ - Find your workspace - Click on port **80** or **443** under "Apps" -**📖 [Full Getting Started Guide](./docs/user/getting-started.md)** +**📖 [Full Getting Started Guide](https://docs.coder.ddev.com/getting-started/)** ### For Administrators @@ -225,4 +221,4 @@ make build-and-push # Build + push image make deploy-freeform # Push freeform template (uses existing image) ``` -**📖 [Full Operations Guide](./docs/admin/operations-guide.md)** +**📖 [Full Operations Guide](https://docs.coder.ddev.com/self-hosting/operations-guide/)** diff --git a/docs/README.html b/docs/README.html new file mode 100644 index 0000000..993f289 --- /dev/null +++ b/docs/README.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/self-hosting/overview/ +--- diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 7555ff0..0000000 --- a/docs/README.md +++ /dev/null @@ -1,230 +0,0 @@ -# DDEV Coder Template Documentation - -Welcome to the DDEV Coder template documentation. This guide helps you deploy, manage, and use cloud-based DDEV development environments. - -## Quick Links - -- **[Project README](../README.md)** - Quick start and overview -- **[Developer Guide (AGENTS.md)](../AGENTS.md)** - For contributors and AI-assisted development -- **[Image Build Instructions](../image/README.md)** - Docker image details - -## Documentation by Audience - -### For Administrators - -System administrators and DevOps teams managing Coder infrastructure and the DDEV template. - -- **[Server Setup Guide](./admin/server-setup.md)** - Fresh server installation: Docker, Sysbox, Coder server, adding capacity -- **[Operations Guide](./admin/operations-guide.md)** - Template deployment, Docker image builds, version management, workspace lifecycle -- **[User Management Guide](./admin/user-management.md)** - User accounts, roles, permissions, SSH keys, API tokens, resource quotas -- **[Troubleshooting Guide](./admin/troubleshooting.md)** - Common issues, debugging tools, error messages, emergency recovery - -**New installation:** [Server Setup Guide](./admin/server-setup.md) -**Ongoing operations:** [Operations Guide](./admin/operations-guide.md) - -### For Users - -Developers and users creating and working with DDEV workspaces. - -- **[Drupal Core Quickstart](./user/quickstart.md)** - Get a Drupal core workspace running in minutes; issue fork support -- **[Getting Started Guide](./user/getting-started.md)** - First-time setup, creating your first workspace, basic verification -- **[Using Workspaces](./user/using-workspaces.md)** - Daily workflows, VS Code for Web, DDEV projects, Git, port forwarding - -**Drupal core contributors:** [Quickstart](./user/quickstart.md) -**New to Coder:** [Getting Started Guide](./user/getting-started.md) - -### For DDEV Experts - -For teams evaluating this template or users familiar with local DDEV. - -- **[Comparison to Local DDEV](./architecture/comparison-to-local.md)** - Architecture differences, feature parity, benefits, tradeoffs, migration - -**Start here:** [Comparison to Local DDEV](./architecture/comparison-to-local.md) - -## What is This? - -The DDEV Coder template provides cloud-based development environments with full DDEV support: - -- **Docker-in-Docker** - Each workspace has isolated Docker daemon (via Sysbox runtime) -- **DDEV pre-installed** - Ready to run PHP, Node.js, Python projects -- **VS Code for Web** - Browser-based IDE with full extension support -- **Persistent storage** - Home directory and Docker volumes preserved across sessions -- **Port forwarding** - Access DDEV projects via Coder's secure proxy - -### Key Technologies - -- **Coder v2+** - Open-source infrastructure for creating remote development environments -- **Sysbox** - Secure nested containers without privileged mode -- **DDEV** - Local development tool for PHP/Node/Python (supports 20+ project types) -- **Ubuntu 24.04** - Base container OS -- **Terraform** - Infrastructure as Code for template definition - -## Use Cases - -### Team Development - -- **Consistent environments** - Everyone uses the same versions, tools, configuration -- **Fast onboarding** - New developers get working environment in minutes -- **No local setup** - No Docker Desktop, no dependency conflicts - -### Remote Work - -- **Access anywhere** - Work from any device with a browser -- **Cloud resources** - Use powerful cloud machines for heavy workloads -- **Persistent state** - Stop/start workspaces without losing work - -### Education and Training - -- **Pre-configured environments** - Students don't need to install tools -- **Isolated workspaces** - Each student has separate environment -- **Easy reset** - Instructor can recreate clean environments - -## Architecture Overview - -``` -┌─────────────────────────────────────────┐ -│ Coder Server (Management Plane) │ -│ - User authentication │ -│ - Template management │ -│ - Workspace orchestration │ -└─────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────┐ -│ Coder Agent Node (Workspaces) │ -│ ┌─────────────────────────────────────┐ │ -│ │ Workspace Container (Sysbox) │ │ -│ │ ┌─────────────────────────────────┐ │ │ -│ │ │ Docker Daemon (inside) │ │ │ -│ │ │ ┌─────────────────────────────┐ │ │ │ -│ │ │ │ DDEV Containers │ │ │ │ -│ │ │ │ - Web (PHP/Node/Python) │ │ │ │ -│ │ │ │ - Database (MySQL/Postgres) │ │ │ │ -│ │ │ │ - Additional services │ │ │ │ -│ │ │ └─────────────────────────────┘ │ │ │ -│ │ └─────────────────────────────────┘ │ │ -│ │ /home/coder (persistent volume) │ │ -│ └─────────────────────────────────────┘ │ -└─────────────────────────────────────────┘ -``` - -**Key points:** -- Each workspace is an isolated container with its own Docker daemon -- DDEV runs inside the workspace using the nested Docker daemon -- Sysbox provides security without `--privileged` mode -- VS Code for Web connects directly to workspace via Coder agent - -## Feature Highlights - -### What's Included - -✅ **Docker and Docker Compose** - Full Docker CLI and daemon -✅ **DDEV** - Latest stable version with all features -✅ **Node.js LTS** - Version 24.x pre-installed -✅ **VS Code for Web** - Official Coder module with extension support -✅ **Git with SSH** - GitSSH integration for seamless cloning -✅ **System tools** - curl, wget, vim, build-essential, bash-completion -✅ **Passwordless sudo** - Full system access within workspace - -### What's NOT Included - -❌ **Local Docker Desktop** - Replaced by Docker-in-Docker -❌ **Local DDEV** - Runs in cloud workspace instead -❌ **Direct port binding** - Use Coder's port forwarding -❌ **Host network access** - Isolated workspace networking - -### Supported Project Types - -DDEV supports 20+ project types out of the box: - -- **PHP**: Drupal, WordPress, Laravel, Symfony, Magento, Typo3, Craft CMS, Backdrop -- **Node.js**: Any framework (Next.js, Express, Gatsby, etc.) -- **Python**: Django, Flask, any Python web app -- **Static sites**: HTML, Jekyll, Hugo -- **Generic**: Custom PHP, Go, Rust, and more - -## Documentation Conventions - -### Command Prompts - -```bash -# Commands run on your local machine -coder login https://coder.example.com - -# Commands run inside workspace (after 'coder ssh workspace') -ddev start -``` - -### File Paths - -- **Host paths**: `/coder-workspaces/-` -- **Workspace paths**: `/home/coder` (inside container) -- **Template paths**: `freeform/template.tf` (in this repository) - -### Variables - -- `` - Name of your workspace (e.g., `my-project`) -- `` - Username of workspace owner -- `` - Coder organization name -- `` - Docker image version (e.g., `v0.1`) - -## Getting Help - -### Community Resources - -- **GitHub Issues**: [Report bugs or request features](https://github.com/ddev/coder-ddev/issues) -- **DDEV Documentation**: [Official DDEV docs](https://docs.ddev.com/) -- **Coder Documentation**: [Official Coder docs](https://coder.com/docs) -- **Coder Discord**: [Community chat](https://discord.gg/coder) - -### Before Asking for Help - -1. Check the [Troubleshooting Guide](./admin/troubleshooting.md) -2. Search [existing GitHub issues](https://github.com/ddev/coder-ddev/issues) -3. Review [DDEV troubleshooting docs](https://docs.ddev.com/users/usage/troubleshooting/) - -### Reporting Issues - -Include: -- Workspace logs: `coder logs ` -- Template version: `cat VERSION` -- Coder version: `coder version` -- DDEV version: `coder ssh -- ddev version` -- Full error messages - -## Contributing - -This is an open-source project. Contributions welcome! - -- **Report bugs**: [GitHub Issues](https://github.com/ddev/coder-ddev/issues) -- **Contribute code**: Fork, branch, submit PR -- **Documentation**: Suggest improvements or add examples -- **AI-assisted development**: See [AGENTS.md](../AGENTS.md) for AI workflow - -## License - -See [LICENSE](../LICENSE) file for details. - -## Version - -Current version: See [VERSION](../VERSION) file. - -## Next Steps - -### For Administrators -1. Read [Server Setup Guide](./admin/server-setup.md) (new installations) -2. Read [Operations Guide](./admin/operations-guide.md) -3. Build Docker image and deploy template -4. Create test workspace - -### For Users -1. Read [Getting Started Guide](./user/getting-started.md) -2. Install Coder CLI -3. Create your first workspace -4. Start a DDEV project - -### For DDEV Experts -1. Read [Comparison to Local DDEV](./architecture/comparison-to-local.md) -2. Understand architecture differences -3. Evaluate for your team -4. Plan migration strategy diff --git a/docs/_config.yml b/docs/_config.yml index fc84114..37e985a 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,2 +1,11 @@ title: "DDEV Coder Workspaces" description: "Cloud-hosted development environments powered by DDEV" +# This Jekyll site is only the landing pages at https://start.coder.ddev.com +# (index, drupal-issue, drupal-core). The user documentation in content/ is a +# Zensical site published by Read the Docs to https://docs.coder.ddev.com +# (see mkdocs.yml and .readthedocs.yaml at the repo root). +exclude: + - content + - requirements.txt +plugins: + - jekyll-redirect-from diff --git a/docs/admin/operations-guide.html b/docs/admin/operations-guide.html new file mode 100644 index 0000000..545bb5b --- /dev/null +++ b/docs/admin/operations-guide.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/self-hosting/operations-guide/ +--- diff --git a/docs/admin/server-setup.html b/docs/admin/server-setup.html new file mode 100644 index 0000000..f70aa96 --- /dev/null +++ b/docs/admin/server-setup.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/self-hosting/server-setup/ +--- diff --git a/docs/admin/troubleshooting.html b/docs/admin/troubleshooting.html new file mode 100644 index 0000000..e4db712 --- /dev/null +++ b/docs/admin/troubleshooting.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/self-hosting/troubleshooting/ +--- diff --git a/docs/admin/user-management.html b/docs/admin/user-management.html new file mode 100644 index 0000000..41b6584 --- /dev/null +++ b/docs/admin/user-management.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/self-hosting/user-management/ +--- diff --git a/docs/architecture/comparison-to-local.html b/docs/architecture/comparison-to-local.html new file mode 100644 index 0000000..0724854 --- /dev/null +++ b/docs/architecture/comparison-to-local.html @@ -0,0 +1,3 @@ +--- +redirect_to: https://docs.coder.ddev.com/reference/comparison-to-local/ +--- diff --git a/docs/coder-ddev-start.css b/docs/coder-ddev-start.css index 52ea608..0bd29dc 100644 --- a/docs/coder-ddev-start.css +++ b/docs/coder-ddev-start.css @@ -1,6 +1,7 @@ /** * Shared design tokens + components for start.coder.ddev.com - * Used on static HTML landing pages and Jekyll docs markdown pages. + * Used on the static HTML landing pages. (The user docs at docs.coder.ddev.com + * are a separate Zensical site with its own theme.) * See /components.html for example usage. * See DDEV brand guide https://docs.ddev.com/en/stable/developers/brand-guide/ * for primary color definitions. @@ -1509,3 +1510,63 @@ pre code { line-height: 1.35; max-width: 100%; } + +/* Top bar on the landing page: puts the documentation link first */ +.cds-topbar { + position: absolute; + top: 0; + left: 0; + right: 0; + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + flex-wrap: wrap; + padding: 1rem 1.5rem; + border-bottom: 1px solid var(--border-subtle); + text-align: left; +} + +.cds-topbar__brand { + color: var(--text); + font-weight: 700; + text-decoration: none; +} + +.cds-topbar__brand:hover { + color: var(--link-hover); +} + +.cds-topbar__links { + display: flex; + align-items: center; + gap: 1.25rem; +} + +.cds-topbar__docs { + padding: 0.5rem 1rem; +} + +/* The hero is vertically centered; keep its content clear of the top bar */ +.cds-hero { + padding-top: 5.5rem; +} + +.cds-page-header__docs { + margin-left: auto; +} + +@media (max-width: 560px) { + .cds-topbar { + padding: 0.75rem 1rem; + } + + .cds-topbar__brand { + display: none; + } + + .cds-topbar__links { + width: 100%; + justify-content: space-between; + } +} diff --git a/docs/content/assets/favicon.svg b/docs/content/assets/favicon.svg new file mode 100644 index 0000000..f061db9 --- /dev/null +++ b/docs/content/assets/favicon.svg @@ -0,0 +1 @@ + diff --git a/docs/user/quickstart.md b/docs/content/drupal/quickstart.md similarity index 71% rename from docs/user/quickstart.md rename to docs/content/drupal/quickstart.md index f54fc78..2889d66 100644 --- a/docs/user/quickstart.md +++ b/docs/content/drupal/quickstart.md @@ -14,26 +14,25 @@ Go to **[coder.ddev.com](https://coder.ddev.com)** and sign in with GitHub. You Pick one of the following two guided forms to either load a clean Drupal install, or work on an issue or contrib project. -
- - -
-

Vanilla Drupal Core

-

Launch into Drupal core on a mainline 10.x, 11.x, or 12.x branch (no contrib modules or issue fork) using ddev-drupal-dev conventional project structure.

- -
-
+
+ +- **Guided Drupal Issue picker** (recommended) + + --- + + Get started from an issue fork or contrib project using [`ddev-drupal-contrib`](https://github.com/ddev/ddev-drupal-contrib) (or [`ddev-drupal-dev`](https://github.com/amateescu/ddev-drupal-dev) for core issues). + + [Drupal issue picker](https://start.coder.ddev.com/drupal-issue){ .md-button .md-button--primary } + +- **Vanilla Drupal Core** -
+ --- + + Launch into Drupal core on a mainline 10.x, 11.x, or 12.x branch (no contrib modules or issue fork) using the [`ddev-drupal-dev`](https://github.com/amateescu/ddev-drupal-dev) conventional project structure. + + [Drupal core picker](https://start.coder.ddev.com/drupal-core){ .md-button } + +
On the form, select the appropriate Drupal version and install profile, then launch your workspace in Coder. @@ -55,7 +54,6 @@ Admin credentials: `admin` / `admin` (Please modify if site is shared publi ## Code layout - ### Drupal core development ``` @@ -115,7 +113,7 @@ ddev ssh ## Working on a Drupal issue -On the [Guided Drupal Issue Picker](/drupal-issue), paste a drupal.org issue URL, issue number, or project URL — it auto-detects whether the issue is for Drupal core or a contrib module/theme, fetches the available branches, and opens a pre-configured workspace with the issue branch already checked out. Entering a project URL (e.g. `drupal.org/project/token`) or bare machine name launches a plain contrib dev workspace without a specific issue. +On the [Guided Drupal Issue Picker](https://start.coder.ddev.com/drupal-issue), paste a drupal.org issue URL, issue number, or project URL — it auto-detects whether the issue is for Drupal core or a contrib module/theme, fetches the available branches, and opens a pre-configured workspace with the issue branch already checked out. Entering a project URL (e.g. `drupal.org/project/token`) or bare machine name launches a plain contrib dev workspace without a specific issue. When working on an issue, the workspace surfaces issue info in several places: @@ -181,4 +179,4 @@ tail -50 /tmp/drupal-setup.log ddev describe ``` -See also: [full getting-started guide](getting-started.md) · [DDEV docs](https://docs.ddev.com/) · [Drupal core contribution guide](https://www.drupal.org/contribute/development) · [ddev-drupal-dev add-on](https://github.com/amateescu/ddev-drupal-dev) +See also: [full getting-started guide](../getting-started/first-workspace.md) · [DDEV docs](https://docs.ddev.com/) · [Drupal core contribution guide](https://www.drupal.org/contribute/development) · [ddev-drupal-dev add-on](https://github.com/amateescu/ddev-drupal-dev) diff --git a/docs/content/freeform/create.md b/docs/content/freeform/create.md new file mode 100644 index 0000000..5a99f89 --- /dev/null +++ b/docs/content/freeform/create.md @@ -0,0 +1,62 @@ +# Creating a Freeform Workspace + +## From the web + +1. Open [the freeform template](https://coder.ddev.com/templates/coder/freeform/workspace?mode=manual). +2. Give the workspace a **name**. Use lowercase letters, digits and hyphens, for example `client-site`. The name appears in all of the workspace's URLs. +3. Fill in the settings described below, or leave the defaults. +4. Click **Create workspace**. The workspace is usually ready in about a minute; you can watch the startup log on the workspace page. + +## Settings + +You can change every setting below later. On the workspace page, open **Settings → Parameters**, change the value, then restart the workspace. Changes take effect on the next start. + +### DDEV project names + +A comma-separated list of the DDEV projects you plan to run, for example `shop,blog`. For each name, the workspace gets: + +- an app button for the site, labeled with the project name, +- a **Mailpit (name)** button for captured email, +- an **xhgui (name)** button for profiling. + +Leave it empty for a single project with the same name as the workspace. + +!!! warning "Names must match exactly" + The name you list here must be exactly the name of the DDEV project (`name:` in `.ddev/config.yaml`, set with `ddev config --project-name=...`). Use lowercase letters, digits and hyphens. If a project isn't listed, its site has no app button and no working URL. `ddev coder-setup` warns you when this happens. + +### Public Sharing + +Off by default, so only you can open your sites. Turn it on to let anyone with the link open every listed project's site, without signing in. Mailpit and xhgui always stay private. See [Sharing your site](sharing.md). + +### VS Code Extensions + +Choose which extensions VS Code for Web installs. You can also install more extensions from the Extensions view at any time; they stay installed across restarts. + +### Enable Claude Code remote control + +Off by default. Turn it on to control Claude Code running in this workspace from [claude.ai/code](https://claude.ai/code) or the Claude mobile app. **Claude Code: skip permission prompts** passes `--dangerously-skip-permissions`. See [Claude Code](../workspaces/ai-tools.md#claude-code-remote-control). + +### Run a Claude Code self-hosted runner + +Off by default. Turn it on to have this workspace run sessions you start on claude.ai/code in a self-hosted environment. **Claude Code runner: concurrent sessions** sets how many run at once (1 to 4). This can't be combined with remote control, and the workspace should be used only for the runner. See [Claude Code](../workspaces/ai-tools.md#claude-code-self-hosted-runner). + +## From the command line + +With the [Coder CLI](https://coder.com/docs/install/cli) logged in to coder.ddev.com: + +```bash +coder create --template freeform my-workspace +``` + +The CLI asks for each setting. Because a list of project names contains commas, put it in a file instead of using `--parameter`, which splits values on commas: + +```bash +cat > params.yaml <<'YAML' +project_names: "shop,blog" +YAML +coder create --template freeform my-workspace --rich-parameter-file params.yaml --yes +``` + +## Resources + +Each workspace gets the CPU, memory and disk that coder.ddev.com allocates to every workspace. You don't choose them when creating it. If you need more, [open an issue](https://github.com/ddev/coder-ddev/issues) to discuss your use case. diff --git a/docs/content/freeform/first-project.md b/docs/content/freeform/first-project.md new file mode 100644 index 0000000..0d64210 --- /dev/null +++ b/docs/content/freeform/first-project.md @@ -0,0 +1,86 @@ +# Your First Freeform Project + +This walkthrough takes you from an empty workspace to a running site. It assumes a workspace named `my-site` created with the default settings, so its one registered project name is also `my-site`. + +## 1. Open a terminal + +On the workspace page, click **VS Code**. When it opens, choose **Terminal → New Terminal** from the menu (☰). VS Code opens in `~/my-site`, a directory named after the workspace; it may not exist yet, in which case VS Code opens your home directory. + +You can also use SSH from your computer. See [Editors, SSH and files](../workspaces/editors-and-ssh.md). + +## 2. Get your code + +=== "Clone an existing project" + + Your workspace already has an SSH key that Git uses. Add it to your Git host once (see [Git and SSH keys](../workspaces/editors-and-ssh.md#git-and-ssh-keys)), then: + + ```bash + git clone git@github.com:your-org/your-project.git ~/my-site + cd ~/my-site + ``` + +=== "Start a new project" + + ```bash + mkdir ~/my-site && cd ~/my-site + ``` + + Then follow one of the [project recipes](recipes.md) for your framework. + +## 3. Configure DDEV + +If the project already has a `.ddev/` directory, make sure its name matches the registered project name: + +```bash +ddev config --project-name=my-site +``` + +For a project without DDEV configuration, pick a type and docroot (see the [DDEV CMS quickstarts](https://docs.ddev.com/en/stable/users/quickstart/)): + +```bash +ddev config --project-name=my-site --project-type=php --docroot=public +``` + +## 4. Connect the project to the workspace + +```bash +ddev coder-setup +``` + +You only need to do this once per project. It adds a small DDEV hook (`.ddev/config.coder.yaml`) that writes the workspace's routing rules after every `ddev start`, and adds that file to your global Git ignore list so it never ends up in your repository. + +## 5. Start the project + +```bash +ddev start +``` + +Now open the site in any of these ways: + +- Click the **my-site** app button on the workspace page. +- Run `ddev launch` in the terminal. It prints the URL (in VS Code, Ctrl-click or Cmd-click it). +- Run `ddev describe` to see the URLs of the site, Mailpit and any other services. + +The URL looks like `https://my-site--my-site--your-username.coder.ddev.com`. + +!!! note "Use the workspace URLs, not `*.ddev.site`" + URLs like `https://my-site.ddev.site` only work on the machine DDEV runs on. In a workspace, always use the `coder.ddev.com` URLs above. `ddev describe` and `ddev launch` already show the right ones once `ddev coder-setup` has run. + +## 6. Install dependencies and import data + +Use DDEV's tools exactly as you would locally: + +```bash +ddev composer install +ddev npm install +ddev import-db --file=dump.sql.gz +ddev import-files --source=files.tar.gz +``` + +To get a database dump or files into the workspace, drag them into the VS Code file explorer, or use `scp` from your computer. See [Editors, SSH and files](../workspaces/editors-and-ssh.md#copying-files). + +## Next steps + +- Add a second project: [Multiple projects](multiple-projects.md). +- Have the project start automatically when the workspace starts: [Running things on workspace start](../workspaces/lifecycle.md#running-things-automatically-on-start). +- Show it to someone: [Sharing your site](sharing.md). diff --git a/docs/content/freeform/index.md b/docs/content/freeform/index.md new file mode 100644 index 0000000..edc2c68 --- /dev/null +++ b/docs/content/freeform/index.md @@ -0,0 +1,35 @@ +# Freeform Workspaces + +The **freeform** template is a general-purpose DDEV workspace. It doesn't set up any particular project for you. You bring your own code, or create a new project, and run it with DDEV exactly as you would on your own computer. Anything DDEV supports works: WordPress, Laravel, Symfony, Drupal sites, TYPO3, Craft CMS, Magento, Node.js, Python, static sites and more. + +[Create a freeform workspace](https://coder.ddev.com/templates/coder/freeform/workspace?mode=manual){ .md-button .md-button--primary } + +## What makes freeform different + +- **Several projects in one workspace.** List the DDEV project names you plan to use, and each one gets its own URL and its own app buttons. DDEV's router sends each request to the right project. See [Multiple projects](multiple-projects.md). +- **Real HTTPS URLs for every project.** Each site is served at `https://----.coder.ddev.com`. Mailpit and xhgui get their own URLs too. +- **One setup command per project.** `ddev coder-setup` hooks a project into the workspace's routing. After that, `ddev start` keeps the routes up to date, including routes for add-on services. +- **Optional public sharing** of your sites, so you can show work-in-progress to someone without a Coder account. See [Sharing your site](sharing.md). +- **Optional Claude Code**, either as remote control from claude.ai/code or as a self-hosted runner. See [Claude Code](../workspaces/ai-tools.md). + +## The short version + +```bash +# In the workspace terminal (VS Code → Terminal → New Terminal) +git clone https://github.com/your-org/my-site.git ~/my-site +cd ~/my-site +ddev config --project-name=my-site # must be one of the workspace's project names +ddev coder-setup # once per project +ddev start +``` + +Then click the **my-site** app button on the workspace page, or run `ddev launch`. + +That's all there is to it. The rest of this section explains each step: + +1. [Creating a freeform workspace](create.md): the settings you can choose. +2. [Your first project](first-project.md): a complete walkthrough. +3. [Multiple projects](multiple-projects.md): running several sites side by side. +4. [Project recipes](recipes.md): copy-and-paste setups for popular frameworks. +5. [Services and add-ons](services.md): Mailpit, xhgui, databases, Redis, Solr and other DDEV add-ons. +6. [Sharing your site](sharing.md): making a site public. diff --git a/docs/content/freeform/multiple-projects.md b/docs/content/freeform/multiple-projects.md new file mode 100644 index 0000000..55b9c91 --- /dev/null +++ b/docs/content/freeform/multiple-projects.md @@ -0,0 +1,59 @@ +# Multiple Projects + +A freeform workspace can run several DDEV projects at once. Each project gets its own URL and app buttons, and they can all be running at the same time. + +## How it works + +Every project's site is served through DDEV's router inside the workspace. Coder sends each request to the router with the original hostname, and the router passes it to the right project based on that hostname. `ddev coder-setup` installs a hook so that every `ddev start` writes the routing rules for that project. + +Each project's URLs follow the same pattern: + +| What | URL | +| ----------- | ------------------------------------------------------------------ | +| Site | `https://----.coder.ddev.com` | +| Mailpit | `https://mailpit-----.coder.ddev.com` | +| xhgui | `https://xhgui-----.coder.ddev.com` | + +For example, the project `blog` in workspace `agency` owned by `jdoe` is at `https://blog--agency--jdoe.coder.ddev.com`. + +## Add a project + +1. **Register the name.** On the workspace page, open **Settings → Parameters** and add the name to **DDEV project names**, for example change `shop` to `shop,blog`. Save, then restart the workspace when prompted. This creates the new app buttons. +2. **Set up the project** in the workspace: + + ```bash + git clone git@github.com:your-org/blog.git ~/blog + cd ~/blog + ddev config --project-name=blog + ddev coder-setup + ddev start + ``` + +3. Click the new **blog** app button, or run `ddev launch`. + +!!! tip "Register all the names up front" + Restarting the workspace stops your running DDEV projects. If you know you'll want several projects, list them all when you create the workspace. Listing a name you don't use yet does no harm; its button just shows an error until that project is running. + +## Remove a project + +```bash +cd ~/blog +ddev delete --omit-snapshot # removes the project's containers and database +``` + +Then remove its name from **DDEV project names** and restart the workspace to remove its buttons. Delete the directory too if you no longer need the code. + +## Working with several projects + +```bash +ddev list # all projects and their status +ddev start --all # start every project +ddev stop blog # stop one project from anywhere +ddev poweroff # stop everything +``` + +All projects share the workspace's CPU, memory and disk. If the workspace feels slow, stop projects you aren't using. See [Workspace lifecycle](../workspaces/lifecycle.md#disk-space). + +## Projects with several hostnames + +DDEV's `additional_hostnames` and `additional_fqdns` (used for example by Drupal multisite or WordPress multisite) don't get their own workspace URLs. Each project has exactly one site URL per registered name. For multisite development, give each site its own DDEV project, or switch sites by path rather than hostname. diff --git a/docs/content/freeform/recipes.md b/docs/content/freeform/recipes.md new file mode 100644 index 0000000..afe14d5 --- /dev/null +++ b/docs/content/freeform/recipes.md @@ -0,0 +1,145 @@ +# Project Recipes + +These recipes create a new project from scratch in a freeform workspace. They follow DDEV's [CMS quickstarts](https://docs.ddev.com/en/stable/users/quickstart/) with the one extra step that a workspace needs: `ddev coder-setup`. + +Each recipe assumes the project name is registered in the workspace's **DDEV project names** (see [Creating a workspace](create.md#ddev-project-names)). Replace `my-site` with your project name. + +!!! tip "The pattern is always the same" + `ddev config --project-name= ...`, then `ddev coder-setup`, then `ddev start`. For any framework not listed here, use the matching DDEV quickstart and add `ddev coder-setup` before `ddev start`. + +## WordPress + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=wordpress +ddev coder-setup +ddev start +ddev wp core download +ddev wp core install --url='$DDEV_PRIMARY_URL' --title='My site' \ + --admin_user=admin --admin_password=admin --admin_email=admin@example.com +ddev launch /wp-admin/ +``` + +!!! note "WordPress site URL" + WordPress stores its own URL in the database. DDEV sets `WP_HOME` and `WP_SITEURL` for the project's `*.ddev.site` address, which isn't reachable through the workspace. If links or redirects point at `*.ddev.site`, set both to the workspace URL that `ddev launch` shows, in `wp-config.php` before DDEV's settings include, or with `ddev wp option update home ` and `ddev wp option update siteurl `. + +## Laravel + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=laravel --docroot=public +ddev coder-setup +ddev start +ddev composer create-project laravel/laravel . +ddev launch +``` + +## Symfony + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=symfony --docroot=public +ddev coder-setup +ddev start +ddev composer create-project symfony/skeleton . +ddev launch +``` + +## Drupal site + +For a Drupal *site* (not Drupal core development, which has its [own template](../drupal/quickstart.md)): + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=drupal11 --docroot=web +ddev coder-setup +ddev start +ddev composer create-project drupal/recommended-project . +ddev composer require drush/drush +ddev drush site:install --account-name=admin --account-pass=admin -y +ddev launch +``` + +Use `ddev drush uli` for a one-time login link; open it through `ddev launch` or replace the host with your workspace URL. + +## Drupal CMS + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=drupal11 --docroot=web +ddev coder-setup +ddev start +ddev composer create-project drupal/cms . +ddev launch +``` + +## TYPO3 + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=typo3 --docroot=public +ddev coder-setup +ddev start +ddev composer create-project typo3/cms-base-distribution . +ddev exec touch public/FIRST_INSTALL +ddev launch /typo3/install.php +``` + +## Craft CMS + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=craftcms --docroot=web +ddev coder-setup +ddev start +ddev composer create-project craftcms/craft . +ddev launch +``` + +## Static HTML or plain PHP + +```bash +mkdir -p ~/my-site/public && cd ~/my-site +echo ' public/index.php +ddev config --project-name=my-site --project-type=php --docroot=public +ddev coder-setup +ddev start +ddev launch +``` + +## Node.js app + +DDEV can run a Node.js server in its web container with `web_extra_daemons` and `web_extra_exposed_ports`. A minimal example with Express: + +```bash +mkdir ~/my-site && cd ~/my-site +ddev config --project-name=my-site --project-type=generic --webserver-type=generic +ddev coder-setup +cat > .ddev/config.node.yaml <<'YAML' +web_extra_daemons: + - name: node + command: "node server.js" + directory: /var/www/html +web_extra_exposed_ports: + - name: node + container_port: 3000 + http_port: 80 + https_port: 443 +YAML +ddev start +ddev npm init -y +ddev npm install express +cat > server.js <<'JS' +const app = require('express')(); +app.get('/', (req, res) => res.send('Hello from DDEV on Coder')); +app.listen(3000); +JS +ddev restart +ddev launch +``` + +See DDEV's documentation on [extra daemons and exposed ports](https://docs.ddev.com/en/stable/users/extend/customization-extendibility/) for more. + +## Front-end dev servers (Vite and friends) + +A dev server running inside the web container needs to know the public URL it is served from. `ddev coder-setup` puts these variables into the web container for that purpose: `CODER`, `CODER_AGENT_URL`, `CODER_WORKSPACE_NAME`, `CODER_WORKSPACE_OWNER_NAME`, `CODER_WORKSPACE_AGENT_NAME` and `VSCODE_PROXY_URI`. Use them in your dev server's configuration to allow the workspace's hostname and to set the HMR host. See the [URL patterns reference](../reference/coder-url-patterns.md) for how the hostnames are built, and DDEV's [Vite documentation](https://docs.ddev.com/en/stable/users/usage/vite/) for a general Vite setup. diff --git a/docs/content/freeform/services.md b/docs/content/freeform/services.md new file mode 100644 index 0000000..7cdc021 --- /dev/null +++ b/docs/content/freeform/services.md @@ -0,0 +1,56 @@ +# Services and Add-ons + +## Built in for every project + +| Service | How to open it | Notes | +| ------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| **Mailpit** | **Mailpit (project)** app button, or `ddev launch -m` | Catches all email the project sends. Always private. | +| **xhgui** | **xhgui (project)** app button | Profiling UI. Turn profiling on with `ddev xhgui on`. Always private. | +| **Database** | `ddev mysql`, `ddev psql`, `ddev import-db`, `ddev export-db`, `ddev snapshot` | MariaDB by default; change it with `ddev config --database=...`. | + +## Database tools + +The quickest way to look at the database is the command line: + +```bash +ddev mysql # interactive client (MariaDB/MySQL) +ddev mysql -e 'SHOW TABLES;' # one query +ddev export-db --file=backup.sql.gz # back up +ddev snapshot # fast snapshot you can restore with ddev snapshot restore +``` + +To use a desktop database client such as TablePlus or DBeaver, forward the database port to your computer with the Coder CLI. `ddev describe` shows the database's host port: + +```bash +# On your computer +coder port-forward my-workspace --tcp 3306: +``` + +Then connect your client to `127.0.0.1:3306` with user `db`, password `db`, database `db`. + +!!! note "Adminer and phpMyAdmin" + On coder.ddev.com, freeform workspaces don't have an **Adminer** app button. You can still install a database UI add-on (for example `ddev add-on get ddev/ddev-adminer`); `ddev launch` then lists its URL as a forwarded port that only you can open. + +## Other DDEV add-ons + +Install add-ons from the [DDEV add-on registry](https://addons.ddev.com) the usual way: + +```bash +ddev add-on get ddev/ddev-redis +ddev add-on get ddev/ddev-solr +ddev restart +``` + +The hook that `ddev coder-setup` installed runs after every start and adds routes for any new services that have a web interface. Run `ddev launch` to list all of the project's URLs, including those for add-ons. + +- Add-on services with a web interface are reachable through forwarded-port URLs such as `https://8983--main--my-workspace--jdoe.coder.ddev.com`. These are private to you. +- `ddev describe` shows the new URLs after one more `ddev restart`; `ddev launch` shows them right away. + +## Other ports + +Anything listening on a port in the workspace (a dev server you run by hand, for example) can be opened from the workspace page with the **Ports** button, or from the command line: + +```bash +# On your computer: make workspace port 5173 available as localhost:5173 +coder port-forward my-workspace --tcp 5173 +``` diff --git a/docs/content/freeform/sharing.md b/docs/content/freeform/sharing.md new file mode 100644 index 0000000..af94124 --- /dev/null +++ b/docs/content/freeform/sharing.md @@ -0,0 +1,30 @@ +# Sharing Your Site + +By default, only you can open your workspace's sites. Anyone else who opens the link is asked to sign in to coder.ddev.com and is then refused. + +## Make your sites public + +1. On the workspace page, open **Settings → Parameters**. +2. Turn on **Public Sharing** and save. +3. Restart the workspace. The change takes effect on the next start. + +Now anyone with a project's site URL can open it without signing in. Send them the URL that `ddev launch` shows. + +- Public Sharing applies to **every** project listed in **DDEV project names**; you can't share just one. +- **Mailpit and xhgui always stay private**, as do VS Code and the terminal. Other forwarded ports stay private unless you share them yourself from the workspace's **Open ports** menu. +- To stop sharing, turn the switch off and restart the workspace again. + +!!! warning "Public means public" + Anyone who gets the URL can open the site while it is running, including search engines and bots if the link is posted somewhere. Don't share sites that contain real customer data, and use the site's own login for anything that needs protection. + +## Sharing the workspace itself + +To let a teammate use your workspace (VS Code, terminal and private sites), share it with another coder.ddev.com user. On the workspace page, click **Share**, or use the CLI: + +```bash +coder sharing add my-workspace --user their-username:use # role: use or admin +coder sharing status my-workspace +coder sharing remove my-workspace --user their-username +``` + +They then see the workspace in their own Coder dashboard. See [Coder's shared workspaces documentation](https://coder.com/docs/user-guides/shared-workspaces) for what each role allows. diff --git a/docs/content/getting-started/access.md b/docs/content/getting-started/access.md new file mode 100644 index 0000000..d0a32cf --- /dev/null +++ b/docs/content/getting-started/access.md @@ -0,0 +1,38 @@ +# Getting Access + +coder.ddev.com is a service of the [DDEV Foundation](https://ddev.com). You sign in with GitHub, and access is limited to members of certain GitHub organizations. + +## Who has access + +You can use coder.ddev.com if your GitHub account is a member of one of these: + +- An organization that [sponsors DDEV](https://ddev.com/support-ddev/) at the $100/month level or above. +- The [`ddev`](https://github.com/ddev) organization. +- The [`coder-ddev-com`](https://github.com/coder-ddev-com) organization, which is how individual contributors get access. + +Your membership doesn't have to be public. When you first sign in, GitHub asks you to let coder.ddev.com read your organization memberships (the `read:org` permission); private membership is enough. + +!!! tip "Refused even though your organization sponsors DDEV?" + New sponsor organizations are added to the allow list by the DDEV team, so there can be a short delay. Make sure you have accepted your organization invitation on GitHub. If it still fails, [open an issue](https://github.com/ddev/coder-ddev/issues) or ask in the [DDEV Discord](https://ddev.com/s/discord). + +## Request access as an individual + +If you don't belong to a sponsoring organization, [open an access request](https://github.com/coder-ddev-com/access-requests/issues/new?template=access-request.yml). Tell us briefly what you want to work on. Once it is approved, you are invited to the `coder-ddev-com` organization. Accept the invitation from GitHub's email or from [github.com/orgs/coder-ddev-com/invitation](https://github.com/orgs/coder-ddev-com/invitation), then sign in. + +## Sign in + +1. Go to [coder.ddev.com/login](https://coder.ddev.com/login). +2. Choose **Sign in with GitHub** and approve the app. +3. You arrive at your **Workspaces** page. It's empty until you create your first workspace. + +If you see an "access denied" page, your GitHub account isn't in one of the organizations above yet. + +## Use the CLI (optional) + +The [Coder CLI](https://coder.com/docs/install/cli) lets you SSH into workspaces, copy files, and connect desktop editors. + +```bash +coder login https://coder.ddev.com +``` + +This opens your browser to approve the login. See [Editors, SSH and files](../workspaces/editors-and-ssh.md) for what you can do next. diff --git a/docs/content/getting-started/choosing-a-template.md b/docs/content/getting-started/choosing-a-template.md new file mode 100644 index 0000000..3aa27be --- /dev/null +++ b/docs/content/getting-started/choosing-a-template.md @@ -0,0 +1,16 @@ +# Choosing a Template + +coder.ddev.com offers three workspace templates. All of them include the same tools (DDEV, Docker, VS Code for Web, Git); they differ in what gets set up for you. + +| Template | Best for | What is set up for you | Start here | +| ------------------ | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| **freeform** | Your own projects in any framework DDEV supports; several projects at once | Nothing project-specific. You clone or create projects yourself; each listed project gets its own URL and app buttons. | [Freeform workspaces](../freeform/index.md) | +| **drupal-core** | Drupal core development and core issue forks | A Drupal core checkout, installed site, issue fork branch if you choose one | [Drupal issue picker](https://start.coder.ddev.com/drupal-issue) or [Drupal quickstart](../drupal/quickstart.md) | +| **drupal-contrib** | Working on a contrib module or theme from drupal.org | The project checkout, a Drupal site with the project enabled, issue fork branch if you choose one | [Drupal issue picker](https://start.coder.ddev.com/drupal-issue) | + +## Rules of thumb + +- **Working on a drupal.org issue?** Use the [issue picker](https://start.coder.ddev.com/drupal-issue). It detects core or contrib and fills in the right settings. +- **Anything else** (a client site, a WordPress or Laravel app, a Drupal site that isn't core development, trying out a framework): use **freeform**. +- **Several related sites** (for example a front end and an API, or a multisite setup): use one **freeform** workspace with several [projects](../freeform/multiple-projects.md). +- **Want projects fully isolated from each other?** Create separate workspaces. Each workspace has its own Docker daemon and disk. diff --git a/docs/user/getting-started.md b/docs/content/getting-started/first-workspace.md similarity index 96% rename from docs/user/getting-started.md rename to docs/content/getting-started/first-workspace.md index 5082620..054d8ed 100644 --- a/docs/user/getting-started.md +++ b/docs/content/getting-started/first-workspace.md @@ -7,6 +7,7 @@ This guide helps you create your first DDEV workspace and start developing in th **Coder** is an open-source platform for creating remote development environments. Instead of developing on your local machine, you work in a cloud-based workspace with all tools pre-installed. **Key concepts:** + - **Workspace** - Your personal development environment (like a remote VM) - **Template** - A blueprint for creating workspaces (pre-configured tools, settings) - **Agent** - Software running in your workspace that connects to Coder server @@ -22,6 +23,7 @@ With this template, DDEV runs inside your cloud workspace, giving you all DDEV f ### Coder Account You need access to a Coder server. Ask your administrator for: + - Coder server URL (e.g., `https://coder.example.com`) - Username and password (or SSO login) - Confirmation that the `freeform` template is available @@ -31,6 +33,7 @@ You need access to a Coder server. Ask your administrator for: Install on your local machine: **Coder CLI** (required for SSH access): + ```bash # macOS (Homebrew) brew install coder/coder/coder @@ -45,12 +48,14 @@ winget install Coder.Coder ``` **SSH client** (usually pre-installed): + ```bash # Verify SSH is available ssh -V ``` **Git** (optional, for cloning repositories): + ```bash # macOS brew install git @@ -68,6 +73,7 @@ git --version ### Optional: Desktop VS Code If you prefer desktop VS Code over the web version: + ```bash # Download from https://code.visualstudio.com/ # Install Remote-SSH extension @@ -95,6 +101,7 @@ coder login https://coder.example.com ``` **Verify login:** + ```bash coder list # Should show your workspaces (empty if this is your first time) @@ -116,6 +123,7 @@ coder list 5. Click **Create Workspace** **Wait for workspace to start** (1-3 minutes): + - Status will change from "Starting" to "Running" - You'll see the workspace dashboard @@ -133,6 +141,7 @@ coder create --template freeform my-first-workspace \ ``` **Check workspace status:** + ```bash coder list # Should show your workspace as "Running" @@ -159,6 +168,7 @@ coder ssh my-first-workspace ``` **Run your first command:** + ```bash # Check DDEV is installed ddev version @@ -246,6 +256,7 @@ ddev start ``` **Wait for DDEV to start** (1-2 minutes first time): + ``` Starting my-site... ... @@ -294,6 +305,7 @@ ddev start DDEV normally uses URLs like `https://my-site.ddev.site`, but in Coder, you access projects via **port forwarding**. **How it works:** + 1. DDEV listens on ports 80/443 inside workspace 2. Coder forwards these ports through its proxy 3. You access via Coder's forwarded URLs @@ -301,6 +313,7 @@ DDEV normally uses URLs like `https://my-site.ddev.site`, but in Coder, you acce ### Access Your Project **Via Coder Web UI (Recommended):** + 1. Go to Coder dashboard 2. Find your workspace 3. Under **Apps**, click **DDEV Web** @@ -309,6 +322,7 @@ DDEV normally uses URLs like `https://my-site.ddev.site`, but in Coder, you acce The URL follows the pattern: `https://ddev-web--workspace-name--owner.coder.example.com/` **Via CLI Port Forward:** + ```bash # Forward port to your local machine coder port-forward my-first-workspace --tcp 8080:80 @@ -318,6 +332,7 @@ coder port-forward my-first-workspace --tcp 8080:80 ``` **Check DDEV status:** + ```bash ddev describe # Shows project details and status @@ -329,12 +344,14 @@ ddev describe ### Edit Files **Via VS Code for Web:** + 1. Open VS Code (Apps → VS Code in Coder UI) 2. Navigate to `~/projects/my-site` 3. Edit files normally 4. Changes are saved automatically **Via SSH and vim:** + ```bash coder ssh my-first-workspace cd ~/projects/my-site @@ -404,7 +421,8 @@ git config --global user.email "your.email@example.com" To clone private repositories or push to GitHub/GitLab/etc, you need to add your Coder public key to your Git host. -**Step 1: Get your Coder public key** +#### Step 1: Get your Coder public key + ```bash # Inside workspace (via SSH or VS Code terminal) coder publickey @@ -413,25 +431,29 @@ coder publickey # Copy the entire output (starts with ssh-ed25519 or ssh-rsa) ``` -**Step 2: Add key to your Git host** +## Step 2: Add key to your Git host **For GitHub:** -1. Go to https://github.com/settings/keys + +1. Go to 2. Click **New SSH key** 3. Paste your Coder public key 4. Click **Add SSH key** **For GitLab:** -1. Go to https://gitlab.com/-/profile/keys + +1. Go to 2. Paste your Coder public key 3. Click **Add key** **For Bitbucket:** -1. Go to https://bitbucket.org/account/settings/ssh-keys/ + +1. Go to 2. Click **Add key** 3. Paste your Coder public key -**Step 3: Test SSH connection** +### Step 3: Test SSH connection + ```bash # Test GitHub ssh -T git@github.com @@ -475,6 +497,7 @@ coder stop my-first-workspace ``` **What happens when stopped:** + - Workspace container stops - All files in `/home/coder` are preserved - DDEV projects are preserved @@ -492,6 +515,7 @@ coder start my-first-workspace **Startup time:** faster than initial create (no reinstall needed) **After starting:** + ```bash # SSH in coder ssh my-first-workspace @@ -513,12 +537,14 @@ coder delete my-first-workspace ``` **What gets deleted:** + - Workspace container - All files in `/home/coder` - All DDEV projects and databases - Docker images and volumes inside workspace **Before deleting:** + ```bash # Backup important data cd ~/projects @@ -531,6 +557,7 @@ tar -czf backup.tar.gz my-site/ ### Workspace Won't Start **Check status:** + ```bash coder list # If stuck in "Starting", check logs: @@ -538,6 +565,7 @@ coder logs my-first-workspace ``` **Common causes:** + - Template not deployed correctly (contact admin) - Resource limits exceeded (contact admin) - Sysbox runtime not installed on host (contact admin) @@ -547,6 +575,7 @@ coder logs my-first-workspace **Symptom:** `Cannot connect to Docker daemon` **Solution:** + ```bash # Check Docker service systemctl status docker @@ -565,12 +594,14 @@ If still broken, restart workspace: `coder restart my-first-workspace` **Symptom:** `ddev start` fails **Check Docker first:** + ```bash docker ps # If this fails, fix Docker before DDEV ``` **Common DDEV issues:** + ```bash # Reset DDEV project ddev poweroff @@ -587,6 +618,7 @@ ddev start **Symptom:** Port forwarding shows ports but URLs don't load **Check:** + ```bash # Inside workspace ddev describe @@ -595,6 +627,7 @@ curl localhost:80 ``` **Solution:** + - Use Coder's port forwarding links (not DDEV URLs) - Find port URLs in the **Ports** section of Coder web UI - DDEV's URLs (*.ddev.site) won't work in Coder @@ -604,6 +637,7 @@ curl localhost:80 **Symptom:** `Permission denied (publickey)` when cloning **Solution:** + 1. Get your Coder public key: `coder publickey` 2. Add that key to GitHub/GitLab (Settings → SSH Keys) 3. Test: `ssh -T git@github.com` @@ -614,6 +648,7 @@ curl localhost:80 **Symptom:** `No space left on device` **Solution:** + ```bash # Clean Docker images and volumes docker system prune -a --volumes -f @@ -629,6 +664,7 @@ rm -rf ~/projects/old-project ### Workspace is Slow **Check resources:** + ```bash # Inside workspace top # Check CPU usage @@ -637,6 +673,7 @@ docker stats # Check Docker container resources ``` **Solution:** + - Stop unused DDEV projects: `ddev stop --all` - Increase workspace resources (delete and recreate with higher CPU/RAM) - Contact admin to increase default resources @@ -651,8 +688,8 @@ docker stats # Check Docker container resources ### Learn More About Coder -- **[Using Workspaces](./using-workspaces.md)** - Daily workflows and tips -- **[Coder CLI](https://coder.com/docs/cli)** - CLI reference +- **[Using Workspaces](../workspaces/guide.md)** - Daily workflows and tips +- **[Coder CLI](https://coder.com/docs/reference/cli)** - CLI reference - **[VS Code for Web](https://coder.com/docs/ides/web-ides)** - IDE features ### Try More Project Types @@ -733,8 +770,8 @@ source ~/.bashrc ### Documentation -- [Using Workspaces](./using-workspaces.md) - Advanced workflows -- [Troubleshooting Guide](../admin/troubleshooting.md) - Detailed debugging +- [Using Workspaces](../workspaces/guide.md) - Advanced workflows +- [Troubleshooting Guide](../workspaces/troubleshooting.md) - Detailed debugging - [DDEV Docs](https://docs.ddev.com/) - DDEV reference ### Support @@ -747,7 +784,7 @@ source ~/.bashrc ### Before Asking for Help 1. Check this guide's [Troubleshooting](#troubleshooting) section -2. Review [Troubleshooting Guide](../admin/troubleshooting.md) +2. Review [Troubleshooting Guide](../workspaces/troubleshooting.md) 3. Collect error messages and logs 4. Try restarting workspace: `coder restart my-first-workspace` diff --git a/docs/content/getting-started/index.md b/docs/content/getting-started/index.md new file mode 100644 index 0000000..7b0f8d0 --- /dev/null +++ b/docs/content/getting-started/index.md @@ -0,0 +1,31 @@ +# Getting Started + +DDEV Coder Workspaces are cloud development environments hosted at [coder.ddev.com](https://coder.ddev.com). They are built on [Coder](https://coder.com), an open-source platform for remote development environments, and they run [DDEV](https://ddev.com) inside each workspace. + +## How it works + +1. **[Get access](access.md)** and sign in to coder.ddev.com with your GitHub account. +2. **[Choose a template](choosing-a-template.md)**: Drupal issue, Drupal core or freeform. +3. **Create a workspace.** It's ready in about a minute. +4. **Open it** with the app buttons on the workspace page: **VS Code** for the editor and terminal, and one button for each DDEV site. + +## What's in a workspace + +- **Docker and DDEV.** Each workspace runs its own Docker daemon, so DDEV works the same way it does on your own computer. +- **VS Code for Web**, opened in your project directory, with a terminal. +- **Git and SSH.** Coder gives each account an SSH key that Git in the workspace uses automatically. Add it to GitHub, GitLab or drupal.org and you can clone and push. +- **Node.js, Composer (through DDEV), Homebrew** and common command-line tools. +- **Passwordless `sudo`**, so you can install anything else you need. +- **Persistent storage.** Your home directory, Docker images and Homebrew packages survive stopping and starting the workspace. See [Workspace lifecycle](../workspaces/lifecycle.md). + +## What you need + +- A web browser. Everything else is optional. +- A GitHub account that has access. See [Getting access](access.md). +- Optional: the [Coder CLI](https://coder.com/docs/install/cli) if you want to use SSH, `scp` or desktop editors. See [Editors, SSH and files](../workspaces/editors-and-ssh.md). + +## Next steps + +- New to all of this? Follow [Your first workspace](first-workspace.md). +- Bringing your own project? Go straight to [Freeform workspaces](../freeform/index.md). +- Contributing to Drupal? Use the [Drupal quickstart](../drupal/quickstart.md). diff --git a/docs/content/index.md b/docs/content/index.md new file mode 100644 index 0000000..61318cf --- /dev/null +++ b/docs/content/index.md @@ -0,0 +1,50 @@ +# DDEV Coder Workspaces + +[coder.ddev.com](https://coder.ddev.com) gives you a complete [DDEV](https://ddev.com) development environment in your browser. Each workspace is its own Linux machine with Docker, DDEV, Git, Node.js, Composer and VS Code for Web already set up. You don't need to install anything on your computer. + +
+ +- :material-rocket-launch: **[Get started](getting-started/index.md)** + + --- + + Get access, sign in with GitHub and create your first workspace. + +- :material-shape-plus: **[Freeform workspaces](freeform/index.md)** + + --- + + Bring any DDEV project (WordPress, Laravel, Symfony, Drupal sites, Node, static sites) and run one or several of them in one workspace. + +- :material-water: **[Drupal contribution](drupal/quickstart.md)** + + --- + + Start a ready-to-go Drupal core or contrib workspace from a drupal.org issue. + +- :material-console: **[Working in a workspace](workspaces/lifecycle.md)** + + --- + + What persists, VS Code and SSH, Claude Code, and fixing common problems. + +
+ +## Start a workspace + +| I want to… | Go to | +| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| Work on a drupal.org issue or contrib project | [Drupal issue picker](https://start.coder.ddev.com/drupal-issue) | +| Run my own project, or several projects at once | [Create a freeform workspace](https://coder.ddev.com/templates/coder/freeform/workspace?mode=manual) | +| Get a clean Drupal core checkout with no issue fork | [Guided Drupal core](https://start.coder.ddev.com/drupal-core) | + +Not sure which one? See [Choosing a template](getting-started/choosing-a-template.md). + +## Get help + +- [Troubleshooting](workspaces/troubleshooting.md) covers the most common problems. +- Report bugs or ask for features in [ddev/coder-ddev issues](https://github.com/ddev/coder-ddev/issues). +- Chat with us in the [DDEV Discord](https://ddev.com/s/discord) or in **#ddev** on Drupal Slack. + +!!! note "Running your own Coder server?" + These docs are written for people using the hosted service at coder.ddev.com. If you want to run these templates on your own infrastructure, see [Self-Hosting](self-hosting/overview.md). diff --git a/docs/reference/coder-url-patterns.md b/docs/content/reference/coder-url-patterns.md similarity index 100% rename from docs/reference/coder-url-patterns.md rename to docs/content/reference/coder-url-patterns.md diff --git a/docs/architecture/comparison-to-local.md b/docs/content/reference/comparison-to-local.md similarity index 97% rename from docs/architecture/comparison-to-local.md rename to docs/content/reference/comparison-to-local.md index 5ba092e..7a33c00 100644 --- a/docs/architecture/comparison-to-local.md +++ b/docs/content/reference/comparison-to-local.md @@ -5,6 +5,7 @@ This guide is for teams and developers familiar with local DDEV who are evaluati ## Executive Summary **Local DDEV:** + - Runs on your laptop/desktop - Uses local Docker Desktop or Docker Engine - Direct filesystem access @@ -12,6 +13,7 @@ This guide is for teams and developers familiar with local DDEV who are evaluati - No authentication, single user **DDEV in Coder:** + - Runs in cloud workspace (remote container) - Uses Docker-in-Docker via Sysbox runtime - Remote filesystem (persistent volumes) @@ -42,6 +44,7 @@ This guide is for teams and developers familiar with local DDEV who are evaluati ``` **Key points:** + - DDEV talks directly to local Docker - Project files on local filesystem - `*.ddev.site` domains via ddev-router @@ -76,6 +79,7 @@ This guide is for teams and developers familiar with local DDEV who are evaluati ``` **Key differences:** + - Nested Docker (Docker-in-Docker via Sysbox) - Remote filesystem (persistent across sessions) - Port forwarding instead of *.ddev.site @@ -86,17 +90,20 @@ This guide is for teams and developers familiar with local DDEV who are evaluati ### 1. Docker Runtime **Local DDEV:** + - Uses Docker Desktop (macOS/Windows) or Docker Engine (Linux) - DDEV talks to Docker socket: `/var/run/docker.sock` - Privileged operations allowed **Coder DDEV:** + - Uses Docker-in-Docker via Sysbox runtime - Each workspace has isolated Docker daemon - Sysbox provides security without `--privileged` - Docker data in dedicated volume: `/var/lib/docker` **Implications:** + - ✅ Better isolation (workspaces can't interfere) - ✅ Multi-user safe (no shared Docker daemon) - ⚠️ Slightly slower Docker operations (nested overhead) @@ -105,18 +112,21 @@ This guide is for teams and developers familiar with local DDEV who are evaluati ### 2. Networking **Local DDEV:** + - Uses `ddev-router` container for *.ddev.site domains - Direct port binding to localhost - mDNS for .ddev.site resolution - LAN access possible (optional) **Coder DDEV:** + - No ddev-router (not needed) - Port forwarding via Coder proxy - Access via DDEV Web app URL: `https://ddev-web--workspace--owner.coder.example.com/` - *.ddev.site URLs don't work **Migration:** + ```yaml # Local .ddev/config.yaml (not needed in Coder) router_http_port: "80" @@ -128,6 +138,7 @@ use_dns_when_possible: true ``` **Access patterns:** + ```bash # Local DDEV curl https://my-site.ddev.site @@ -141,18 +152,21 @@ curl http://localhost:80 ### 3. Filesystem **Local DDEV:** + - Project files on local filesystem (e.g., `~/projects/my-site`) - Mounted into containers via Docker bind mounts - Fast file operations (native filesystem) - NFS option for macOS (optional) **Coder DDEV:** + - Project files on remote volume (`/home/coder/projects/my-site`) - Persistent across workspace restarts - Mounted into DDEV containers (nested mount) - Network latency for file operations **Performance comparison:** + | Operation | Local DDEV | Coder DDEV | |-----------|------------|------------| | Read file | ~1ms | ~5-20ms | @@ -163,6 +177,7 @@ curl http://localhost:80 | Page render | Fast | Similar | **Optimization:** + - Use NFS mount in Coder: `nfs_mount_enabled: true` in `.ddev/config.yaml` - Disable Xdebug when not needed: `ddev xdebug off` - Use Docker layer caching for builds @@ -170,18 +185,21 @@ curl http://localhost:80 ### 4. IDE and Development Environment **Local DDEV:** + - Desktop IDE (VS Code, PHPStorm, Sublime) - Direct filesystem access - Local terminal - Native performance **Coder DDEV:** + - VS Code for Web (browser-based) - Remote filesystem (via Coder agent) - Remote terminal (via SSH or VS Code) - Network latency for file operations **Desktop IDE with Coder:** + ```bash # Configure SSH coder config-ssh @@ -195,6 +213,7 @@ coder config-ssh ``` **Tradeoffs:** + | Aspect | Desktop IDE + Local DDEV | VS Code Web + Coder DDEV | |--------|--------------------------|--------------------------| | Latency | None | 10-100ms | @@ -207,20 +226,23 @@ coder config-ssh ### 5. Team Collaboration **Local DDEV:** + - Each developer has own setup - Configuration drift possible - Manual environment setup (documentation) - No centralized management **Coder DDEV:** + - Identical environments for all users - Centralized template management - Zero-setup onboarding (create workspace) - Admin controls resources, versions -**Example: Onboarding time** +#### Example: Onboarding time **Local DDEV:** + 1. Install Docker Desktop (5-10 min) 2. Install DDEV (5 min) 3. Install IDE (5-10 min) @@ -229,25 +251,28 @@ coder config-ssh 6. Configure environment (10-30 min) 7. Troubleshoot issues (0-120 min) -**Total: 40 minutes to 3+ hours** +##### Total: 40 minutes to 3+ hours **Coder DDEV:** + 1. Get Coder credentials (1 min) 2. Create workspace (2 min) 3. Clone repository (5 min) 4. Start DDEV (2 min) -**Total: 10 minutes** +###### Total: 10 minutes ### 6. Resource Management **Local DDEV:** + - Uses local machine resources (RAM, CPU, disk) - Limited by laptop/desktop specs - Must manage Docker resource limits - Affects battery life (laptops) **Coder DDEV:** + - Uses cloud resources (configurable) - Scalable per project needs - Doesn't affect local machine @@ -256,11 +281,13 @@ coder config-ssh **Example configurations:** **Local laptop:** + - 16GB RAM, 4-core CPU - Supports 2-3 DDEV projects simultaneously - Docker Desktop limit: 8GB RAM, 2 cores **Coder workspace:** + - Default: 8GB RAM, 4 cores - Configurable: up to 64GB RAM, 32 cores - Dedicated Docker volume (no local disk impact) @@ -269,12 +296,14 @@ coder config-ssh ### 7. Persistence and Backup **Local DDEV:** + - Projects on local disk - Time Machine / manual backups - Git for code (must push) - Database snapshots: `ddev snapshot` **Coder DDEV:** + - Projects on persistent remote volume - Volume survives workspace stop/restart - Git for code (must push) @@ -284,18 +313,21 @@ coder config-ssh **Data loss scenarios:** **Local DDEV:** + - ❌ Disk failure (no backup) - ❌ Laptop stolen/lost - ✅ Git push before failure - ⚠️ Database not in Git (use snapshots) **Coder DDEV:** + - ✅ Workspace stop/restart (data preserved) - ✅ Volume backed up (admin configured) - ❌ Workspace deletion (permanent) - ⚠️ Database not in Git (use snapshots) **Best practices:** + - **Always commit and push code regularly** (both) - **Use `ddev snapshot` before risky operations** (both) - **Export databases periodically** (both) @@ -306,6 +338,7 @@ coder config-ssh ### 1. Team Consistency **Problem with local DDEV:** + - Developer A: macOS, Docker Desktop, DDEV 1.23, PHP 8.1 - Developer B: Windows, Docker Desktop, DDEV 1.24, PHP 8.2 - Developer C: Linux, Docker Engine, DDEV 1.22, PHP 8.1 @@ -313,6 +346,7 @@ coder config-ssh Result: "It works on my machine" syndrome. **Solution with Coder:** + - All developers: Ubuntu 24.04, DDEV 1.24.10, PHP 8.1 (same image) - Update template → everyone gets update - No configuration drift @@ -320,6 +354,7 @@ Result: "It works on my machine" syndrome. ### 2. Zero-Setup Onboarding **Local DDEV onboarding:** + ```bash # Developer's first day brew install docker # or download Docker Desktop @@ -334,6 +369,7 @@ ddev start ``` **Coder DDEV onboarding:** + ```bash # Developer's first day coder create --template freeform my-workspace --yes @@ -343,12 +379,14 @@ coder create --template freeform my-workspace --yes ### 3. Powerful Resources **Local laptop limitations:** + - Building large Docker images: slow - Running multiple projects: swapping - Composer/npm with many packages: slow - Database imports: slow **Coder workspace:** + - Configurable resources (8GB, 16GB, 32GB RAM) - Fast cloud CPUs - SSD storage @@ -357,11 +395,13 @@ coder create --template freeform my-workspace --yes ### 4. Remote Work Friendly **Local DDEV on weak laptop:** + - Slow Docker performance - Limited battery life - Can't work from tablet/Chromebook **Coder DDEV:** + - Access from any device with browser - Work from iPad, Chromebook, hotel computer - Same performance regardless of device @@ -369,6 +409,7 @@ coder create --template freeform my-workspace --yes ### 5. Centralized Management **Admins can:** + - Update DDEV version for all workspaces (rebuild image) - Set resource limits (prevent abuse) - Backup all workspaces (host-level) @@ -382,15 +423,18 @@ coder create --template freeform my-workspace --yes ### 1. Internet Dependency **Local DDEV:** + - ✅ Works offline (once installed) - ✅ No network latency **Coder DDEV:** + - ❌ Requires internet connection - ⚠️ Network latency (10-100ms) - ⚠️ Slow/unreliable internet = bad experience **Mitigation:** + - Use fast internet (50+ Mbps) - Deploy Coder close to users (low latency) - Cache Docker images in workspace @@ -398,14 +442,17 @@ coder create --template freeform my-workspace --yes ### 2. Filesystem Performance **Local DDEV:** + - Fast file operations (native filesystem) - `composer install`: 30 seconds **Coder DDEV:** + - Slower file operations (remote volume) - `composer install`: 60-90 seconds **Mitigation:** + - Use NFS: `nfs_mount_enabled: true` - Use Docker layer caching - Accept tradeoff for benefits @@ -413,16 +460,19 @@ coder create --template freeform my-workspace --yes ### 3. IDE Limitations **Local DDEV:** + - Full desktop IDE (PHPStorm, VS Code, Sublime) - All extensions available - Native performance **Coder DDEV:** + - VS Code for Web (most extensions work) - Some extensions unavailable (require desktop) - Network latency **Mitigation:** + - Use desktop VS Code with Remote-SSH - Use PHPStorm with SFTP deployment - Most developers adapt to VS Code for Web @@ -430,14 +480,17 @@ coder create --template freeform my-workspace --yes ### 4. *.ddev.site URLs Don't Work **Local DDEV:** + - Access via: `https://my-site.ddev.site` - Multiple projects: `https://site1.ddev.site`, `https://site2.ddev.site` **Coder DDEV:** + - Access via port forwarding: `https://coder.example.com/port/12345` - Multiple projects: different ports **Mitigation:** + - Use Coder UI to find port links (bookmark them) - Configure custom domains (admin) - Accept tradeoff for remote access benefits @@ -445,19 +498,23 @@ coder create --template freeform my-workspace --yes ### 5. Cost Considerations **Local DDEV:** + - Free (uses your hardware) - One-time laptop/desktop cost **Coder DDEV:** + - Cloud compute costs (per workspace per hour) - Storage costs (per GB per month) **Example costs** (AWS us-east-1, 2024): + - 4 vCPU, 8GB RAM: ~$0.15/hour = $110/month (24/7) - Stop when not in use: ~$30/month (8 hours/day, 5 days/week) - Storage (50GB): ~$5/month **Mitigation:** + - Stop workspaces when not in use - Use smaller workspaces for simple projects - Savings from reduced onboarding time, consistency, IT support @@ -467,24 +524,28 @@ coder create --template freeform my-workspace --yes ### For Organizations **1. Evaluate:** + - Try Coder with 2-3 developers - Test typical workflows - Measure onboarding time improvement - Compare costs vs benefits **2. Plan:** + - Choose cloud provider (AWS, GCP, Azure, on-prem) - Install Coder server - Install Sysbox on agent nodes - Build and deploy the freeform template **3. Pilot:** + - Onboard 5-10 developers - Collect feedback - Iterate on template configuration - Document workflows **4. Rollout:** + - Onboard remaining developers - Deprecate local DDEV (optional) - Monitor usage and costs @@ -492,6 +553,7 @@ coder create --template freeform my-workspace --yes ### For Individual Projects **1. Clone project:** + ```bash # In Coder workspace cd ~/projects @@ -500,6 +562,7 @@ cd project ``` **2. Copy DDEV config:** + ```bash # Local machine (if you have custom .ddev/config.yaml) scp -r .ddev my-workspace:~/projects/project/ @@ -511,6 +574,7 @@ git push ``` **3. Adjust config for Coder:** + ```yaml # .ddev/config.yaml @@ -528,17 +592,20 @@ git push ``` **4. Start project:** + ```bash ddev start ``` **5. Test:** + - Access via Coder port forwarding - Run tests: `ddev exec phpunit` - Check database: `ddev mysql` - Import production database: `ddev import-db --url=...` **6. Document differences:** + ```markdown # Project README update @@ -554,7 +621,8 @@ Access: https://project.ddev.site ### Common Migration Issues -**Issue 1: Custom local configuration** +#### Issue 1: Custom local configuration + ```yaml # Local .ddev/config.yaml web_environment: @@ -569,7 +637,8 @@ web_environment: - API_KEY=${API_KEY} ``` -**Issue 2: Local file paths** +## Issue 2: Local file paths + ```php // Local code require_once '/Users/john/projects/library/autoload.php'; @@ -579,6 +648,7 @@ require_once __DIR__ . '/../library/autoload.php'; ``` **Issue 3: *.ddev.site hardcoded** + ```javascript // Local code const API_URL = 'https://api.ddev.site'; @@ -587,7 +657,8 @@ const API_URL = 'https://api.ddev.site'; const API_URL = process.env.API_URL || 'https://api.ddev.site'; ``` -**Issue 4: Performance-sensitive operations** +### Issue 4: Performance-sensitive operations + ```bash # Local: fast npm install # 30 seconds @@ -600,49 +671,58 @@ ddev npm install # 60-90 seconds ## When to Use Which -### Use Local DDEV when: +### Use Local DDEV when ✅ **Solo developer, personal projects** + - No team coordination needed - You control your machine - Offline work required ✅ **Optimal performance critical** + - Heavy file operations - Real-time compilation watchers - Can't tolerate network latency ✅ **Very limited budget** + - Cloud costs not acceptable - Have powerful local machine ✅ **Fully offline work** + - No reliable internet - Security requires air-gapped dev -### Use Coder DDEV when: +### Use Coder DDEV when ✅ **Team development** + - Multiple developers - Need consistent environments - Onboarding time matters ✅ **Remote work** + - Distributed team - Work from multiple locations/devices - Weak laptops, tablets ✅ **Centralized management** + - IT wants control - Compliance/security requirements - Resource quotas needed ✅ **Fast onboarding** + - High turnover - Contractors/interns - Training environments ✅ **Scalable resources** + - Projects need more than laptop can provide - Heavy builds, large databases @@ -651,11 +731,13 @@ ddev npm install # 60-90 seconds Some teams use both: **Developers choose:** + - Local DDEV for daily work (fast) - Coder DDEV for testing, demos, reviews - Coder DDEV for onboarding new team members **Projects decide:** + - Simple projects: local DDEV - Complex projects: Coder DDEV - Prototypes: local DDEV @@ -704,12 +786,14 @@ A: Yes, easily. Clone Git repo, use same .ddev/config.yaml, run `ddev start`. **Coder DDEV is not a replacement for local DDEV in all cases.** It's a different deployment model with different tradeoffs. **Best for:** + - Teams prioritizing consistency and onboarding speed - Remote/distributed teams - Organizations with centralized IT management - Projects needing more resources than laptops provide **Local DDEV still best for:** + - Solo developers with good local setup - Performance-critical workflows - Offline work requirements @@ -721,6 +805,6 @@ A: Yes, easily. Clone Git repo, use same .ddev/config.yaml, run `ddev start`. - [DDEV Documentation](https://docs.ddev.com/) - Official DDEV docs - [Coder Documentation](https://coder.com/docs) - Official Coder docs -- [Getting Started Guide](../user/getting-started.md) - New to Coder DDEV -- [Operations Guide](../admin/operations-guide.md) - Deployment and management +- [Getting Started Guide](../getting-started/index.md) - New to Coder DDEV +- [Operations Guide](../self-hosting/operations-guide.md) - Deployment and management - [GitHub Issues](https://github.com/ddev/coder-ddev/issues) - Ask questions, report issues diff --git a/docs/admin/coder-ddev-com/access-request-issue-template.yml b/docs/content/self-hosting/coder-ddev-com/access-request-issue-template.yml similarity index 100% rename from docs/admin/coder-ddev-com/access-request-issue-template.yml rename to docs/content/self-hosting/coder-ddev-com/access-request-issue-template.yml diff --git a/docs/admin/coder-ddev-com/access-requests-README.md b/docs/content/self-hosting/coder-ddev-com/access-requests-README.md similarity index 99% rename from docs/admin/coder-ddev-com/access-requests-README.md rename to docs/content/self-hosting/coder-ddev-com/access-requests-README.md index 86e0fb1..53d74cd 100644 --- a/docs/admin/coder-ddev-com/access-requests-README.md +++ b/docs/content/self-hosting/coder-ddev-com/access-requests-README.md @@ -25,6 +25,7 @@ If you do not have access through one of the above paths, open an issue in this We will review your request and, if approved, add you to the `coder-ddev-com` org. You will receive a GitHub invitation — once you accept it, you can sign in to coder.ddev.com with your GitHub account. **What to include in your request:** + - Your GitHub username - Why you want access (brief description — DDEV user, contributor, etc.) diff --git a/docs/admin/coder-ddev-com/org-profile-README.md b/docs/content/self-hosting/coder-ddev-com/org-profile-README.md similarity index 91% rename from docs/admin/coder-ddev-com/org-profile-README.md rename to docs/content/self-hosting/coder-ddev-com/org-profile-README.md index 7ebe3d1..5de940e 100644 --- a/docs/admin/coder-ddev-com/org-profile-README.md +++ b/docs/content/self-hosting/coder-ddev-com/org-profile-README.md @@ -29,4 +29,4 @@ If you do not have access through one of the paths above, open an issue in the [ ## Questions -Visit the [DDEV Discord](https://discord.ddev.com) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). +Visit the [DDEV Discord](https://ddev.com/s/discord) or open an issue in [ddev/ddev](https://github.com/ddev/ddev/issues). diff --git a/docs/admin/coder-ddev-com/sponsor-notification.md b/docs/content/self-hosting/coder-ddev-com/sponsor-notification.md similarity index 79% rename from docs/admin/coder-ddev-com/sponsor-notification.md rename to docs/content/self-hosting/coder-ddev-com/sponsor-notification.md index 9a6f88f..ee118c8 100644 --- a/docs/admin/coder-ddev-com/sponsor-notification.md +++ b/docs/content/self-hosting/coder-ddev-com/sponsor-notification.md @@ -6,11 +6,12 @@ Subject: coder.ddev.com access for [ORG NAME] org members Hi, -As a $100+/month sponsor of DDEV, all members of the **[ORG NAME]** GitHub organization ([github.com/[GITHUB ORG SLUG]](https://github.com/[GITHUB ORG SLUG])) now have access to **[coder.ddev.com](https://coder.ddev.com)** — a cloud-hosted DDEV development environment. +As a $100+/month sponsor of DDEV, all members of the **[ORG NAME]** GitHub organization (`https://github.com/[GITHUB ORG SLUG]`) now have access to **[coder.ddev.com](https://coder.ddev.com)** — a cloud-hosted DDEV development environment. **What is coder.ddev.com?** coder.ddev.com provides on-demand cloud workspaces running DDEV with: + - VS Code for Web (full IDE in the browser) - A terminal - Docker-in-Docker via Sysbox (full DDEV support, all project types) @@ -28,7 +29,7 @@ All members of the [ORG NAME] GitHub org can sign in. They do not need to be add **Questions or issues?** -- [DDEV Discord](https://discord.ddev.com) — `#coder-ddev-com` channel (or any channel) +- [DDEV Discord](https://ddev.com/s/discord) — `#coder-ddev-com` channel (or any channel) - [ddev/ddev issues](https://github.com/ddev/ddev/issues) Thank you for supporting DDEV! diff --git a/docs/admin/operations-guide.md b/docs/content/self-hosting/operations-guide.md similarity index 99% rename from docs/admin/operations-guide.md rename to docs/content/self-hosting/operations-guide.md index bc961ea..5582321 100644 --- a/docs/admin/operations-guide.md +++ b/docs/content/self-hosting/operations-guide.md @@ -17,6 +17,7 @@ Before deploying this template, ensure the following are in place: ### Docker Host Infrastructure - **Sysbox runtime installed** on all Coder agent nodes: + ```bash # Install prerequisites sudo apt-get install -y jq @@ -32,6 +33,7 @@ Before deploying this template, ensure the following are in place: sudo systemctl status sysbox -n20 sysbox-runc --version ``` + **Note:** Docker must be installed (not via snap) before installing Sysbox. The installer will restart Docker. See [Sysbox install docs](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/install-package.md) for details. - Docker configured to use Sysbox runtime for appropriate containers @@ -194,6 +196,7 @@ make build-and-push-no-cache && make push-template-freeform ### Creating Workspaces **Via Web UI:** + 1. Log into Coder dashboard 2. Click "Create Workspace" 3. Select "freeform" template @@ -202,6 +205,7 @@ make build-and-push-no-cache && make push-template-freeform 6. Click "Create Workspace" **Via CLI:** + ```bash # Create with defaults coder create --template freeform my-workspace --yes @@ -253,6 +257,7 @@ coder update my-workspace ``` **Notes:** + - Updates template configuration but NOT the Docker image - To update Docker image, workspace must be rebuilt (delete and recreate) - Updating preserves `/home/coder` volume @@ -347,6 +352,7 @@ coder templates push --directory freeform freeform --yes ### Workspace Data Backup Each workspace stores persistent data in: + - **Home directory**: `/coder-workspaces/-` on host - **Docker volume**: Named volume `coder---dind-cache` @@ -528,6 +534,7 @@ git log --oneline freeform/template.tf ### Monitoring **Check workspace health:** + ```bash # View workspace logs coder ssh my-workspace -- journalctl -u coder-agent -f @@ -541,6 +548,7 @@ coder ssh my-workspace -- ddev list ``` **Resource usage:** + ```bash # Check workspace container resources docker stats coder- @@ -575,11 +583,13 @@ coder ssh my-workspace -- systemctl status docker ### Sysbox Runtime Sysbox provides **secure nested containers** without privileged mode: + - No `--privileged` flag required - Isolated Docker daemon per workspace - AppArmor and seccomp profiles configured **Security profiles in template.tf:** + ```hcl security_opt = ["apparmor:unconfined", "seccomp:unconfined"] ``` @@ -636,7 +646,7 @@ Monitor resource usage and adjust template defaults accordingly. ### Documentation - Keep `AGENTS.md` updated for AI-assisted development -- Update user docs in `/docs/user/` when template changes +- Update the user docs in `docs/content/` when a template changes - Document breaking changes in git tags and release notes ## Additional Resources diff --git a/docs/content/self-hosting/overview.md b/docs/content/self-hosting/overview.md new file mode 100644 index 0000000..cac11f7 --- /dev/null +++ b/docs/content/self-hosting/overview.md @@ -0,0 +1,46 @@ +# Self-Hosting + +The rest of these docs describe the hosted service at coder.ddev.com. This section is for people who run the coder-ddev templates on their own [Coder](https://coder.com) server, and for the people who operate coder.ddev.com. + +## What you run + +- A **Coder server** (v2.13 or later) with a wildcard domain for workspace app URLs. +- One or more **Docker hosts with [Sysbox](https://github.com/nestybox/sysbox)**, so each workspace can run its own Docker daemon without privileged containers. +- The **workspace image** built from [`image/Dockerfile`](https://github.com/ddev/coder-ddev/tree/main/image) (published as `ddev/coder-ddev` on Docker Hub). +- One or more of the **templates** in the repository: [`freeform`](https://github.com/ddev/coder-ddev/tree/main/freeform), [`drupal-core`](https://github.com/ddev/coder-ddev/tree/main/drupal-core) and [`drupal-contrib`](https://github.com/ddev/coder-ddev/tree/main/drupal-contrib). + +```text +Coder server ── authentication, templates, workspace orchestration + │ + ▼ +Docker host (sysbox-runc) + └─ workspace container (one per workspace) + ├─ Docker daemon ── DDEV containers (web, db, router, add-ons) + ├─ VS Code for Web, Coder agent + └─ /home/coder (persistent) +``` + +## Guides + +- [Server setup](server-setup.md): installing Docker, Sysbox and Coder on a fresh server, and adding capacity. +- [Operations](operations-guide.md): building the image, pushing templates, versions, and workspace lifecycle cleanup. +- [User management](user-management.md): accounts, roles, GitHub organization access, tokens and quotas. +- [Troubleshooting](troubleshooting.md): server-side problems, debugging tools and recovery. + +## Template variables + +Settings that users can't change are template variables, set when the template is pushed (see the `Makefile`): + +| Variable | Default | Description | +| -------------------------- | --------------------------------- | ----------------------------------------------------------------------------------- | +| `workspace_image_registry` | `index.docker.io/ddev/coder-ddev` | Registry and repository of the workspace image | +| `image_version` | `v0.1` | Image tag; the Makefile passes the contents of the root `VERSION` file | +| `cpu` | `4` | CPU shares for each workspace | +| `memory` | `8` | Memory limit in GB for each workspace | +| `docker_gid` | `988` | GID of the `docker` group | +| `docker_registry_mirror` | (auto-detect) | Docker registry mirror for the workspaces' Docker daemons | +| `enable_adminer` | `false` | `freeform` only: add an **Adminer** app button for each project | + +## Contributing + +Developer and contributor guidance, including for AI agents, lives in the repository's [`AGENTS.md`](https://github.com/ddev/coder-ddev/blob/main/AGENTS.md). Changes are welcome as pull requests to [ddev/coder-ddev](https://github.com/ddev/coder-ddev). diff --git a/docs/admin/server-setup.md b/docs/content/self-hosting/server-setup.md similarity index 98% rename from docs/admin/server-setup.md rename to docs/content/self-hosting/server-setup.md index 0218e50..8d228e0 100644 --- a/docs/admin/server-setup.md +++ b/docs/content/self-hosting/server-setup.md @@ -5,6 +5,7 @@ This guide covers setting up a new Coder server with the DDEV template from scra ## Overview The full stack requires: + 1. Provisioning the server (Hetzner) — if starting from bare metal; skip if you already have a fresh Ubuntu 24.04 LTS or higher LTS install 2. Docker (non-snap) — for running workspace containers 3. Registry mirror — pull-through cache to speed up workspace starts and avoid Docker Hub rate limits @@ -33,9 +34,11 @@ The recommended layout uses LVM on the system disk and a plain ext4 partition on LVM means any of `root`, `var`, or `data` can be grown later with `lvextend -r`. Sizes above are deliberately generous for staging and scale up automatically on prod-sized disks because `data` claims the rest of the volume group. -> **Software RAID:** This guide uses `SWRAID 0` (no RAID) because the staging server has mismatched-purpose disks. For production with two matched disks, change to `SWRAID 1` with `SWRAIDLEVEL 1` and adjust the `PART` lines per Hetzner's installimage docs. RAID-1 across the system disk is recommended for prod; the second disk holding workspace files can be left out of the array if you intend to grow it independently. +!!! note "Software RAID" + This guide uses `SWRAID 0` (no RAID) because the staging server has mismatched-purpose disks. For production with two matched disks, change to `SWRAID 1` with `SWRAIDLEVEL 1` and adjust the `PART` lines per Hetzner's installimage docs. RAID-1 across the system disk is recommended for prod; the second disk holding workspace files can be left out of the array if you intend to grow it independently. -> **Boot mode:** Hetzner servers default to Legacy/BIOS boot, and Hetzner Robot does not expose a UEFI toggle when activating the rescue system. Switching to UEFI requires firmware-level access via vKVM or a support ticket. For most installs Legacy/BIOS is fine; this guide assumes it. If you do switch to UEFI, add `PART /boot/efi esp 256M` as the first partition. +!!! note "Boot mode" + Hetzner servers default to Legacy/BIOS boot, and Hetzner Robot does not expose a UEFI toggle when activating the rescue system. Switching to UEFI requires firmware-level access via vKVM or a support ticket. For most installs Legacy/BIOS is fine; this guide assumes it. If you do switch to UEFI, add `PART /boot/efi esp 256M` as the first partition. ### Activate the rescue system @@ -659,13 +662,15 @@ coder login https://coder.ddev.com The initial admin account must be created with username/password via the web UI (above). Once that's done, configure GitHub OAuth so all subsequent logins — including `coder login` from the CLI — can use GitHub instead. > **If you already have a duplicate account** (e.g. `rfay` password account and `rfay-wanderingortiz8` GitHub account): Coder does not support renaming users in the UI or reliably via the API. Fix it directly in PostgreSQL: +> > ```bash > sudo -u postgres psql coder -c "UPDATE users SET username='rfay' WHERE username='rfay-wanderingortiz8';" > sudo systemctl restart coder > ``` +> > You will also need to delete the original password account (`rfay`) first if it still exists, or rename it out of the way the same way. -**1. Create a GitHub OAuth App** +#### 1. Create a GitHub OAuth App Create the app under your **GitHub organization**, not your personal account — apps created under a personal account show "by \" on the authorization screen instead of "by \". Go to **github.com/organizations/ddev/settings/applications → New OAuth App** and fill in: @@ -716,7 +721,7 @@ CODER_OAUTH2_GITHUB_ALLOWED_ORGS=ddev,coder-ddev-com,tag1consulting,upsun,platfo > **Device Flow:** Do not set `CODER_OAUTH2_GITHUB_DEVICE_FLOW=true` when `CODER_OAUTH2_GITHUB_ALLOWED_ORGS` is set. Device flow routes all GitHub logins through a code-based flow that does not request `read:org` scope — org membership checks fail with a 403 and users cannot log in. -**3. Restart Coder** +## 3. Restart Coder ```bash sudo systemctl restart coder @@ -845,6 +850,7 @@ make deploy-all ``` This deploys three templates: + - **drupal-core** — automated Drupal core development environment; clones Drupal core, installs the site, and sets up the [amateescu/ddev-drupal-dev](https://github.com/amateescu/ddev-drupal-dev) add-on (see Step 10 for the recommended seed cache setup) - **drupal-contrib** — automated environment for developing Drupal contrib modules and themes; uses the [ddev/ddev-drupal-contrib](https://github.com/ddev/ddev-drupal-contrib) add-on, which installs Drupal as a dev dependency and symlinks the module/theme into the web root - **freeform** — multi-project workspace: keeps ddev-router running so multiple DDEV projects can coexist in one workspace, each reachable at its own hostname via Host-header routing @@ -1061,6 +1067,7 @@ sudo systemctl restart coder **User preferences** (per-user opt-in): Go to `https://coder.ddev.com/settings/notifications` and enable specific events. Some events (e.g. "Workspace Created") are disabled by default and must be explicitly enabled here — the deployment events page only sets the delivery method, not whether the event fires for you. Recommended events to enable: + - **User account created** — fires when any user signs up (admin-facing, enabled by default) - **Workspace Created** — fires when you or another user creates a workspace (must opt in at `/settings/notifications`) - **Workspace Deleted** — workspace removed @@ -1396,6 +1403,7 @@ sudo journalctl -u workspace-lifecycle-cleanup -q -n50 ## Troubleshooting **Coder service won't start:** + ```bash journalctl -u coder -n50 # Check CODER_ACCESS_URL is set and reachable @@ -1403,6 +1411,7 @@ journalctl -u coder -n50 ``` **Sysbox containers fail to start:** + ```bash sysbox-runc --version # Verify sysbox is installed sudo systemctl status sysbox # Check sysbox services are running @@ -1410,6 +1419,7 @@ docker info | grep -i runtime # Verify sysbox-runc appears as a runtime ``` **Workspaces can't reach Docker:** + ```bash # Inside a workspace docker ps # Should work if Sysbox is functioning diff --git a/docs/admin/troubleshooting.md b/docs/content/self-hosting/troubleshooting.md similarity index 96% rename from docs/admin/troubleshooting.md rename to docs/content/self-hosting/troubleshooting.md index 7904320..51c2a22 100644 --- a/docs/admin/troubleshooting.md +++ b/docs/content/self-hosting/troubleshooting.md @@ -21,6 +21,7 @@ This guide covers common issues with the DDEV Coder template and their solutions **Symptom:** `coder templates push` fails with validation error **Check:** + ```bash # Validate Terraform syntax cd freeform @@ -32,12 +33,14 @@ terraform fmt -check ``` **Common causes:** + - Invalid HCL syntax in `template.tf` - Missing required variables - Invalid Docker image reference - Registry authentication issues **Solution:** + ```bash # Fix syntax errors terraform fmt freeform/template.tf @@ -56,6 +59,7 @@ coder templates push --directory freeform freeform --yes --verbose **Symptom:** Users don't see template in Coder UI **Check:** + ```bash # List templates coder templates list @@ -68,6 +72,7 @@ coder users show --json | grep organization ``` **Solution:** + - Ensure template is deployed to user's organization - Verify user has "Member" role or higher - Check template access restrictions (Enterprise only) @@ -77,6 +82,7 @@ coder users show --json | grep organization **Symptom:** Workspace creation fails with "image pull error" **Check:** + ```bash # Test image pull locally docker pull ddev/coder-ddev:v0.1 @@ -89,6 +95,7 @@ grep workspace_image_registry freeform/template.tf ``` **Solution:** + ```bash # For private registries, configure template variables: coder create --template freeform my-workspace \ @@ -106,6 +113,7 @@ coder create --template freeform my-workspace \ **Symptom:** Workspace creation hangs, never reaches "Running" **Check:** + ```bash # View workspace logs coder logs my-workspace @@ -118,12 +126,14 @@ coder ssh my-workspace -- journalctl -u coder-agent -f ``` **Common causes:** + 1. **Startup script failure** - Check Coder agent logs: `coder logs my-workspace` 2. **Docker daemon not starting** - Check `/tmp/dockerd.log` 3. **Sysbox runtime missing** - Verify host has Sysbox installed 4. **Resource exhaustion** - Check host has available CPU/RAM **Solution:** + ```bash # Check startup logs (output goes to Coder agent logs) coder logs my-workspace @@ -147,11 +157,14 @@ df -h /coder-workspaces/ **Common issues:** -**Issue 1: chown fails** +#### Issue 1: chown fails + ```bash # Error: chown: cannot access '/home/coder': Permission denied ``` + **Solution:** Check volume mount in `template.tf`: + ```hcl volume { container_path = "/home/coder" @@ -159,21 +172,27 @@ volume { } ``` -**Issue 2: Docker daemon won't start** +## Issue 2: Docker daemon won't start + ```bash # Error: failed to start dockerd ``` + **Solution:** Check Sysbox runtime and security options: + ```hcl runtime = "sysbox-runc" security_opt = ["apparmor:unconfined", "seccomp:unconfined"] ``` -**Issue 3: DDEV not found** +## Issue 3: DDEV not found + ```bash # Error: ddev: command not found ``` + **Solution:** Rebuild Docker image with DDEV installed: + ```bash cd image docker build --no-cache -t ddev/coder-ddev:v0.1 . @@ -185,6 +204,7 @@ docker push ddev/coder-ddev:v0.1 **Symptom:** Previously working workspace fails to restart **Check:** + ```bash # Check workspace status coder show my-workspace @@ -197,6 +217,7 @@ docker ps -a | grep coder ``` **Solution:** + ```bash # Delete and recreate workspace coder delete my-workspace --yes @@ -213,6 +234,7 @@ docker restart coder- **Symptom:** `docker ps` fails inside workspace with "Cannot connect to Docker daemon" **Check:** + ```bash # Inside workspace coder ssh my-workspace @@ -232,7 +254,8 @@ systemctl status docker **Common causes:** -**Cause 1: Sysbox not installed on host** +## Cause 1: Sysbox not installed on host + ```bash # On Coder host sysbox-runc --version @@ -245,14 +268,16 @@ apt-get install -y jq ./sysbox-ce_${SYSBOX_VERSION}-0.linux_amd64.deb # Note: installer automatically restarts Docker ``` -**Cause 2: Container not using Sysbox runtime** +## Cause 2: Container not using Sysbox runtime + ```bash # Check template.tf grep runtime freeform/template.tf # Should be: runtime = "sysbox-runc" ``` -**Cause 3: Missing security profiles** +## Cause 3: Missing security profiles + ```bash # Check template.tf grep security_opt freeform/template.tf @@ -260,7 +285,8 @@ grep security_opt freeform/template.tf # security_opt = ["apparmor:unconfined", "seccomp:unconfined"] ``` -**Cause 4: Docker volume not mounted** +## Cause 4: Docker volume not mounted + ```bash # Check volume mount docker inspect coder- | grep "Destination.*docker" @@ -271,6 +297,7 @@ docker volume ls | grep dind-cache ``` **Solution:** + ```bash # Fix template.tf and redeploy coder templates push --directory freeform freeform --yes @@ -285,6 +312,7 @@ coder create --template freeform my-workspace --yes **Symptom:** Docker works initially but stops responding **Check:** + ```bash # Inside workspace journalctl -u docker -f @@ -300,6 +328,7 @@ cat /tmp/dockerd.log ``` **Solution:** + ```bash # To increase resources, delete and recreate workspace with higher memory # (Back up data first: coder ssh my-workspace -- tar -czf ~/backup.tar.gz ~/projects) @@ -318,6 +347,7 @@ sudo systemctl restart docker **Symptom:** `permission denied while trying to connect to Docker daemon` **Check:** + ```bash # Inside workspace groups # Should include "docker" @@ -326,6 +356,7 @@ getent group docker # Check GID ``` **Solution:** + ```bash # Check docker_gid in template.tf matches host # Default is 988 @@ -344,6 +375,7 @@ sudo usermod -aG docker $USER **Symptom:** `ddev start` fails or containers exit immediately **Check:** + ```bash # Inside workspace ddev start --debug @@ -361,20 +393,23 @@ docker ps -a | grep ddev **Common causes:** -**Cause 1: Docker daemon not running** +## Cause 1: Docker daemon not running + ```bash docker ps # If fails: systemctl status docker ``` -**Cause 2: Insufficient resources** +## Cause 2: Insufficient resources + ```bash docker stats free -h # Increase workspace memory/CPU if needed ``` -**Cause 3: Port conflicts** +## Cause 3: Port conflicts + ```bash ddev describe # Check for conflicting projects @@ -382,7 +417,8 @@ ddev list ddev stop --all ``` -**Cause 4: Corrupt DDEV project** +## Cause 4: Corrupt DDEV project + ```bash ddev delete --omit-snapshot rm -rf .ddev @@ -391,6 +427,7 @@ ddev start ``` **Solution:** + ```bash # Clean restart ddev poweroff @@ -407,6 +444,7 @@ ddev start **Symptom:** `ddev import-db` fails with memory or timeout errors **Check:** + ```bash # Check workspace resources docker stats @@ -419,6 +457,7 @@ df -h ``` **Solution:** + ```bash # To increase memory, delete and recreate workspace with higher memory # (Back up data first: ddev export-db --file=dump.sql.gz) @@ -438,6 +477,7 @@ ddev mysql < dump.sql **Symptom:** DDEV project URLs don't work **Check:** + ```bash # Check DDEV status ddev describe @@ -450,6 +490,7 @@ curl localhost:80 ``` **Solution:** + - Access via Coder port forwarding UI (not direct URLs) - Click on port links in Coder dashboard under "Apps" - DDEV URLs shown by `ddev describe` won't work directly @@ -462,6 +503,7 @@ curl localhost:80 **Symptom:** Files owned by root or wrong UID **Check:** + ```bash # Inside workspace ls -la /home/coder @@ -472,6 +514,7 @@ ls -la /coder-workspaces/- ``` **Solution:** + ```bash # Startup script should fix this automatically # If not, run manually: @@ -486,6 +529,7 @@ chown -R 1000:1000 /coder-workspaces/- **Symptom:** `sudo: command not found` or permission denied **Check:** + ```bash # Inside workspace which sudo @@ -495,6 +539,7 @@ groups **Solution:** Rebuild image with sudo configured: + ```dockerfile # In image/Dockerfile RUN echo "coder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/coder @@ -505,12 +550,14 @@ RUN echo "coder ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/coder **Symptom:** Permission denied writing to `/home/coder` **Check:** + ```bash ls -la /home/coder df /home/coder # Check if volume mounted ``` **Solution:** + ```bash # Fix ownership sudo chown -R coder:coder /home/coder @@ -530,6 +577,7 @@ sudo chown -R coder:coder /home/coder **Symptom:** Coder port forwarding shows ports but URLs don't work **Check:** + ```bash # Inside workspace ddev describe @@ -541,6 +589,7 @@ docker ps | grep ddev ``` **Solution:** + - Use Coder's port forwarding links (not DDEV's URLs) - Ensure DDEV is configured for Coder environment - Check `host_webserver_port` in `.ddev/global_config.yaml` @@ -550,6 +599,7 @@ docker ps | grep ddev **Symptom:** Port already in use errors **Check:** + ```bash # Inside workspace ddev list @@ -560,6 +610,7 @@ netstat -tlnp | grep :80 ``` **Solution:** + ```bash # Stop all DDEV projects ddev stop --all @@ -574,6 +625,7 @@ router_https_port: "8443" **Symptom:** VS Code can't forward ports from workspace **Check:** + ```bash # Verify service is listening netstat -tlnp | grep @@ -583,6 +635,7 @@ curl localhost: ``` **Solution:** + - Use Coder's port forwarding (not VS Code's) - Configure ports in `template.tf` `coder_app` resources - VS Code port forwarding may not work with Docker-in-Docker @@ -594,6 +647,7 @@ curl localhost: **Symptom:** VS Code app shows blank page or infinite loading **Check:** + ```bash # Check workspace is running coder list @@ -605,6 +659,7 @@ coder ssh my-workspace -- echo "Agent OK" ``` **Solution:** + - Refresh browser - Clear browser cache and cookies - Try different browser @@ -615,6 +670,7 @@ coder ssh my-workspace -- echo "Agent OK" **Symptom:** Extensions fail to install or don't work **Check:** + ```bash # Check disk space coder ssh my-workspace -- df -h @@ -624,8 +680,10 @@ coder ssh my-workspace -- df -h ``` **Solution:** + - Some extensions require desktop VS Code - Use SSH connection with desktop VS Code: + ```bash coder config-ssh # Then connect via VS Code Remote-SSH @@ -636,6 +694,7 @@ coder ssh my-workspace -- df -h **Symptom:** Terminal in VS Code doesn't work or has wrong shell **Check:** + ```bash # Inside workspace terminal echo $SHELL @@ -645,6 +704,7 @@ which bash zsh ``` **Solution:** + - Default shell is bash - Change in VS Code settings: `Terminal › Integrated › Default Profile: Linux` - Restart VS Code @@ -654,6 +714,7 @@ which bash zsh ### Workspace is Slow **Check:** + ```bash # Check resource usage docker stats coder- @@ -665,11 +726,13 @@ docker stats ``` **Causes:** + 1. **Insufficient resources** - Increase CPU/memory 2. **Disk I/O** - Check Docker volume performance 3. **Too many DDEV projects running** - Stop unused projects **Solution:** + ```bash # Increase resources coder update my-workspace \ @@ -689,6 +752,7 @@ docker system prune -a -f **Symptom:** `docker build` or DDEV builds take very long **Check:** + ```bash # Check Docker info docker info | grep "Storage Driver" @@ -699,6 +763,7 @@ rm /tmp/test ``` **Solution:** + - Increase workspace resources - Use Docker BuildKit: `DOCKER_BUILDKIT=1 docker build ...` - Use multi-stage builds to reduce layer count @@ -709,12 +774,14 @@ rm /tmp/test **Symptom:** DDEV project is slow (page loads, composer, npm) **Check:** + ```bash ddev describe docker stats $(docker ps -q --filter name=ddev) ``` **Solution:** + ```bash # To increase resources, delete and recreate workspace # (Back up data first: coder ssh my-workspace -- tar -czf ~/backup.tar.gz ~/projects) @@ -734,6 +801,7 @@ ddev xdebug off ### Viewing Logs **Workspace agent logs:** + ```bash # Via Coder CLI coder logs my-workspace @@ -746,17 +814,20 @@ journalctl -u coder-agent -f ``` **Startup script logs** (output goes to Coder agent logs): + ```bash coder logs my-workspace ``` **Docker daemon logs:** + ```bash coder ssh my-workspace -- cat /tmp/dockerd.log coder ssh my-workspace -- journalctl -u docker -f ``` **DDEV logs:** + ```bash coder ssh my-workspace -- ddev logs coder ssh my-workspace -- ddev logs db @@ -766,6 +837,7 @@ coder ssh my-workspace -- ddev logs web ### Interactive Debugging **SSH into workspace:** + ```bash # Open shell coder ssh my-workspace @@ -778,6 +850,7 @@ coder logs my-workspace ``` **Check workspace state:** + ```bash # Show workspace details coder show my-workspace @@ -791,6 +864,7 @@ docker volume inspect coder---dind-cache ``` **Test Docker inside workspace:** + ```bash coder ssh my-workspace -- docker ps coder ssh my-workspace -- docker info @@ -798,6 +872,7 @@ coder ssh my-workspace -- docker run hello-world ``` **Test DDEV:** + ```bash coder ssh my-workspace -- ddev version coder ssh my-workspace -- ddev list @@ -820,6 +895,7 @@ coder ssh my-workspace -- ddev describe ### Emergency Recovery **Workspace completely broken:** + ```bash # 1. Backup data if possible coder ssh my-workspace -- tar -czf ~/backup.tar.gz ~/projects @@ -837,6 +913,7 @@ coder ssh my-workspace -- tar -xzf ~/backup.tar.gz ``` **Docker daemon completely broken:** + ```bash # Inside workspace sudo systemctl stop docker @@ -849,6 +926,7 @@ coder restart my-workspace ``` **Host out of resources:** + ```bash # On Coder host docker system prune -a --volumes -f @@ -878,16 +956,19 @@ New server setups should configure containerd's root during initial setup — se When reporting issues, provide: 1. **Workspace details:** + ```bash coder show my-workspace ``` 2. **Logs:** + ```bash coder logs my-workspace > workspace-logs.txt ``` 3. **Template version:** + ```bash grep image_version freeform/template.tf cat VERSION @@ -907,7 +988,7 @@ When reporting issues, provide: - [Operations Guide](./operations-guide.md) - Template deployment - [User Management](./user-management.md) - User and permission issues -- [Coder Troubleshooting](https://coder.com/docs/guides/troubleshooting) - Official docs +- [Coder Troubleshooting](https://coder.com/docs/admin/monitoring) - Official docs - [Sysbox Troubleshooting](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/troubleshoot.md) - Sysbox-specific issues -- [DDEV Troubleshooting](https://docs.ddev.com/users/usage/troubleshooting/) - DDEV-specific issues +- [DDEV Troubleshooting](https://docs.ddev.com/en/stable/users/usage/troubleshooting/) - DDEV-specific issues - [GitHub Issues](https://github.com/ddev/coder-ddev/issues) - Report bugs or ask questions diff --git a/docs/admin/user-management.md b/docs/content/self-hosting/user-management.md similarity index 98% rename from docs/admin/user-management.md rename to docs/content/self-hosting/user-management.md index d036f14..dd0f4a1 100644 --- a/docs/admin/user-management.md +++ b/docs/content/self-hosting/user-management.md @@ -11,6 +11,7 @@ Coder uses a role-based access control (RBAC) system to manage users and their p ### Creating User Accounts **Via Web UI:** + 1. Log into Coder as admin 2. Navigate to **Users** section 3. Click **Create User** @@ -19,6 +20,7 @@ Coder uses a role-based access control (RBAC) system to manage users and their p 6. Click **Create** **Via CLI:** + ```bash # Create user coder users create @@ -41,6 +43,7 @@ Coder has three built-in roles: | **Member** | Create/manage own workspaces from allowed templates | Developers, users | **Assigning roles:** + ```bash # Set user roles coder users edit-roles --roles template-admin @@ -54,6 +57,7 @@ coder users edit-roles --roles member By default, all users can access all templates. **Organization-based access:** + - Create separate organizations for different teams - Deploy templates per organization - Users only see templates in their organization @@ -63,6 +67,7 @@ By default, all users can access all templates. **For organizations with SSO/OIDC:** Coder supports automatic user provisioning via: + - GitHub OAuth - Google Workspace - Okta @@ -123,6 +128,7 @@ Users need SSH keys for Git operations inside workspaces. 4. SSH key is automatically available in all workspaces **Or via CLI** (shows your Coder Git SSH public key): + ```bash coder publickey ``` @@ -139,6 +145,7 @@ git config --global core.sshCommand "$GIT_SSH_COMMAND" ``` Users can clone repositories using SSH: + ```bash git clone git@github.com:user/repo.git ``` @@ -146,6 +153,7 @@ git clone git@github.com:user/repo.git ### SSH Access to Workspaces **Users can SSH into their workspaces:** + ```bash # SSH into workspace coder ssh my-workspace @@ -158,6 +166,7 @@ coder port-forward my-workspace --tcp 8080:8080 ``` **Generate SSH config:** + ```bash # Add workspaces to ~/.ssh/config coder config-ssh @@ -173,6 +182,7 @@ Users need API tokens for CLI access and automation. ### Creating Tokens **Via Web UI:** + 1. Log into Coder 2. Go to **Account** → **Tokens** 3. Click **Create Token** @@ -180,6 +190,7 @@ Users need API tokens for CLI access and automation. 5. Copy token (shown once) **Via CLI:** + ```bash # Create token coder tokens create --name @@ -205,10 +216,12 @@ coder list ### Token Scopes Tokens inherit user's role permissions: + - **Member tokens**: Can create/manage own workspaces - **Admin tokens**: Can manage templates, users, all workspaces **Security best practices:** + - Set short expiration for automation tokens (30-90 days) - Use separate tokens per service/CI system - Rotate tokens regularly @@ -220,10 +233,10 @@ Tokens inherit user's role permissions: - Users **own** the workspaces they create - Only the owner (and admins) can: - - Stop/start workspace - - Delete workspace - - SSH into workspace - - View workspace logs + - Stop/start workspace + - Delete workspace + - SSH into workspace + - View workspace logs ### Sharing Workspaces @@ -231,21 +244,25 @@ Coder does not support workspace sharing out-of-the-box. **Workarounds for collaboration:** -**Option 1: VS Code Live Share** +#### Option 1: VS Code Live Share + - Install Live Share extension in workspace - Share session link with team members - Collaborators need VS Code (desktop or web) -**Option 2: Port Forwarding** +##### Option 2: Port Forwarding + - Expose DDEV project via Coder port forwarding - Share access URL with team members - Requires workspace to be running -**Option 3: Shared Workspaces (Manual)** +###### Option 3: Shared Workspaces (Manual) + - Create workspace for shared access - Share credentials with team (not recommended for production) -**Option 4: Project handoff** +###### Option 4: Project handoff + - Commit code to Git repository - Other user creates their own workspace - Clone the shared repository @@ -257,6 +274,7 @@ Coder does not support workspace sharing out-of-the-box. **Template-level defaults:** Edit `freeform/template.tf`: + ```hcl variable "cpu" { default = 4 @@ -280,10 +298,12 @@ variable "memory" { **Host-level disk quotas:** Each workspace uses: + - Home directory: `/coder-workspaces/-` - Docker volume: `coder---dind-cache` **Set filesystem quotas (Linux):** + ```bash # Enable quotas on host filesystem apt-get install quota @@ -294,6 +314,7 @@ setquota -u coder 50G 60G 0 0 /home ``` **Monitor disk usage:** + ```bash # Check workspace home directories du -sh /coder-workspaces/* @@ -307,6 +328,7 @@ docker system df -v | grep coder ### User Activity **View workspace activity:** + ```bash # List all workspaces with owners coder list --all @@ -321,6 +343,7 @@ coder logs ### Resource Usage **Per-workspace metrics:** + ```bash # Check running workspaces coder list --all @@ -331,6 +354,7 @@ coder ssh -- df -h ``` **Host-level monitoring:** + ```bash # Check all workspace containers docker ps | grep coder @@ -365,11 +389,13 @@ coder tokens remove ### Data Retention When deleting a user: + - Workspaces are **not** automatically deleted - Admins must manually delete user workspaces - Workspace data is removed on deletion (home directory + Docker volume) **Backup before deletion:** + ```bash # Backup user workspace data tar -czf user-backup.tar.gz /coder-workspaces/-* @@ -404,6 +430,7 @@ docker volume ls | grep coder- ### Onboarding Checklist For new users: + - [ ] Create user account (or SSO enabled) - [ ] Assign role (Member by default) - [ ] Add to organization (if applicable) @@ -416,6 +443,7 @@ For new users: ### Offboarding Checklist For departing users: + - [ ] List all user workspaces - [ ] Backup workspace data (if needed) - [ ] Delete all workspaces @@ -430,6 +458,7 @@ For departing users: ### User Can't Create Workspace **Check:** + - User has "Member" role or higher - Template is deployed to user's organization - Template is not restricted to specific users/groups @@ -446,6 +475,7 @@ coder templates list --org ### User Can't SSH into Workspace **Check:** + - Workspace is running: `coder list` - User owns workspace (or is admin) - Coder CLI is authenticated: `coder login ` @@ -462,6 +492,7 @@ coder show ### Git SSH Not Working **Check:** + - User has SSH key added to Coder account - Git host (GitHub, GitLab) has user's public key - `GIT_SSH_COMMAND` is set in workspace: `echo $GIT_SSH_COMMAND` @@ -478,6 +509,7 @@ coder ssh my-workspace -- coder gitssh --help ### Permission Denied Errors **Check:** + - User role and permissions: `coder users show ` - Template access restrictions: check Coder web UI under **Templates → Settings** - Organization membership: `coder organizations members list` diff --git a/docs/content/workspaces/ai-tools.md b/docs/content/workspaces/ai-tools.md new file mode 100644 index 0000000..419c9c7 --- /dev/null +++ b/docs/content/workspaces/ai-tools.md @@ -0,0 +1,43 @@ +# Claude Code + +Every workspace has [Claude Code](https://claude.com/claude-code) installed. You can use it three ways. + +## In a terminal + +Open a terminal in the workspace and run `claude` in your project directory. The first time, it asks you to log in. Your login is kept in your home directory, so it survives restarts. + +## Claude Code remote control + +Turn on **Enable Claude Code remote control** in the workspace's settings (all templates offer it) to drive Claude Code in the workspace from [claude.ai/code](https://claude.ai/code) or the Claude mobile app, even when no browser tab or terminal is open. + +1. Turn the setting on when creating the workspace, or later in **Settings → Parameters**, then restart. +2. **First use:** click the **Claude Code** app button on the workspace page (or SSH in) and complete the one-time Claude login and the workspace trust prompt. +3. The session then shows up on claude.ai/code under the workspace's name. + +To work in a particular project, `cd` into it in any terminal and run `claude-here`. That starts a new remote-control session in that directory, named after it, and the previous session stops appearing in claude.ai/code. + +- **Claude Code: skip permission prompts** runs Claude with `--dangerously-skip-permissions`. Only use it if you're comfortable with Claude running any command in the workspace without asking. +- Requires a Claude Pro, Max, Team or Enterprise subscription. API keys, Bedrock, Vertex and custom gateways are not supported. +- Remote sessions disconnect after about 10 minutes offline. + +## Claude Code self-hosted runner + +**Freeform only.** Turn on **Run a Claude Code self-hosted runner** to make the workspace a self-hosted environment for Claude Code on the web. Sessions you start on claude.ai/code in that environment then run in this workspace, with its Docker and DDEV. + +One-time setup: + +1. On claude.ai, create a self-hosted environment and copy its environment secret. +2. In the workspace, save it: + + ```bash + mkdir -p ~/.claude-runner + cat > ~/.claude-runner/environment-secret # paste, press Enter, then Ctrl-D + chmod 600 ~/.claude-runner/environment-secret + ``` + +3. Restart the workspace. + +On every start, the runner runs in the `tmux` session `claude-runner` (`tmux attach -t claude-runner`), logging to `/tmp/claude-runner-.log`. Sessions clone their repositories under `~/workspace/runner-`. Run `claude-sessions` to list live sessions with their checkout, branch and number of unpushed commits. + +- **Use a workspace only for the runner.** The runner rewrites `~/.gitconfig` and `~/.config/git` before every session. It can't be turned on together with remote control. +- **Concurrent sessions** (1 to 4) sets how many sessions run at once. They share the workspace's Docker daemon and DDEV, and a skill installed in `~/.claude/skills/coder-shared-workspace` tells them how to stay out of each other's way. For full isolation, use several workspaces with one session each; the same environment secret works in all of them. diff --git a/docs/content/workspaces/editors-and-ssh.md b/docs/content/workspaces/editors-and-ssh.md new file mode 100644 index 0000000..fd550c9 --- /dev/null +++ b/docs/content/workspaces/editors-and-ssh.md @@ -0,0 +1,85 @@ +# Editors, SSH and Files + +## VS Code for Web + +Click **VS Code** on the workspace page. It opens in the directory named after the workspace (`~/`), with a built-in terminal (**Terminal → New Terminal**). Extensions you install from the Extensions view persist across restarts. The extensions installed by default are chosen with the **VS Code Extensions** setting; see [Creating a workspace](../freeform/create.md#vs-code-extensions). + +## Set up the Coder CLI + +Everything else on this page uses the [Coder CLI](https://coder.com/docs/install/cli) on your computer: + +```bash +coder login https://coder.ddev.com +coder config-ssh --yes +``` + +`coder config-ssh` adds an entry to your `~/.ssh/config` for each of your workspaces, named `.coder`. Run it again after creating a new workspace. + +## SSH + +```bash +coder ssh my-workspace # or: ssh my-workspace.coder +coder ssh -A my-workspace # forward your local SSH agent (see below) +``` + +## Desktop editors + +- **VS Code**: install the [Coder extension](https://marketplace.visualstudio.com/items?itemName=coder.coder-remote), or use the Remote - SSH extension and connect to `my-workspace.coder`. +- **JetBrains IDEs** (PhpStorm and others): use [JetBrains Toolbox with the Coder plugin](https://coder.com/docs/user-guides/workspace-access/jetbrains), or JetBrains Gateway over SSH to `my-workspace.coder`. +- **Any SSH-capable editor** works the same way, with `my-workspace.coder` as the host. + +## Copying files + +After `coder config-ssh`, use `scp` or `rsync` with the `.coder` host name: + +```bash +# Upload a database dump, then import it +scp ~/Downloads/dump.sql.gz my-workspace.coder:~/my-site/ +coder ssh my-workspace -- env -C /home/coder/my-site ddev import-db --file=dump.sql.gz + +# Download a file +scp my-workspace.coder:~/my-site/backup.sql.gz . + +# Sync a directory +rsync -av ./files/ my-workspace.coder:~/my-site/web/sites/default/files/ +``` + +For small files, you can also drag them into the VS Code for Web file explorer, or right-click a file there and choose **Download**. + +## Forwarding ports to your computer + +```bash +coder port-forward my-workspace --tcp 3306: +``` + +This makes a port in the workspace available as `localhost` on your computer, for example for a desktop database client. See [Database tools](../freeform/services.md#database-tools). + +## Git and SSH keys + +Coder creates an SSH key for your account, and Git in every workspace uses it automatically. Add its public key to your Git host once: + +1. Copy the public key from [your account's SSH keys page](https://coder.ddev.com/settings/ssh-keys), or run `coder publickey` on your computer. +2. Add it to [GitHub](https://github.com/settings/keys), [GitLab](https://gitlab.com/-/user_settings/ssh_keys), [drupal.org](https://www.drupal.org/user) (**SSH keys** tab on your profile) or any other host. +3. Test it in the workspace: `ssh -T git@github.com`. + +Set your Git identity once; it's stored in your home directory and persists: + +```bash +git config --global user.name "Your Name" +git config --global user.email "you@example.com" +``` + +### SSH keys inside DDEV containers + +DDEV's containers can use the same keys, for example for `ddev composer install` with private repositories, or for Drush aliases. Nothing needs setting up and you don't need `ddev auth ssh`: + +```bash +ddev exec ssh -T git@github.com +``` + +The workspace relays DDEV's SSH agent to the best available agent, in this order: + +1. **Your own agent, when it is forwarded**: by desktop VS Code, or by `coder ssh -A`. This lets you use keys from your computer or a password manager such as 1Password. +2. **Your Coder key** otherwise. + +The most recent terminal or session that forwards an agent wins, for the whole workspace. While an agent is forwarded, any container on the DDEV network can ask it to sign, so an agent that confirms each use is safer. diff --git a/docs/user/using-workspaces.md b/docs/content/workspaces/guide.md similarity index 95% rename from docs/user/using-workspaces.md rename to docs/content/workspaces/guide.md index cb1d652..92b9155 100644 --- a/docs/user/using-workspaces.md +++ b/docs/content/workspaces/guide.md @@ -1,6 +1,9 @@ -# Using DDEV Coder Workspaces +# Detailed Workspace Guide -This guide covers daily workflows, tips, and best practices for working with DDEV in Coder workspaces. +This guide covers daily workflows, tips, and best practices for working with DDEV in Coder workspaces in more depth than the other pages in this section. + +!!! note "Being reorganized" + Parts of this guide are being moved into the shorter pages in this section: [Workspace lifecycle](lifecycle.md), [Editors, SSH and files](editors-and-ssh.md), [Claude Code](ai-tools.md) and [Troubleshooting](troubleshooting.md). Where they disagree, those pages are current. ## Table of Contents @@ -21,15 +24,18 @@ This guide covers daily workflows, tips, and best practices for working with DDE Your workspace has two types of storage: **Persistent (survives stop/restart):** + - `/home/coder` directory (all your files) - Docker volumes (DDEV databases, images, containers) **Non-persistent (reset on restart):** + - Running processes - Temporary files in `/tmp` - System packages installed with `apt-get` (unless in Docker image) **What this means:** + - Your code, databases, and DDEV projects are safe when stopping workspace - You need to restart DDEV projects after workspace restart - System-level changes (installed packages) are lost unless in Docker image @@ -140,6 +146,7 @@ for ws in my-first-workspace my-second-workspace; do coder stop "$ws"; done ``` **Use cases for multiple workspaces:** + - Different projects with different requirements - Testing configurations without affecting main workspace - Separate staging and development environments @@ -150,11 +157,13 @@ for ws in my-first-workspace my-second-workspace; do coder stop "$ws"; done ### Accessing VS Code **From Coder dashboard:** + 1. Find your workspace 2. Click **VS Code** under "Apps" 3. VS Code opens in new tab **Direct URL** (bookmark this): + ``` https://coder.example.com/@me/my-workspace/apps/code ``` @@ -180,6 +189,7 @@ All workspaces come with these extensions automatically installed at workspace s Extensions are installed from the **[Open VSX Registry](https://open-vsx.org/)** — the open-source alternative to the Microsoft Marketplace used by VS Code Server and other non-Microsoft VS Code deployments. **To install an extension manually:** + 1. Open Extensions panel (`Ctrl+Shift+X`) 2. Search for the extension by name 3. Click Install @@ -190,7 +200,7 @@ If an extension you need is missing, check if it exists on [open-vsx.org](https: ### Adding Extensions to All Workspaces -Admins can pre-install additional extensions for all users by adding extension IDs to the `extensions` list in the template's `vscode-web` module. See the [server setup guide](../admin/server-setup.md) for details. +Admins can pre-install additional extensions for all users by adding extension IDs to the `extensions` list in the template's `vscode-web` module. See the [server setup guide](../self-hosting/server-setup.md) for details. ### Future IDE Possibilities @@ -203,15 +213,18 @@ The current setup uses **VS Code for Web** (browser-based VS Code Server). Other ### Terminal in VS Code **Open terminal:** + - Menu: Terminal → New Terminal - Keyboard: Ctrl+` (backtick) **Multiple terminals:** + - Click `+` to add terminal - Split terminal with split button - Switch between terminals with dropdown **Terminal tips:** + ```bash # Terminal opens in /home/coder by default # Navigate to project @@ -229,15 +242,18 @@ ddev npm run dev ### File Management **Opening projects:** + 1. File → Open Folder 2. Navigate to `~/projects/my-site` 3. Click **OK** **Drag and drop:** + - Drag files from your computer into VS Code to upload - Works for single files and folders (up to reasonable size) **File search:** + - **Ctrl+P** (Cmd+P): Quick file open - **Ctrl+Shift+F** (Cmd+Shift+F): Search in files - **Ctrl+Shift+E** (Cmd+Shift+E): File explorer @@ -245,6 +261,7 @@ ddev npm run dev ### Git Integration **Built-in Git features:** + - **Source Control** panel (Ctrl+Shift+G) - Stage changes (click `+` next to file) - Commit (type message, click ✓) @@ -252,6 +269,7 @@ ddev npm run dev - View diff (click modified file) **GitLens extension features:** + - Blame annotations (who changed each line) - Commit history - Repository explorer @@ -271,12 +289,14 @@ ddev xdebug off # Disable when done (improves performance) ``` Then in VS Code: + 1. Add a breakpoint (click left of line number — should appear solid red) 2. Press **F5** → select "Listen for Xdebug" 3. Refresh your browser to trigger the breakpoint 4. The bottom bar turns orange when the debug session is active **Node.js:** + ```json // .vscode/launch.json { @@ -294,15 +314,19 @@ Press **F5** to start debugging. Beyond the pre-installed set, these are useful additions for specific project types (search Open VSX by name): **Drupal:** + - Drupal Smart Snippets **WordPress:** + - WordPress Snippets **Laravel:** + - Laravel Blade Snippets **Node.js:** + - npm Intellisense - ES7+ React/Redux/React-Native snippets @@ -326,6 +350,7 @@ Beyond the pre-installed set, these are useful additions for specific project ty DDEV supports 20+ project types. Common examples: **WordPress:** + ```bash mkdir ~/projects/my-wordpress cd ~/projects/my-wordpress @@ -335,6 +360,7 @@ ddev composer create roots/bedrock ``` **Drupal:** + ```bash mkdir ~/projects/my-drupal cd ~/projects/my-drupal @@ -344,6 +370,7 @@ ddev drush site:install --account-name=admin --account-pass=admin -y ``` **Laravel:** + ```bash mkdir ~/projects/my-laravel cd ~/projects/my-laravel @@ -353,6 +380,7 @@ ddev exec php artisan key:generate ``` **Generic PHP:** + ```bash mkdir ~/projects/my-php-site cd ~/projects/my-php-site @@ -363,6 +391,7 @@ ddev start ``` **Node.js:** + ```bash mkdir ~/projects/my-node-app cd ~/projects/my-node-app @@ -377,6 +406,7 @@ ddev exec node server.js ### Database Management **Import database:** + ```bash # From SQL file ddev import-db --file=dump.sql @@ -389,6 +419,7 @@ ddev import-db --url=https://example.com/dump.sql.gz ``` **Export database:** + ```bash # Export to file ddev export-db --file=dump.sql.gz @@ -398,6 +429,7 @@ ddev export-db > dump.sql ``` **Direct MySQL access:** + ```bash # MySQL CLI ddev mysql @@ -410,6 +442,7 @@ ddev mysql -e "SELECT * FROM users LIMIT 10;" ``` **Database GUI** (via browser): + ```bash # phpMyAdmin (if configured in .ddev/config.yaml) ddev launch -p @@ -422,6 +455,7 @@ coder port-forward my-workspace --tcp 3306:3306 ### Running Commands **Execute commands in web container:** + ```bash # Generic command ddev exec @@ -436,6 +470,7 @@ ddev exec sudo ``` **SSH into web container:** + ```bash ddev ssh @@ -447,6 +482,7 @@ exit ``` **Composer commands:** + ```bash ddev composer install ddev composer require vendor/package @@ -455,6 +491,7 @@ ddev composer dump-autoload ``` **npm/yarn commands:** + ```bash ddev npm install ddev npm run dev @@ -466,6 +503,7 @@ ddev yarn build ### Custom Commands **Create custom DDEV commands:** + ```bash # Create .ddev/commands/web/ directory mkdir -p .ddev/commands/web @@ -488,6 +526,7 @@ ddev mycommand ### Multiple Projects **Running multiple DDEV projects:** + ```bash # Start all projects cd ~/projects/project1 && ddev start @@ -510,6 +549,7 @@ ddev poweroff **Port conflicts:** If you run multiple projects simultaneously, they'll use different ports automatically. Check with: + ```bash ddev describe # Shows URLs and ports for each project @@ -539,6 +579,7 @@ git config --global alias.ci commit **Your SSH key is managed by Coder** and automatically available in workspaces. **Get your Coder public key:** + ```bash # Inside workspace coder publickey @@ -547,11 +588,13 @@ coder publickey ``` **Add key to your Git host:** -1. **GitHub**: https://github.com/settings/keys → New SSH key -2. **GitLab**: https://gitlab.com/-/profile/keys → Add key -3. **Bitbucket**: https://bitbucket.org/account/settings/ssh-keys/ → Add key + +1. **GitHub**: → New SSH key +2. **GitLab**: → Add key +3. **Bitbucket**: → Add key **Test SSH:** + ```bash # Test GitHub ssh -T git@github.com @@ -589,6 +632,7 @@ Notes: ### Common Workflows **Clone and start working:** + ```bash cd ~/projects git clone git@github.com:username/repo.git @@ -598,6 +642,7 @@ ddev start ``` **Daily workflow:** + ```bash # Pull latest changes git pull @@ -622,6 +667,7 @@ git push origin feature/my-feature ``` **Stash changes:** + ```bash # Stash uncommitted changes git stash @@ -634,6 +680,7 @@ git stash pop ``` **Merge conflicts:** + ```bash # If pull creates conflicts git pull @@ -678,11 +725,13 @@ In Coder, you **don't** access services via direct URLs. Instead: 3. You access via Coder's secure URL **Traditional DDEV:** + ``` https://my-site.ddev.site ← Doesn't work in Coder ``` **Coder DDEV:** + ``` https://ddev-web--workspace-name--owner.coder.example.com/ ← Use DDEV Web app URL ``` @@ -690,6 +739,7 @@ https://ddev-web--workspace-name--owner.coder.example.com/ ← Use DDEV Web app ### Accessing DDEV Projects **Via Coder UI (Recommended):** + 1. Go to workspace in Coder dashboard 2. Under **Apps**, click **DDEV Web** 3. Your DDEV project loads in a new tab @@ -697,6 +747,7 @@ https://ddev-web--workspace-name--owner.coder.example.com/ ← Use DDEV Web app The URL follows the pattern: `https://ddev-web--workspace-name--owner.domain/` **Common DDEV ports:** + - **80**: HTTP web server - **443**: HTTPS web server - **8025**: Mailpit web UI (email testing) @@ -737,18 +788,20 @@ coder port-forward my-workspace --tcp 3000:3000 You can share a running workspace with another user for pair programming or review. The recipient gets a live view of your workspace in their browser — same URL, same running site. **Via the web UI:** + 1. Open your workspace in the Coder dashboard 2. Click **Share** in the top-right corner 3. Enter the Coder username to share with and set the permission level 4. Send them the workspace URL **Via the CLI:** + ```bash -# Share with another user (specify role: view or admin) +# Share with another user (specify role: use or admin) coder sharing add / --user : # Example -coder sharing add rfay/issue-3453474 --user stasadev:view +coder sharing add rfay/issue-3453474 --user stasadev:use # List current shares coder sharing status rfay/issue-3453474 @@ -768,12 +821,14 @@ Admins can access any workspace on the server — useful for debugging or suppor You can share a specific port (e.g., a site you're working on) without sharing the full workspace: **Via the web UI:** + 1. Open your workspace 2. Click **Open ports** (top right of the agent section) 3. Click the share icon next to the port you want to expose 4. Set visibility: **Owner** (private), **Authenticated** (any logged-in user), or **Public** (anyone with the URL) **Via the CLI** (forward a port to your local machine): + ```bash coder port-forward --tcp 8080:8080 ``` @@ -785,6 +840,7 @@ Port visibility (public/authenticated/owner) is managed via the Coder web UI das ### Importing Existing Projects **From Git repository:** + ```bash cd ~/projects git clone git@github.com:username/existing-project.git @@ -796,6 +852,7 @@ ddev import-db --file=backup.sql.gz ``` **From local machine:** + ```bash # Option 1: Via VS Code drag-and-drop # Open VS Code, drag project folder into file explorer @@ -826,6 +883,7 @@ ddev snapshot --cleanup ``` **Use case:** Before risky database changes: + ```bash ddev snapshot # Try risky migration @@ -837,6 +895,7 @@ ddev snapshot restore ### File Sync and Backup **Download files from workspace** (requires `coder config-ssh`): + ```bash # Via SCP scp -r my-workspace.coder:~/projects/my-site ./local-backup/ @@ -846,6 +905,7 @@ scp -r my-workspace.coder:~/projects/my-site ./local-backup/ ``` **Upload files to workspace** (requires `coder config-ssh`): + ```bash # Via SCP scp -r ./local-files my-workspace.coder:~/projects/my-site/ @@ -854,6 +914,7 @@ scp -r ./local-files my-workspace.coder:~/projects/my-site/ ``` **Backup entire project:** + ```bash # Inside workspace cd ~/projects @@ -867,6 +928,7 @@ scp my-workspace.coder:~/projects/my-site-backup.tar.gz ./ ### Package Management **Composer (PHP):** + ```bash ddev composer install # Install dependencies ddev composer require pkg/name # Add package @@ -875,6 +937,7 @@ ddev composer dump-autoload # Rebuild autoloader ``` **npm (Node.js):** + ```bash ddev npm install # Install dependencies ddev npm install package # Add package @@ -883,6 +946,7 @@ ddev npm run