applebee.io logo
Back to articles
DrupalDDEVDevOpsSSL

Drupal 11 with DDEV, nip.io, and HTTPS

Jim Applebee

Drupal 11 with DDEV, nip.io, and HTTPS

DDEV already provides HTTPS for local development through its locally trusted certificate setup. For one developer on one machine, that is normally the right answer. A nip.io hostname becomes useful when another device on the same network needs to reach the project. A publicly trusted certificate is a separate requirement and usually unnecessary for private LAN work.

Create the Drupal 11 project

With Docker, DDEV, and Composer installed:

mkdir drupal11-ddev
cd drupal11-ddev
ddev config --project-type=drupal11 --docroot=web --create-docroot
ddev composer create-project drupal/recommended-project:^11
ddev start

Follow the URL reported by ddev start. If your browser does not trust DDEV’s local certificate, run mkcert -install as DDEV documents, then restart the project. This is sufficient for normal local development.

Make the project reachable on a private LAN

Find the development computer’s LAN address. For example, on macOS:

ipconfig getifaddr en0

If the address is 192.168.1.100, add the following to .ddev/config.yaml:

additional_fqdns:
  - drupal.192.168.1.100.nip.io

Then run ddev restart. The hostname resolves to the embedded address, but that does not make a private computer public. Other devices must be able to route to the address, the host firewall must allow the connection, and DDEV’s router ports must be reachable.

DDEV’s locally issued certificate may not be trusted on the second device. Install the local certificate authority there only if it is a device you control and your security policy permits it. Otherwise, use plain HTTP on the trusted LAN for short-lived testing or use a proper public test environment.

Can Let’s Encrypt issue for nip.io?

Yes, for an individual nip.io hostname when validation can succeed. The old blanket statement that Let’s Encrypt does not support nip.io is incorrect.

The important distinction is reachability and control:

  • HTTP-01 validation requires the hostname to resolve to a publicly reachable server on port 80. A hostname that resolves to a private address such as 192.168.1.100 cannot be validated from the public internet.
  • DNS-01 can validate a host whose web server is private, but it requires control of the authoritative DNS record. With a shared wildcard-DNS service such as nip.io, you do not control its DNS zone and cannot add the required TXT record.
  • A hostname containing your public IP may pass HTTP-01 if routing, firewall, and port forwarding are configured correctly. Exposing a development machine solely to obtain a certificate is usually a poor trade.

For a private LAN, use DDEV’s normal local HTTPS. For a stable environment that needs public trust, use a domain you control and a publicly reachable test host, or automate DNS-01 through your DNS provider’s API.

Install a custom certificate the DDEV way

If you already have a certificate and key for a hostname configured in the project, DDEV expects them in .ddev/custom_certs and names them after the DDEV project:

.ddev/custom_certs/<projectname>.crt
.ddev/custom_certs/<projectname>.key

Copy the full certificate chain to the .crt file and the private key to the .key file, protect the key, and run ddev restart. Do not commit private keys. A custom Docker Compose mount is not needed for the documented DDEV configuration.

Renewal is part of the design

certbot certonly --manual --preferred-challenges dns can prove control interactively, but an unattended certbot renew cannot recreate a TXT record that a person added by hand. Automatic renewal requires a supported DNS plugin, a deploy/auth hook, or another ACME client integrated with the DNS provider’s API. After renewal, copy or deploy the new certificate into .ddev/custom_certs and restart DDEV.

That operational work is another reason to prefer DDEV’s local HTTPS for local development.

Sources