Skip to content

Goal: your Acquia-hosted Drupal site running at a local URL, populated with a real environment’s database and files.

  • DDEV running the site locally in containers: PHP, database, and web server, none of them installed on your machine directly.
  • The code cloned from your application’s repository, and the database and files pulled from its dev environment.
  • A repeatable one-command refresh (ddev pull acquia) for every time your local data goes stale.

This works the same whether your site renders its own pages (in-platform rendering) or serves a headless frontend. A local backend is a local backend.

  • Docker (or another DDEV-supported container runtime) installed and running
  • acli installed and authenticated (CLI quickstart), and your SSH key registered (acli ssh-key:create-upload generates one if you don’t have it and registers it in one step)
  • Access to a Cloud Platform application (which path am I on?). No application? A self-serve Cloud Platform free trial provisions one with its codebase already in place. An application whose repository is still empty needs Set up a codebase first (it also routes sites coming from another host).
  1. Terminal window
    brew install ddev/ddev/ddev

    ddev --version confirms the install on any platform.

  2. The repository URL is on the application’s overview page at cloud.acquia.com. This is the application’s own repository, the one you push to when you ship a change, so this checkout is the one you keep working in:

    Terminal window
    git clone [email protected]:myapp.git
    cd myapp
  3. Terminal window
    ddev config --project-type=drupal --docroot=docroot \
    --database=mysql:8.0

    DDEV writes its config to .ddev/: commit it, and every teammate gets the same local stack for free.

    --database is not optional detail here. Cloud Platform runs MySQL; DDEV defaults to MariaDB (mariadb:11.8 in DDEV 1.25). The mismatch does not fail at this step, it fails later, when a database you pulled from Acquia hits a collation or syntax the local engine does not have. Setting it now is the difference between step 5 working and an import error with no obvious cause. Confirm your environment’s MySQL version in the Cloud Platform user interface and pass that version if it is not 8.0.

  4. DDEV ships an Acquia integration that drives acli for you. It needs a Cloud Platform API token (the same kind acli auth:login created; generate one at cloud.acquia.com/a/profile/tokens), stored once, globally:

    Terminal window
    ddev config global \
    --web-environment-add="ACQUIA_API_KEY=<key>,ACQUIA_API_SECRET=<secret>"

    The variable names are DDEV’s, fixed by its bundled Acquia provider (which reads exactly ACQUIA_API_KEY and ACQUIA_API_SECRET). The same credential pair travels as ACQUIA_CLOUD_API_KEY and ACQUIA_CLOUD_API_SECRET in CI deploys and direct API calls.

    Know what you just stored: the token sits in plaintext in DDEV’s global config on this machine, and it acts with your full Cloud Platform permissions, not a scoped subset. Treat it like any credential: rotate it on the auth guide’s schedule (new token at cloud.acquia.com/a/profile/tokens, re-run the command above, revoke the old one). Revoke it whenever a machine is retired or handed off.

    DDEV ships the Acquia provider at .ddev/providers/acquia.yaml; you do not create it. Point it at an environment with ACQUIA_ENVIRONMENT_ID, set to the app.env alias from everyday workflows orientation (for example myapp.dev), not the environment’s UUID:

    Terminal window
    ddev config \
    --web-environment-add=ACQUIA_ENVIRONMENT_ID=myapp.dev

    Then authorize your SSH key inside the container, once per DDEV session:

    Terminal window
    ddev auth ssh
  5. Terminal window
    ddev start
    ddev pull acquia
    ddev launch

    ddev pull acquia fetches the environment’s database and files and imports them locally. ddev launch opens the site at its local URL (https://myapp.ddev.site). From now on, a stale local site is one ddev pull acquia from fresh.

ddev start fails before doing anything

means the container runtime isn’t running. Start Docker (or your chosen runtime) and re-run; ddev debug dockercheck diagnoses it.

ddev start reports port 80 or 443 already in use

another web server or Docker project holds the port. Stop it, or move DDEV’s router ports once, globally: ddev config global --router-http-port=8080 --router-https-port=8443.

Permission denied (publickey) on the clone in step 2

your SSH key isn’t registered or isn’t offered; the code-workflow quickstart’s fix applies verbatim.

ddev pull acquia prints Authenticating... then Pull failed: exit status 1

with nothing else. The provider’s own message is swallowed, so the exit status is all you get. Two causes, in the order worth checking: the container has no authorized key (run ddev auth ssh), or acli inside the container is not authenticated (run ddev exec acli auth:login, which the shipped provider file names as a prerequisite).

ddev pull acquia fails with an authentication error

means the API key/secret pair is missing, mistyped, or revoked. Check what was stored with grep -A5 web_environment ~/.ddev/global_config.yaml; both names must be listed. (ddev config global does not print this section.) Repeating --web-environment-add within one command keeps only the last value, so passing the pair as two flags on one line stores the secret and drops the key. Store them as one comma-separated value, as in step 4. If they’re present and the pull still fails, the token was mistyped or revoked. Generate a fresh one at cloud.acquia.com/a/profile/tokens and re-run the ddev config global --web-environment-add command from step 4 with the new values.

ddev pull acquia fails importing with Unknown collation

(for example Unknown collation: 'utf8mb4_0900_ai_ci') means the local database engine is older than the one the dump came from: MySQL 8 collations do not exist in MariaDB, which is DDEV’s default. ddev config --database= does not change the engine of a running project, so recreate it:

Terminal window
ddev delete -Oy
ddev config --project-type=drupal --docroot=docroot \
--database=mysql:8.0
ddev start && ddev pull acquia

ddev delete -Oy removes the project’s containers and database without touching your code or .ddev/config.yaml.

The pull works but the site errors locally

means database and code are out of step (the environment runs different code than your checkout). Check out the branch the environment tracks (shown on its environment card in the Cloud Platform user interface), then ddev restart and pull again.

  • Local development guide: the refresh routine, config sync, pushing work back, and the alternatives (Lando, plain acli, Cloud IDE).
  • Ship one change: push from this checkout and watch the dev environment deploy it.
  • Code-workflow guide: branches and tags per environment, moving databases and files, remote drush.
  • Acquia’s Cloud IDE documentation: the zero-install alternative to a local stack, a browser-based environment already authenticated with the platform.

Was this page helpful?