Installing a Second HTTPS Service in DDev

Let’s say you have a DDev setup with https://example.ddev.site, but you need a second secure URL for a separate service. Normally you’d do this with additional_hostnames, but you still would need to use a nonstandard port like 8443 because port 443 across all the hostnames goes to the web container. But there is a way to get https://host2.ddev.site (on port 443) to be served by another DDev service:

First, in your new service, manually set up it up to serve port 443 on the new hostname:

    environment:
# This configures traefik to map host2.ddev.site:443 specifically
# to this container port 8080. Because we don't want the web container
# handling this hostname, we do NOT include it in additional_hostnames.
VIRTUAL_HOST: host2.ddev.site
HTTP_EXPOSE: 80:8080
HTTPS_EXPOSE: 443:8080

In DDev’s config.yaml, do not place host2 in additional_hostnames. The reason is this would place “host2.ddev.site” in the web container’s VIRTUAL_HOST. I recommend a comment to point this out:

# We _are_ using the hostname host2.ddev.site in the project, BUT we cannot
# list it here because then the web container would handle it.
additional_hostnames: []

✅ Now you have two HTTPS services:

  • example.ddev.site:443 -> web container port 80
  • host2.ddev.site:443 -> host2 container port 8080

Allowing https://host2.ddev.site to work inside another container

This isn’t essential, but in my case I needed to use the same URL in the browser and within a third container site3 running Alpine linux.

In the site3 Dockerfile, install ca-certificates, so we can later install the self-signed DDev cert:

RUN apk add ca-certificates

In docker-compose.site3.yaml, map the DNS and add a volume mount with the cert:

    external_links:
# Set up host2.ddev.site to reach the main traefik router
- ddev-router:host2.ddev.site
volumes:
- ".:/mnt/ddev_config"
# Allow copying mkcert/rootCA.pem into container
- ddev-global-cache:/mnt/ddev-global-cache

In config.yaml, add post-start hooks to install the cert:

hooks:
post-start:
- exec: cp /mnt/ddev-global-cache/mkcert/rootCA.pem /usr/local/share/ca-certificates/my-cert.crt
service: site3
- exec: update-ca-certificates
service: site3

Using the DDev cert with node

If site3 uses Node, you’ll need to select the OpenSSL cert store instead of the built-in one.

node --use-openssl-ca script.js

If using pm2:

NODE_OPTIONS="--use-openssl-ca" pm2 start ...