Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/drupal-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ jobs:

- &verify-webroot
name: Verify workspace — web root exists
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/web/index.php
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/index.php

- &verify-drush
name: Verify workspace — Drush DB connected
Expand Down Expand Up @@ -366,11 +366,11 @@ jobs:
run: coder ssh ${{ env.WORKSPACE_NAME }} -- ddev --version

- name: Verify workspace — web root exists
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/web/index.php
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/index.php

- name: Verify workspace — issue branch checked out
run: |
CURRENT=$(coder ssh ${{ env.WORKSPACE_NAME }} -- git -C /home/coder/drupal-core/repos/drupal branch --show-current | tr -d '\r\n')
CURRENT=$(coder ssh ${{ env.WORKSPACE_NAME }} -- git -C /home/coder/drupal-core branch --show-current | tr -d '\r\n')
echo "Current branch: $CURRENT Expected: ${{ env.ISSUE_BRANCH }}"
[[ "$CURRENT" == "${{ env.ISSUE_BRANCH }}" ]] || { echo "ERROR: wrong branch" >&2; exit 1; }

Expand Down Expand Up @@ -514,11 +514,11 @@ jobs:
run: coder ssh ${{ env.WORKSPACE_NAME }} -- ddev --version

- name: Verify workspace — web root exists
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/web/index.php
run: coder ssh ${{ env.WORKSPACE_NAME }} -- test -f /home/coder/drupal-core/index.php

- name: Verify workspace — issue branch checked out
run: |
CURRENT=$(coder ssh ${{ env.WORKSPACE_NAME }} -- git -C /home/coder/drupal-core/repos/drupal branch --show-current | tr -d '\r\n')
CURRENT=$(coder ssh ${{ env.WORKSPACE_NAME }} -- git -C /home/coder/drupal-core branch --show-current | tr -d '\r\n')
echo "Current branch: $CURRENT Expected: ${{ env.ISSUE_BRANCH }}"
[[ "$CURRENT" == "${{ env.ISSUE_BRANCH }}" ]] || { echo "ERROR: wrong branch" >&2; exit 1; }

Expand Down
102 changes: 48 additions & 54 deletions docs/admin/server-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -855,51 +855,21 @@ This deploys three templates:

## Step 10: Set Up the Drupal Core Seed Cache (optional, highly recommended)

The `drupal-core` template can provision a Drupal core development environment faster on new workspaces using a **seed cache** on the host. Without the cache, first-time workspace setup downloads a full git clone and all composer dependencies (~10-13 minutes). With the cache, the composer install phase is nearly instant; total workspace startup is 3-5 minutes (the remaining time is the Drupal site install, which always runs fresh).
The `drupal-core` template can provision workspaces faster using a **seed cache** on the host. The cache is a plain git clone of drupal/drupal. New workspaces pass it as a `--reference` hint to `git clone`, reusing local git objects and avoiding several hundred MB of network transfer. Composer install still runs fresh inside each workspace.

The cache is a standing DDEV project on the host that is periodically refreshed. New workspaces copy the git checkout and vendor directory from it. The database is always installed fresh via `ddev drush si` — this avoids schema-drift reliability problems with pre-built DB snapshots.

### Prerequisites

DDEV must be installed on the Coder server itself (not just inside workspaces). The host DDEV project runs on the host Docker daemon, separate from the Sysbox workspace containers.

Follow the [DDEV Linux installation instructions](https://docs.ddev.com/en/stable/users/install/ddev-installation/#ddev-installation-linux) to install DDEV on the host.

> **User note:** The seed cache must be owned and operated by a normal (non-root) user. DDEV refuses to run as root. All the commands below, and the systemd service, must run as that user — not with `sudo`.
The database is always installed fresh via `ddev drush si`.

### One-time initial setup

Run these commands as your normal (non-root) user — **not** as root:

```bash
mkdir -p ~/cache/drupal-core-seed
cd ~/cache/drupal-core-seed

# Configure DDEV project
ddev config --project-type=drupal12 --php-version=8.5 --docroot=web \
--project-name=drupal-core-seed
ddev start

# Create the full drupal-core development project (takes 5-10 minutes)
ddev composer create-project joachim-n/drupal-core-development-project --no-interaction

# Add Drush
ddev composer require drush/drush
git clone https://git.drupalcode.org/project/drupal.git ~/cache/drupal-core-seed
```

After this runs, the seed directory contains:

| Path | Contents |
|------|----------|
| `composer.json` / `composer.lock` | Project definition |
| `repos/drupal/` | Git clone of Drupal core |
| `vendor/` | All Composer packages |
| `web/` | Docroot (symlinked) |
| `.ddev/` | Host DDEV config — **not** copied to workspaces |
The seed directory IS the git clone — no subdirectory nesting. No DDEV, no vendor, no composer files.

### Install the hourly update timer

The update script runs `composer update` to keep the cache current with Drupal HEAD. Install it as an hourly systemd timer:
The update script runs `git fetch --all --prune` to keep the cache current. Install it as an hourly systemd timer:

```bash
REPO=~/workspace/coder-ddev # adjust if your repo is elsewhere
Expand Down Expand Up @@ -929,8 +899,6 @@ systemctl list-timers drupal-cache-updater.timer

### Manual refresh

Run an update at any time (e.g. after a major Drupal release):

```bash
/usr/local/bin/update-drupal-cache

Expand All @@ -942,6 +910,38 @@ sudo systemctl start drupal-cache-updater.service
journalctl -u drupal-cache-updater.service -f
```

### Migrating from the old joachim-n cache structure

If your server has an existing seed cache built with `joachim-n/drupal-core-development-project`, the startup script now checks for `.git` at the seed root — not inside `repos/drupal/`. New workspaces will fall back to a direct clone (slower) until migration is complete.

Run these steps on each server:

```bash
SEED_DIR=~/cache/drupal-core-seed
REPO=~/workspace/coder-ddev

# 1. Stop the old DDEV seed project
cd "$SEED_DIR" && ddev stop --remove-data 2>/dev/null || true

# 2. Move the git clone to the seed root, remove everything else
mv "$SEED_DIR/repos/drupal" /tmp/drupal-git-tmp
rm -rf "$SEED_DIR"
mv /tmp/drupal-git-tmp "$SEED_DIR"

# 3. Install the updated update script and service
sudo install -m 755 $REPO/drupal-core/scripts/update-drupal-cache \
/usr/local/bin/update-drupal-cache
sudo install -m 644 $REPO/drupal-core/scripts/drupal-cache-updater.service \
/etc/systemd/system/
sudo systemctl daemon-reload

# 4. Verify it works
sudo systemctl start drupal-cache-updater.service
journalctl -u drupal-cache-updater.service --no-pager | tail -10
```

After migration, `~/cache/drupal-core-seed` is the git clone itself — `.git` is at the root.

### Template variable

The template uses a `cache_path` variable for the host-side seed directory. The `Makefile` defaults `DRUPAL_CACHE_PATH` to `~/cache/drupal-core-seed` (resolved to the home directory of whoever runs `make`), so `make push-template-drupal-core` works without any override as long as your seed directory is at that path.
Expand All @@ -956,33 +956,27 @@ make push-template-drupal-core DRUPAL_CACHE_PATH=/your/cache/path

When a workspace starts for the first time:

1. The startup script checks for a valid seed at `/home/coder-cache-seed` (the read-only bind mount of `cache_path`)
2. **Cache hit:** `rsync` copies the project files (excluding `.ddev/`), `ddev composer install` ensures vendor is current (near-instant with vendor already present), then `ddev drush si` installs Drupal fresh (~2-3 min)
3. **Cache miss** (path absent or incomplete): falls back to full `ddev composer create-project` + `ddev drush si` — slower but always works

The database is always installed fresh — there is no pre-built DB snapshot. This avoids schema-drift failures that occurred when the cached DB became stale relative to Drupal HEAD.
1. The startup script checks for `.git` at `/home/coder-cache-seed` (the read-only bind mount of `cache_path`)
2. **Cache hit:** `git clone --reference` reuses local git objects for the initial clone (fast), then `ddev composer install` runs fresh inside the container
3. **Cache miss** (path absent or no `.git` at root): `git clone` runs without a reference — slower but always works

Check workspace startup logs in the Coder dashboard or at `/tmp/drupal-setup.log` inside the workspace to confirm which path was taken.

### Troubleshooting

**Cache not being used:**

- Verify the seed directory exists and is populated: `ls $SEED_DIR/composer.json $SEED_DIR/vendor`
- Confirm `cache_path` in the deployed template matches your actual seed directory (check with `coder templates versions list drupal-core`)
- Check the workspace startup log for the "Cache mount check" diagnostic block — it shows exactly which files were found or missing at the bind mount path
- Look for "Cache hit" in the log; "No cache available" means the path is absent or the seed was never initialized

**Seed project won't start after server reboot:**
```bash
cd ~/cache/drupal-core-seed && ddev start
```
- Verify the seed directory is a git clone: `ls ~/cache/drupal-core-seed/.git`
- Confirm `cache_path` in the deployed template matches your actual seed directory
- Look for "with reference from cache seed" in `/tmp/drupal-setup.log`; absence means the path was missing or `.git` was not at the root

**Update script fails:**

```bash
cd ~/cache/drupal-core-seed
ddev describe # verify DDEV is running
ddev logs # check container logs for errors
git -C ~/cache/drupal-core-seed fetch --all --prune
# If this fails, check network connectivity or re-clone:
rm -rf ~/cache/drupal-core-seed
git clone https://git.drupalcode.org/project/drupal.git ~/cache/drupal-core-seed
```

---
Expand Down
30 changes: 16 additions & 14 deletions docs/user/quickstart.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Quickstart: Drupal Core Development on coder.ddev.com

Cloud-hosted DDEV workspaces for Drupal core development. Full environment — Drupal core clone, running site, drush — ready in about a minute.
Cloud-hosted DDEV workspaces for Drupal core development. Full environment — Drupal core clone, running site, drush — ready in about five minutes.

[![Open in Coder](https://coder.ddev.com/open-in-coder.svg)](https://coder.ddev.com/templates/coder/drupal-core/workspace?mode=manual)

Expand All @@ -16,7 +16,7 @@ Go to **[coder.ddev.com](https://coder.ddev.com)** and sign in with GitHub.

Click the button above, or go to **Create Workspace** → select the **drupal-core** template → click **Create Workspace**.

Wait about a minute for the startup script to complete. Watch progress in the **Logs** tab.
Wait about five minutes for the startup script to complete. Watch progress in the **Logs** tab.

---

Expand All @@ -31,15 +31,14 @@ The running site has the Umami demo profile installed. Admin credentials: `admin
## Code layout

```
~/drupal-core/
├── repos/drupal/ # Drupal core git clone — edit files here
│ └── core/
├── web/ # Web docroot (core/ symlinked from repos/drupal/)
├── .ddev/ # DDEV config
└── vendor/ # Composer-managed dependencies
~/drupal-core/ # Drupal core git clone — edit files here
├── core/ # Drupal core source
├── index.php # Entry point
├── .ddev/ # DDEV config
└── composer.local.json # Local dependencies (drush, dev modules)
```

Make your changes in `repos/drupal/` — they are immediately reflected in the running site.
Edit files directly in `~/drupal-core/` — changes are immediately reflected in the running site.

---

Expand All @@ -52,8 +51,11 @@ ddev drush uli
# Clear cache
ddev drush cr

# Run Drupal tests (from repos/drupal/)
ddev exec phpunit web/core/tests/...
# Run Drupal tests (provided by ddev-drupal-dev add-on)
ddev phpunit core/modules/node

# Install a contrib module for development
ddev add-module token

# Open the site in your browser
ddev launch
Expand All @@ -77,7 +79,7 @@ When working on an issue, the workspace surfaces issue info in several places:
To push your changes back:

```bash
cd ~/drupal-core/repos/drupal
cd ~/drupal-core

# ... make changes ...

Expand All @@ -93,7 +95,7 @@ If you prefer to set up manually:

```bash
# In the workspace terminal:
cd ~/drupal-core/repos/drupal
cd ~/drupal-core

# Create a branch
git checkout -b my-fix
Expand Down Expand Up @@ -132,4 +134,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)
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)
Loading