Always quote docker compose port numbers

Avoid the headache

  • 18th February 2020

I've just spent the last few hours banging my head against a wall trying to figure out why Docker and Traefik wouldn't play ball, and allow me to connect to my SFTP container on port 22.

I'd tried opening the firewall, checking all the traefik config, checking the docker network, inspecting the logs, updating the labels on the container etc etc etc.

Finally, I realised it was a simple YAML error, let's take a look at the config:

version: '3.3'
services:
  traefik:
    image: traefik:latest
    restart: always
    labels:
      traefik.enable: false
    ports:
      - 22:22
      - 80:80
      - 443:443

Looks simple enough, and I've never had any issues with the HTTP and HTTPS services I've been running for months. Because I was doing TCP routing, rather than HTTP, I was sure I had an issue with my Traefik configuration, until I realised, YAML supports "Sexagesimals".

Sexagesimal (also known as base 60 or sexagenary) is a numeral system with sixty as its base.

In version 1.1 of the YAML data storage format, sexagesimals are supported for plain scalars, and formally specified both for integers and floating point numbers. This has led to confusion, as e.g. some MAC addresses would be recognised as sexagesimals and loaded as integers, where others were not and loaded as strings. In YAML 1.2 support for sexagesimals was dropped. https://en.wikipedia.org/wiki/Sexagesimal#YAML

Running docker-compose ps shows how this has been parsed:

      Name                 Command           State                                 Ports
----------------------------------------------------------------------------------------------------------------------
traefik_traefik_1   /entrypoint.sh traefik   Up      0.0.0.0:32768->1342/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

(Note the 0.0.0.0:32768->1342/tcp bit).

Simply wrapping the port numbers in quotes forces YAML to parse this normally, without converting to a base 60 number, and fixing the issue:

    ports:
      - "22:22"
      - "80:80"
      - "443:443"
      Name                 Command           State                              Ports
-----------------------------------------------------------------------------------------------------------------
traefik_traefik_1   /entrypoint.sh traefik   Up      0.0.0.0:22->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

So, lesson learnt, always wrap Docker ports (or any numbers with colons) in quotes to avoid headaches in future.