ddev: 1.22.0 Custom docker-compose config can't use port 9999 due to conflict with traefik management port

Output of ddev debug test

Expand `ddev debug test` diagnostic information
Running bash [-c /tmp/test_ddev.sh] 
======= Existing project config =========
These config files were loaded for project myproject: [/home/myuser/ddev/myproject/.ddev/config.yaml /home/myuser/ddev/myproject/.ddev/config.wkhtmltox.yaml]
name: myproject
type: php
docroot: public
php_version: 8.2
webserver_type: apache-fpm
webimage: ddev/ddev-webserver:v1.22.0
router_http_port: 80
router_https_port: 443
database: {mariadb 10.6}
hooks: map[post-start:[map[exec:mysql -uroot -proot -hdb -e "CREATE DATABASE IF NOT EXISTS db_test; GRANT ALL ON db_test.* TO 'db'@'%';"]]]
mailhog_port: 8025
mailhog_https_port: 8026
webimage_extra_packages: [php8.2-mailparse xfonts-75dpi xfonts-base]
project_tld: ddev.site
use_dns_when_possible: true
composer_version: 2
nodejs_version: 16
default_container_timeout: 120
======= Creating dummy project named  tryddevproject-8756 in ../tryddevproject-8756 =========
OS Information: Linux myuser-ThinkPad-T14-Gen-3 5.19.0-46-generic #47~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jun 21 15:35:31 UTC 2 x86_64 x86_64 x86_64 GNU/Linux
User information: uid=1000(myuser) gid=1000(myuser) groups=1000(myuser),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),135(lxd),136(sambashare),139(libvirt),999(docker)
DDEV version:  ITEM             VALUE                                   
 DDEV version     v1.22.0                                 
 architecture     amd64                                   
 db               ddev/ddev-dbserver-mariadb-10.4:v1.22.0 
 ddev-ssh-agent   ddev/ddev-ssh-agent:v1.22.0             
 docker           24.0.5                                  
 docker-compose   v2.20.0                                 
 docker-platform  Ubuntu 22.04.2 LTS                      
 mutagen          0.17.2                                  
 os               linux                                   
 router           traefik:v2.10                           
 web              ddev/ddev-webserver:v1.22.0             
PROXY settings: HTTP_PROXY='' HTTPS_PROXY='' http_proxy='' NO_PROXY=''
======= DDEV global info =========
Global configuration:
instrumentation-opt-in=true
omit-containers=[]
performance-mode=none
router-bind-all-interfaces=false
internet-detection-timeout-ms=3000
disable-http2=false
use-letsencrypt=false
letsencrypt-email=
table-style=default
simple-formatting=false
auto-restart-containers=false
use-hardened-images=false
fail-on-hook-fail=false
required-docker-compose-version=v2.20.0
use-docker-compose-from-path=false
project-tld=
xdebug-ide-location=
no-bind-mounts=false
router=traefik
wsl2-no-windows-hosts-mgt=false
router-http-port=80
router-https-port=443

======= DOCKER info =========
docker location: -rwxr-xr-x 1 root root 35927416 jul 21 22:35 /usr/bin/docker
docker version: 
Client: Docker Engine - Community
 Version:           24.0.5
 API version:       1.43
 Go version:        go1.20.6
 Git commit:        ced0996
 Built:             Fri Jul 21 20:35:18 2023
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          24.0.5
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.6
  Git commit:       a61e2b4
  Built:            Fri Jul 21 20:35:18 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
DOCKER_DEFAULT_PLATFORM=notset
======= Mutagen Info =========
======= Docker Info =========
Docker platform: Ubuntu 22.04.2 LTS 
Using docker context: default (unix:///var/run/docker.sock) 
docker-compose: v2.20.0 
Using DOCKER_HOST=unix:///var/run/docker.sock 
Docker version: 24.0.5 
Able to run simple container that mounts a volume. 
Able to use internet inside container. 
Docker disk space:
Filesystem                Size      Used Available Use% Mounted on
overlay                 913.8G    263.6G    603.7G  30% /

The ddev-ssh-agent container has been removed. When you start it again you will have to use 'ddev auth ssh' to provide key authentication again.
Existing docker containers: 
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS                    PORTS     NAMES
8f16f7b2495c   7a546d03c39d   "/bin/sh"                2 weeks ago    Created                             phpstorm_helpers_PS-231.9161.47
6dbfbafa35a4   ea2c691c59b1   "/bin/sh"                2 months ago   Created                             phpstorm_helpers_PS-231.9011.38
4b15883d5d2b   ba24e115912e   "/bin/sh"                3 months ago   Created                             phpstorm_helpers_PS-231.8109.199
b6298d47d7d2   2986bb9a7b89   "/bin/sh"                4 months ago   Created                             phpstorm_helpers_PS-223.8836.42
2d4a9a160389   60ad69959caa   "/bin/sh"                4 months ago   Created                             phpstorm_helpers_PS-223.8617.59
b569ae9e043f   lawcloud       "/entrypoint supervi…"   4 months ago   Exited (0) 4 months ago             epic_carson
ca83b0b18670   hello-world    "/hello"                 4 months ago   Exited (0) 4 months ago             beautiful_swartz
39dadc1f859e   hello-world    "/hello"                 4 months ago   Exited (0) 4 months ago             vibrant_spence
Network ddev_default created 
Starting tryddevproject-8756... 
 Container ddev-ssh-agent  Created 
 Container ddev-ssh-agent  Started 
ssh-agent container is running: If you want to add authentication to the ssh-agent container, run 'ddev auth ssh' to enable your keys. 
 Network ddev-tryddevproject-8756_default  Created 
 Container ddev-tryddevproject-8756-web  Created 
 Container ddev-tryddevproject-8756-db  Created 
 Container ddev-tryddevproject-8756-web  Started 
 Container ddev-tryddevproject-8756-db  Started 
 Container ddev-router  Created 
 Container ddev-router  Started 
Successfully started tryddevproject-8756 
Project can be reached at https://tryddevproject-8756.ddev.site https://127.0.0.1:32866 
======== Curl of site from inside container:
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 26 Jul 2023 08:53:20 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding

======== curl -I of http://tryddevproject-8756.ddev.site from outside:
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Date: Wed, 26 Jul 2023 08:53:21 GMT
Server: nginx
Vary: Accept-Encoding

======== full curl of http://tryddevproject-8756.ddev.site from outside:
Success accessing database... db via TCP/IP
ddev is working. You will want to delete this project with 'ddev delete -Oy tryddevproject-8756'
======== Project ownership on host:
drwxr-xr-x 4 tomderoo tomderoo 4096 jul 26 10:53 ../tryddevproject-8756
======== Project ownership in container:
drwxr-xr-x 4 tomderoo tomderoo 4096 Jul 26 08:53 /var/www/html
======== In-container filesystem:
Filesystem                Type 1K-blocks      Used Available Use% Mounted on
/dev/mapper/vgubuntu-root ext4 958137496 276569416 632823632  31% /var/www/html
======== curl again of tryddevproject-8756 from host:
Success accessing database... db via TCP/IP
ddev is working. You will want to delete this project with 'ddev delete -Oy tryddevproject-8756'
Thanks for running the diagnostic. It was successful.

Expected Behavior

After updating to 1.22.0, I expect ddev start to actually start my DDEV project, but instead I get a conflict on port 9999: services.ddev-router.ports array items[5,6] must be unique

Update: There are two easy fixes:

  1. Go back to the traditional nginx-proxy router, which does not use port 9999: ddev config global --router=nginx-proxy
  2. Change your docker-compose.*.yaml to use another port than port 9999. This requires changing HTTP_EXPOSE and HTTPS_EXPOSE to use an alternate exposed port.

Actual Behavior

After upgrading to 1.22.0, I receive the following error on starting my project:

validating /home/myuser/.ddev/.router-compose.yaml: services.ddev-router.ports array items[5,6] must be unique 
Failed to start myproject: ComposeCmd failed to run 'COMPOSE_PROJECT_NAME=ddev-myproject docker-compose -f /home/myuser/.ddev/.router-compose.yaml config', action='[config]', err='exit status 15', stdout='', stderr='validating /home/myuser/.ddev/.router-compose.yaml: services.ddev-router.ports array items[5,6] must be unique' 

The cause is pretty obvious when checing the contents of /home/myuser/.ddev/.router-compose.yaml:

services:
  ddev-router:
    image: traefik:v2.10-built
    build:
      context: router-build
      args:
        BASE_IMAGE: 'traefik:v2.10'
        username: 'myuser'
        uid: '1000'
        gid: '1000'

    
    command:
      - --configFile=/mnt/ddev-global-cache/traefik/static_config.yaml
    user: 1000:1000
    

    networks:
        - ddev_default
    container_name: ddev-router
    ports:
    - "127.0.0.1:443:443"
    - "127.0.0.1:80:80"
    - "127.0.0.1:8025:8025"
    - "127.0.0.1:8026:8026"
    # MY COMMENT: here starts the ugly part; these ports are added because of ddev/mercure config
    - "127.0.0.1:9998:9998"
    - "127.0.0.1:9999:9999"
    
    # Traefik router; configured in static config as entrypoint
    # TODO: Make this configurable? Put it somewhere else?
    # MY COMMENT: ... and you will notice that Traefik auto-adds the exact same port as Mercure did above
    - "127.0.0.1:9999:9999"
    
    volumes:
      
      - ddev-global-cache:/mnt/ddev-global-cache:rw
       
    environment:
      - DISABLE_HTTP2=false
        
    restart: "no"
    healthcheck:
      
      test: "/healthcheck.sh"
      
      interval: 1s
      retries: 120
      start_period: 120s
      timeout: 120s

networks:
  ddev_default:
    name: ddev_default
    external: true
volumes:
  ddev-global-cache:
    name: ddev-global-cache
    external: true

The port config "127.0.0.1:9999:9999" is added twice. The first time comes from the mercure docker compose copied from the Mercure Symfony bundle, the second one comes from Traefik.

Here is my project’s docker-compose.mercure.yaml:

version: '3'

services:
  mercure:
    image: dunglas/mercure
    restart: unless-stopped
    container_name: "ddev-${DDEV_SITENAME}-mercure-hub"
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: ${DDEV_APPROOT}
    expose:
      - "3000"
    environment:
      VIRTUAL_HOST: $DDEV_HOSTNAME
      SERVER_NAME: ":3000"
      HTTP_EXPOSE: "9998:3000"
      HTTPS_EXPOSE: "9999:3000"
      MERCURE_PUBLISHER_JWT_KEY: '1289c268ad0f83eb51036592213bf45794e03c969907dac0d622b3ea22a6d3ab'
      MERCURE_SUBSCRIBER_JWT_KEY: '1289c268ad0f83eb51036592213bf45794e03c969907dac0d622b3ea22a6d3ab'
      MERCURE_EXTRA_DIRECTIVES: |
        cors_origins https://myproject.ddev.site
    # Comment the following line to disable the development mode
    command: /usr/bin/caddy run --config /etc/caddy/Caddyfile.dev
    volumes:
      - mercure_data:/data
      - mercure_config:/config

volumes:
  mercure_data:
  mercure_config:

I would be more than happy to simply change the HTTP_EXPOSE and HTTPS_EXPOSE values, but then Mercure stops working in my Symfony app due to a 502 bad gateway / cors origin on the selected port (I tried the HTTPS one with 9990, I assume it fails with anything that is not 9999), even after changing the .env to have the mercure related variables match the new ports. I do not know why it fails on anything that is not 9999, I am not versed in Mercure config.

I can also avoid the problem by stepping away from Traefik and reconfiguring ddev globally to use the old nginx-proxy router through ddev config global --router=nginx-proxy, while keeping the “working” mercure config. My /home/myuser/.ddev/.router-compose.yaml then outputs:

services:
  ddev-router:
    image: ddev/ddev-router:v1.22.0-built
    build:
      context: router-build
      args:
        BASE_IMAGE: 'ddev/ddev-router:v1.22.0'
        username: 'myuser'
        uid: '1000'
        gid: '1000'

    

    networks:
        - ddev_default
    container_name: ddev-router
    ports:
    - "127.0.0.1:443:443"
    - "127.0.0.1:80:80"
    - "127.0.0.1:8025:8025"
    - "127.0.0.1:8026:8026"
    - "127.0.0.1:9998:9998"
    - "127.0.0.1:9999:9999"
    
    volumes:
      
      - /var/run/docker.sock:/tmp/docker.sock:ro
      
      - ddev-global-cache:/mnt/ddev-global-cache:rw
       
    environment:
      - DISABLE_HTTP2=false
        
    restart: "no"
    healthcheck:
      
      interval: 1s
      retries: 120
      start_period: 120s
      timeout: 120s

networks:
  ddev_default:
    name: ddev_default
    external: true
volumes:
  ddev-global-cache:
    name: ddev-global-cache
    external: true

You will notice: no duplicate ports.

Steps To Reproduce

  1. Have ddev 1.22.0
  2. Have a ddev project with docker mercure config from the Mercure Symfony bundle on the standard config (with specifically the https port at 9999)
  3. Make sure the ddev router is traefik (the default since 1.22.0)
  4. Try to start your project, see it fail

Anything else?

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 28 (17 by maintainers)

Most upvoted comments

This should be very much sorted out in DDEV v1.22.1, just released. The port used is now 10999, and it’s configurable.

I tried to make a DDEV add-on that could fix this problem, but I don’t think it can be done that way.

This should urgently get an override for the port used for Traefik management, for v1.22.1.

Alright, made new issue https://github.com/ddev/ddev/issues/5203 that included a sandbox project at https://github.com/tomderoo/sandbox-sf6-mercure-ddev - I know it has Symfony to frame Mercure, but I do not know how else to create that in a fast and reliabe manner…

It would have been better to use a different port for traefik admin port 😃